From d85069ad99793aab616913e7336287eb3cc795a4 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Thu, 27 Jun 2019 00:02:01 +1200 Subject: [PATCH 0001/1323] Initial commit --- openapi-maven-plugin/LICENSE | 201 +++++++++++++++++++++++++++++++++ openapi-maven-plugin/README.md | 2 + 2 files changed, 203 insertions(+) create mode 100644 openapi-maven-plugin/LICENSE create mode 100644 openapi-maven-plugin/README.md diff --git a/openapi-maven-plugin/LICENSE b/openapi-maven-plugin/LICENSE new file mode 100644 index 000000000..261eeb9e9 --- /dev/null +++ b/openapi-maven-plugin/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/openapi-maven-plugin/README.md b/openapi-maven-plugin/README.md new file mode 100644 index 000000000..5632986f8 --- /dev/null +++ b/openapi-maven-plugin/README.md @@ -0,0 +1,2 @@ +# openapi-maven-plugin +Maven plugin for OpenAPI generation (swagger) From a4c0d72c33c8c9462c9879e163fe50256a8ef726 Mon Sep 17 00:00:00 2001 From: rob bygrave Date: Thu, 27 Jun 2019 00:08:12 +1200 Subject: [PATCH 0002/1323] Initial --- openapi-maven-plugin/.editorconfig | 12 ++ openapi-maven-plugin/.gitignore | 5 + openapi-maven-plugin/pom.xml | 104 ++++++++++++++++++ .../io/dinject/maven/openapi/OpenApiMojo.java | 78 +++++++++++++ 4 files changed, 199 insertions(+) create mode 100644 openapi-maven-plugin/.editorconfig create mode 100644 openapi-maven-plugin/.gitignore create mode 100644 openapi-maven-plugin/pom.xml create mode 100644 openapi-maven-plugin/src/main/java/io/dinject/maven/openapi/OpenApiMojo.java diff --git a/openapi-maven-plugin/.editorconfig b/openapi-maven-plugin/.editorconfig new file mode 100644 index 000000000..837d975fa --- /dev/null +++ b/openapi-maven-plugin/.editorconfig @@ -0,0 +1,12 @@ +# editorconfig.org + +root = true + +[*] +charset = utf-8 +end_of_line = lf +indent_size = 2 +indent_style = space +insert_final_newline = true +trim_trailing_whitespace = true +spaces_around_operators = true diff --git a/openapi-maven-plugin/.gitignore b/openapi-maven-plugin/.gitignore new file mode 100644 index 000000000..0c9d542d8 --- /dev/null +++ b/openapi-maven-plugin/.gitignore @@ -0,0 +1,5 @@ +target/ +build/ +.idea/ +*.iml +.gradle diff --git a/openapi-maven-plugin/pom.xml b/openapi-maven-plugin/pom.xml new file mode 100644 index 000000000..fa8c305a6 --- /dev/null +++ b/openapi-maven-plugin/pom.xml @@ -0,0 +1,104 @@ + + + 4.0.0 + + io.dinject + openapi-maven-plugin + 1.1-SNAPSHOT + maven-plugin + openapi-maven-plugin + https://dinject.io/ + + + org.avaje + java8-parent + 1.3 + + + + scm:git:git@github.com:dinject/openapi-maven-plugin.git + HEAD + + + + + + org.apache.maven + maven-plugin-api + 3.6.1 + + + + org.apache.maven + maven-core + 3.5.3 + + + + org.apache.maven.plugin-tools + maven-plugin-annotations + 3.6.0 + provided + + + + junit + junit + 4.11 + test + + + + + + + + org.apache.maven.plugins + maven-plugin-plugin + 3.6.0 + + openapi + true + + + + default-descriptor + + descriptor + + process-classes + + + help-descriptor + + helpmojo + + process-classes + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 3.1.0 + + + attach-javadocs + + jar + + + -Xdoclint:none + + + + + + + + + + diff --git a/openapi-maven-plugin/src/main/java/io/dinject/maven/openapi/OpenApiMojo.java b/openapi-maven-plugin/src/main/java/io/dinject/maven/openapi/OpenApiMojo.java new file mode 100644 index 000000000..c680c8de9 --- /dev/null +++ b/openapi-maven-plugin/src/main/java/io/dinject/maven/openapi/OpenApiMojo.java @@ -0,0 +1,78 @@ +package io.dinject.maven.openapi; + +import org.apache.maven.plugin.AbstractMojo; +import org.apache.maven.plugins.annotations.LifecyclePhase; +import org.apache.maven.plugins.annotations.Mojo; +import org.apache.maven.plugins.annotations.Parameter; +import org.apache.maven.project.MavenProject; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.StandardCopyOption; + +@Mojo(name = "openapi", defaultPhase = LifecyclePhase.PROCESS_CLASSES) +public class OpenApiMojo extends AbstractMojo { + + /** + * Relative path to find the generated openapi.json file. + */ + @Parameter(name = "source") + String source; + + /** + * Relative path to put the openapi.json. + */ + @Parameter(name = "destination") + String destination; + + /** + * The directory holding the class files we want to transform. + */ + @Parameter(property = "project.build.outputDirectory") + String buildOut; + + @Parameter(property = "project.build.resources[0].directory") + String buildResourceDir; + + @Parameter(defaultValue = "${project}", readonly = true, required = true) + private MavenProject project; + + @Override + public void execute() { + + if (source == null) { + // the location that the APT javalin-generator writes to + source = "meta/openapi.json"; + } + if (destination == null) { + // location in src/main/resources to move openapi doc to + destination = "public/openapi.json"; + } + + File sourceFile = new File(new File(buildOut), source); + if (!sourceFile.exists()) { + getLog().warn("openapi file not found at " + sourceFile); + return; + } + + File srcMainRes = new File(buildResourceDir); + if (destination != null) { + File destFile = new File(srcMainRes, destination); + File destDir = destFile.getParentFile(); + if (!destDir.exists() && !destDir.mkdirs()) { + getLog().error("Failed to make directory " + destDir); + } else { + try { + // copy into src/main/resources ... + Files.copy(sourceFile.toPath(), destFile.toPath(), StandardCopyOption.REPLACE_EXISTING); + getLog().info("copied openapi file to " + destFile); + + } catch (IOException e) { + getLog().error("Failed to copy openapi file", e); + } + } + } + + } +} From dd0ffe82c0eabd6ea7a64062f49ba9d063f07c52 Mon Sep 17 00:00:00 2001 From: rob bygrave Date: Thu, 27 Jun 2019 00:08:59 +1200 Subject: [PATCH 0003/1323] [maven-release-plugin] prepare release openapi-maven-plugin-1.1 --- openapi-maven-plugin/pom.xml | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/openapi-maven-plugin/pom.xml b/openapi-maven-plugin/pom.xml index fa8c305a6..85558c0c6 100644 --- a/openapi-maven-plugin/pom.xml +++ b/openapi-maven-plugin/pom.xml @@ -1,12 +1,10 @@ - + 4.0.0 io.dinject openapi-maven-plugin - 1.1-SNAPSHOT + 1.1 maven-plugin openapi-maven-plugin https://dinject.io/ @@ -19,7 +17,7 @@ scm:git:git@github.com:dinject/openapi-maven-plugin.git - HEAD + openapi-maven-plugin-1.1 From c51dcb1d5a3b54a313b154e06ac6af92a20109b0 Mon Sep 17 00:00:00 2001 From: rob bygrave Date: Thu, 27 Jun 2019 00:09:11 +1200 Subject: [PATCH 0004/1323] [maven-release-plugin] prepare for next development iteration --- openapi-maven-plugin/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openapi-maven-plugin/pom.xml b/openapi-maven-plugin/pom.xml index 85558c0c6..230ac0fd0 100644 --- a/openapi-maven-plugin/pom.xml +++ b/openapi-maven-plugin/pom.xml @@ -4,7 +4,7 @@ io.dinject openapi-maven-plugin - 1.1 + 1.2-SNAPSHOT maven-plugin openapi-maven-plugin https://dinject.io/ @@ -17,7 +17,7 @@ scm:git:git@github.com:dinject/openapi-maven-plugin.git - openapi-maven-plugin-1.1 + HEAD From eb02973dbc121dde672272031b81b8eef4311bf8 Mon Sep 17 00:00:00 2001 From: rob bygrave Date: Fri, 28 Jun 2019 01:26:09 +1200 Subject: [PATCH 0005/1323] Delete the temporary openapi json file and meta dir if empty --- .../io/dinject/maven/openapi/OpenApiMojo.java | 31 ++++++++++++++++--- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/openapi-maven-plugin/src/main/java/io/dinject/maven/openapi/OpenApiMojo.java b/openapi-maven-plugin/src/main/java/io/dinject/maven/openapi/OpenApiMojo.java index c680c8de9..6205e71e0 100644 --- a/openapi-maven-plugin/src/main/java/io/dinject/maven/openapi/OpenApiMojo.java +++ b/openapi-maven-plugin/src/main/java/io/dinject/maven/openapi/OpenApiMojo.java @@ -64,15 +64,38 @@ public void execute() { getLog().error("Failed to make directory " + destDir); } else { try { - // copy into src/main/resources ... - Files.copy(sourceFile.toPath(), destFile.toPath(), StandardCopyOption.REPLACE_EXISTING); - getLog().info("copied openapi file to " + destFile); - + moveToMainResources(sourceFile, destFile); } catch (IOException e) { getLog().error("Failed to copy openapi file", e); } } } + } + /** + * Copy the file to src/main/resources ... + */ + private void moveToMainResources(File sourceFile, File destFile) throws IOException { + // copy into src/main/resources ... + Files.copy(sourceFile.toPath(), destFile.toPath(), StandardCopyOption.REPLACE_EXISTING); + getLog().info("copied openapi file to " + destFile); + if (!sourceFile.delete()) { + getLog().warn("Failed to delete the temporary openapi file " + sourceFile); + } else { + deleteParentIfEmpty(sourceFile); + } + } + + /** + * Delete the parent meta directory if it is empty. + */ + private void deleteParentIfEmpty(File sourceFile) { + final File meta = sourceFile.getParentFile(); + final String[] list = meta.list(); + if (list != null && list.length == 0) { + if (meta.delete()) { + getLog().debug("deleted empty meta directory"); + } + } } } From bc075b7d721741df940ce1fbf749bcbeddde68cc Mon Sep 17 00:00:00 2001 From: rob bygrave Date: Fri, 28 Jun 2019 01:26:35 +1200 Subject: [PATCH 0006/1323] [maven-release-plugin] prepare release openapi-maven-plugin-1.2 --- openapi-maven-plugin/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openapi-maven-plugin/pom.xml b/openapi-maven-plugin/pom.xml index 230ac0fd0..b544253eb 100644 --- a/openapi-maven-plugin/pom.xml +++ b/openapi-maven-plugin/pom.xml @@ -4,7 +4,7 @@ io.dinject openapi-maven-plugin - 1.2-SNAPSHOT + 1.2 maven-plugin openapi-maven-plugin https://dinject.io/ @@ -17,7 +17,7 @@ scm:git:git@github.com:dinject/openapi-maven-plugin.git - HEAD + openapi-maven-plugin-1.2 From 36b6b029c02cd46c8cb644246c0be1ae2cba9b78 Mon Sep 17 00:00:00 2001 From: rob bygrave Date: Fri, 28 Jun 2019 01:26:44 +1200 Subject: [PATCH 0007/1323] [maven-release-plugin] prepare for next development iteration --- openapi-maven-plugin/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openapi-maven-plugin/pom.xml b/openapi-maven-plugin/pom.xml index b544253eb..629ac2d6c 100644 --- a/openapi-maven-plugin/pom.xml +++ b/openapi-maven-plugin/pom.xml @@ -4,7 +4,7 @@ io.dinject openapi-maven-plugin - 1.2 + 1.3-SNAPSHOT maven-plugin openapi-maven-plugin https://dinject.io/ @@ -17,7 +17,7 @@ scm:git:git@github.com:dinject/openapi-maven-plugin.git - openapi-maven-plugin-1.2 + HEAD From cf198c5ae41cceddd3b70adeef5d4be8d8a146a3 Mon Sep 17 00:00:00 2001 From: rob bygrave Date: Thu, 5 Dec 2019 20:36:02 +1300 Subject: [PATCH 0008/1323] Update parent pom --- openapi-maven-plugin/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openapi-maven-plugin/pom.xml b/openapi-maven-plugin/pom.xml index 629ac2d6c..0e1e8edd3 100644 --- a/openapi-maven-plugin/pom.xml +++ b/openapi-maven-plugin/pom.xml @@ -11,8 +11,8 @@ org.avaje - java8-parent - 1.3 + java8-oss + 2.1 From da1b85c1c4879ce4c2c789dfcaffec7b8178e19c Mon Sep 17 00:00:00 2001 From: rob bygrave Date: Thu, 5 Dec 2019 20:36:40 +1300 Subject: [PATCH 0009/1323] [maven-release-plugin] prepare release openapi-maven-plugin-1.3 --- openapi-maven-plugin/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openapi-maven-plugin/pom.xml b/openapi-maven-plugin/pom.xml index 0e1e8edd3..1c14b6c03 100644 --- a/openapi-maven-plugin/pom.xml +++ b/openapi-maven-plugin/pom.xml @@ -4,7 +4,7 @@ io.dinject openapi-maven-plugin - 1.3-SNAPSHOT + 1.3 maven-plugin openapi-maven-plugin https://dinject.io/ @@ -17,7 +17,7 @@ scm:git:git@github.com:dinject/openapi-maven-plugin.git - HEAD + openapi-maven-plugin-1.3 From 1beb5cb327e2b150887a4822153f18bfdf0f5a5f Mon Sep 17 00:00:00 2001 From: rob bygrave Date: Thu, 5 Dec 2019 20:36:51 +1300 Subject: [PATCH 0010/1323] [maven-release-plugin] prepare for next development iteration --- openapi-maven-plugin/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openapi-maven-plugin/pom.xml b/openapi-maven-plugin/pom.xml index 1c14b6c03..0206d76ac 100644 --- a/openapi-maven-plugin/pom.xml +++ b/openapi-maven-plugin/pom.xml @@ -4,7 +4,7 @@ io.dinject openapi-maven-plugin - 1.3 + 1.4-SNAPSHOT maven-plugin openapi-maven-plugin https://dinject.io/ @@ -17,7 +17,7 @@ scm:git:git@github.com:dinject/openapi-maven-plugin.git - openapi-maven-plugin-1.3 + HEAD From 51bf9e29e77eb719b63a7c672a8cd81086566dc6 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Thu, 27 Aug 2020 01:07:37 +1200 Subject: [PATCH 0011/1323] Initial commit --- http-client/LICENSE | 201 ++++++++++++++++++++++++++++++++++++++++++ http-client/README.md | 1 + 2 files changed, 202 insertions(+) create mode 100644 http-client/LICENSE create mode 100644 http-client/README.md diff --git a/http-client/LICENSE b/http-client/LICENSE new file mode 100644 index 000000000..261eeb9e9 --- /dev/null +++ b/http-client/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/http-client/README.md b/http-client/README.md new file mode 100644 index 000000000..b6459902b --- /dev/null +++ b/http-client/README.md @@ -0,0 +1 @@ +# avaje-http-client \ No newline at end of file From 5f333c0c0ba2b5c390afd34e242f25500a0d9380 Mon Sep 17 00:00:00 2001 From: rob bygrave Date: Thu, 27 Aug 2020 17:27:05 +1200 Subject: [PATCH 0012/1323] Initial add --- http-client/.editorconfig | 13 + http-client/.gitignore | 11 + http-client/client/pom.xml | 133 ++++++ .../io/avaje/http/client/BodyAdapter.java | 13 + .../io/avaje/http/client/BodyContent.java | 27 ++ .../java/io/avaje/http/client/BodyReader.java | 7 + .../java/io/avaje/http/client/BodyWriter.java | 24 + .../avaje/http/client/DHttpClientContext.java | 141 ++++++ .../client/DHttpClientContextBuilder.java | 69 +++ .../avaje/http/client/DHttpClientRequest.java | 443 ++++++++++++++++++ .../java/io/avaje/http/client/GzipUtil.java | 37 ++ .../io/avaje/http/client/HttpApiProvider.java | 7 + .../avaje/http/client/HttpClientContext.java | 105 +++++ .../avaje/http/client/HttpClientRequest.java | 156 ++++++ .../avaje/http/client/HttpClientResponse.java | 95 ++++ .../io/avaje/http/client/HttpException.java | 85 ++++ .../avaje/http/client/JacksonBodyAdapter.java | 107 +++++ .../io/avaje/http/client/RequestListener.java | 22 + .../io/avaje/http/client/RequestLogger.java | 63 +++ .../java/io/avaje/http/client/UrlBuilder.java | 46 ++ .../io/avaje/http/client/BaseWebTest.java | 34 ++ .../http/client/DHttpClientContextTest.java | 60 +++ .../http/client/HelloControllerTest.java | 211 +++++++++ .../io/avaje/http/client/UrlBuilderTest.java | 57 +++ .../src/test/java/org/example/Repo.java | 6 + .../src/test/java/org/example/Simple$rc.java | 79 ++++ .../src/test/java/org/example/Simple.java | 32 ++ .../test/java/org/example/webserver/App.java | 74 +++ .../org/example/webserver/ErrorResponse.java | 27 ++ .../example/webserver/HelloController.java | 136 ++++++ .../java/org/example/webserver/HelloDto.java | 48 ++ .../java/org/example/webserver/HelloForm.java | 43 ++ .../java/org/example/webserver/MyService.java | 16 + .../src/test/resources/logback-test.xml | 19 + http-client/pom.xml | 17 + 35 files changed, 2463 insertions(+) create mode 100644 http-client/.editorconfig create mode 100644 http-client/.gitignore create mode 100644 http-client/client/pom.xml create mode 100644 http-client/client/src/main/java/io/avaje/http/client/BodyAdapter.java create mode 100644 http-client/client/src/main/java/io/avaje/http/client/BodyContent.java create mode 100644 http-client/client/src/main/java/io/avaje/http/client/BodyReader.java create mode 100644 http-client/client/src/main/java/io/avaje/http/client/BodyWriter.java create mode 100644 http-client/client/src/main/java/io/avaje/http/client/DHttpClientContext.java create mode 100644 http-client/client/src/main/java/io/avaje/http/client/DHttpClientContextBuilder.java create mode 100644 http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java create mode 100644 http-client/client/src/main/java/io/avaje/http/client/GzipUtil.java create mode 100644 http-client/client/src/main/java/io/avaje/http/client/HttpApiProvider.java create mode 100644 http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java create mode 100644 http-client/client/src/main/java/io/avaje/http/client/HttpClientRequest.java create mode 100644 http-client/client/src/main/java/io/avaje/http/client/HttpClientResponse.java create mode 100644 http-client/client/src/main/java/io/avaje/http/client/HttpException.java create mode 100644 http-client/client/src/main/java/io/avaje/http/client/JacksonBodyAdapter.java create mode 100644 http-client/client/src/main/java/io/avaje/http/client/RequestListener.java create mode 100644 http-client/client/src/main/java/io/avaje/http/client/RequestLogger.java create mode 100644 http-client/client/src/main/java/io/avaje/http/client/UrlBuilder.java create mode 100644 http-client/client/src/test/java/io/avaje/http/client/BaseWebTest.java create mode 100644 http-client/client/src/test/java/io/avaje/http/client/DHttpClientContextTest.java create mode 100644 http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java create mode 100644 http-client/client/src/test/java/io/avaje/http/client/UrlBuilderTest.java create mode 100644 http-client/client/src/test/java/org/example/Repo.java create mode 100644 http-client/client/src/test/java/org/example/Simple$rc.java create mode 100644 http-client/client/src/test/java/org/example/Simple.java create mode 100644 http-client/client/src/test/java/org/example/webserver/App.java create mode 100644 http-client/client/src/test/java/org/example/webserver/ErrorResponse.java create mode 100644 http-client/client/src/test/java/org/example/webserver/HelloController.java create mode 100644 http-client/client/src/test/java/org/example/webserver/HelloDto.java create mode 100644 http-client/client/src/test/java/org/example/webserver/HelloForm.java create mode 100644 http-client/client/src/test/java/org/example/webserver/MyService.java create mode 100644 http-client/client/src/test/resources/logback-test.xml create mode 100644 http-client/pom.xml diff --git a/http-client/.editorconfig b/http-client/.editorconfig new file mode 100644 index 000000000..18b710430 --- /dev/null +++ b/http-client/.editorconfig @@ -0,0 +1,13 @@ +# editorconfig.org + +root = true + +[*] +charset = utf-8 +end_of_line = lf +indent_size = 2 +indent_style = space +insert_final_newline = true +trim_trailing_whitespace = true +spaces_around_operators = true +max_line_length = 130 diff --git a/http-client/.gitignore b/http-client/.gitignore new file mode 100644 index 000000000..d133fc0d8 --- /dev/null +++ b/http-client/.gitignore @@ -0,0 +1,11 @@ +target/ +logs/ +log/ + +*.iml +.idea/ + +.classpath +.project +.settings/ + diff --git a/http-client/client/pom.xml b/http-client/client/pom.xml new file mode 100644 index 000000000..9900cd777 --- /dev/null +++ b/http-client/client/pom.xml @@ -0,0 +1,133 @@ + + + + java11-oss + org.avaje + 2.1.2 + + + 4.0.0 + + io.avaje + avaje-http-client + 0.1-SNAPSHOT + + + + + org.slf4j + slf4j-api + 1.7.25 + + + + com.fasterxml.jackson.core + jackson-databind + 2.11.1 + true + + + + + + + org.junit.jupiter + junit-jupiter-api + 5.6.2 + test + + + + org.junit.jupiter + junit-jupiter-engine + 5.6.2 + test + + + + org.assertj + assertj-core + 3.16.1 + test + + + + io.javalin + javalin + 3.9.1 + test + + + + io.dinject + dinject + 2.3 + test + + + + io.dinject + dinject-controller + 1.21 + test + + + + io.dinject + controller-validator-hibernate + 1.1 + test + + + + org.avaje.composite + logback + 1.1 + test + + + + + + io.dinject + dinject-generator + 2.3 + test + + + + io.dinject + javalin-generator + 1.21 + test + + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.22.2 + + + --illegal-access=permit + + + + + org.apache.maven.plugins + maven-failsafe-plugin + 2.22.2 + + + --illegal-access=permit + + + + + + diff --git a/http-client/client/src/main/java/io/avaje/http/client/BodyAdapter.java b/http-client/client/src/main/java/io/avaje/http/client/BodyAdapter.java new file mode 100644 index 000000000..7f6c06e2e --- /dev/null +++ b/http-client/client/src/main/java/io/avaje/http/client/BodyAdapter.java @@ -0,0 +1,13 @@ +package io.avaje.http.client; + +import java.util.List; + +public interface BodyAdapter { + + BodyWriter beanWriter(Class cls); + + BodyReader beanReader(Class cls); + + BodyReader> listReader(Class cls); + +} diff --git a/http-client/client/src/main/java/io/avaje/http/client/BodyContent.java b/http-client/client/src/main/java/io/avaje/http/client/BodyContent.java new file mode 100644 index 000000000..ad3667d52 --- /dev/null +++ b/http-client/client/src/main/java/io/avaje/http/client/BodyContent.java @@ -0,0 +1,27 @@ +package io.avaje.http.client; + +public class BodyContent { + + public static final String JSON_UTF8 = "application/json; charset=UTF-8"; + + private final String contentType; + + private final byte[] content; + + public static BodyContent asJson(byte[] content) { + return new BodyContent(JSON_UTF8, content); + } + + public BodyContent(String contentType, byte[] content) { + this.contentType = contentType; + this.content = content; + } + + public String contentType() { + return contentType; + } + + public byte[] content() { + return content; + } +} diff --git a/http-client/client/src/main/java/io/avaje/http/client/BodyReader.java b/http-client/client/src/main/java/io/avaje/http/client/BodyReader.java new file mode 100644 index 000000000..e7faf3899 --- /dev/null +++ b/http-client/client/src/main/java/io/avaje/http/client/BodyReader.java @@ -0,0 +1,7 @@ +package io.avaje.http.client; + +public interface BodyReader { + + T read(BodyContent content); + +} diff --git a/http-client/client/src/main/java/io/avaje/http/client/BodyWriter.java b/http-client/client/src/main/java/io/avaje/http/client/BodyWriter.java new file mode 100644 index 000000000..65fc9f27e --- /dev/null +++ b/http-client/client/src/main/java/io/avaje/http/client/BodyWriter.java @@ -0,0 +1,24 @@ +package io.avaje.http.client; + +/** + * Writes beans as content for a specific content type. + */ +public interface BodyWriter { + + /** + * Write the bean as content using the default content type. + *

+ * Used when all beans sent via POST, PUT, PATCH will be sent as + * a single content type like application/json; charset=utf8. + */ + BodyContent write(Object bean); + + /** + * Write the bean as content with the requested content type. + *

+ * The writer is expected to use the given contentType to determine + * how to write the bean as content. + */ + BodyContent write(Object bean, String contentType); + +} diff --git a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContext.java b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContext.java new file mode 100644 index 000000000..fe51524af --- /dev/null +++ b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContext.java @@ -0,0 +1,141 @@ +package io.avaje.http.client; + +import java.io.IOException; +import java.net.http.HttpClient; +import java.net.http.HttpHeaders; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.time.Duration; +import java.util.List; +import java.util.Map; + +class DHttpClientContext implements HttpClientContext { + + private final HttpClient httpClient; + private final String baseUrl; + private final Duration requestTimeout; + private final BodyAdapter bodyAdapter; + private final RequestListener requestListener; + + DHttpClientContext(HttpClient httpClient, String baseUrl, Duration requestTimeout, BodyAdapter bodyAdapter, RequestListener requestListener) { + this.httpClient = httpClient; + this.baseUrl = baseUrl; + this.requestTimeout = requestTimeout; + this.bodyAdapter = bodyAdapter; + this.requestListener = requestListener; + } + + @Override + public HttpClientRequest request() { + return new DHttpClientRequest(this, requestTimeout); + } + + @Override + public BodyAdapter converters() { + return bodyAdapter; + } + + @Override + public UrlBuilder url() { + return new UrlBuilder(baseUrl); + } + + @Override + public HttpClient httpClient() { + return httpClient; + } + + @Override + public void checkResponse(HttpResponse response) { + if (response.statusCode() >= 300) { + throw new HttpException(response, this); + } + } + + void check(HttpResponse response) { + if (response.statusCode() >= 300) { + throw new HttpException(this, response); + } + } + + @Override + public BodyContent readContent(HttpResponse httpResponse) { + byte[] bodyBytes = decodeContent(httpResponse); + final String contentType = getContentType(httpResponse); + return new BodyContent(contentType, bodyBytes); + } + + String getContentType(HttpResponse httpResponse) { + return firstHeader(httpResponse.headers(), "Content-Type", "content-type"); + } + + String getContentEncoding(HttpResponse httpResponse) { + return firstHeader(httpResponse.headers(), "Content-Encoding", "content-encoding"); + } + + @Override + public byte[] decodeContent(String encoding, byte[] body) { + if (encoding.equals("gzip")) { + return GzipUtil.gzipDecode(body); + } + // todo: register decoders with context and use them + return body; + } + + public byte[] decodeContent(HttpResponse httpResponse) { + String encoding = getContentEncoding(httpResponse); + return encoding == null ? httpResponse.body() : decodeContent(encoding, httpResponse.body()); + } + + String firstHeader(HttpHeaders headers, String... names) { + final Map> map = headers.map(); + for (String key : names) { + final List values = map.get(key); + if (values != null && !values.isEmpty()) { + return values.get(0); + } + } + return null; + } + + HttpResponse send(HttpRequest.Builder requestBuilder, HttpResponse.BodyHandler bodyHandler) { + final HttpRequest request = applyFilters(requestBuilder).build(); + try { + return httpClient.send(request, bodyHandler); + } catch (IOException e) { + throw new HttpException(499, e); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new HttpException(499, e); + } + } + + private HttpRequest.Builder applyFilters(HttpRequest.Builder hreq) { + return hreq; + } + + BodyContent write(Object bean, String contentType) { + return bodyAdapter.beanWriter(bean.getClass()).write(bean, contentType); + } + + T readBean(Class cls, BodyContent content) { + return bodyAdapter.beanReader(cls).read(content); + } + + List readList(Class cls, BodyContent content) { + return bodyAdapter.listReader(cls).read(content); + } + + + void afterResponse(DHttpClientRequest request) { + if (requestListener != null) { + requestListener.response(request.listenerEvent()); + } + } + + void afterResponseHandler(DHttpClientRequest request) { + if (requestListener != null) { + requestListener.response(request.listenerEvent()); + } + } +} diff --git a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContextBuilder.java b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContextBuilder.java new file mode 100644 index 000000000..35ab87e62 --- /dev/null +++ b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContextBuilder.java @@ -0,0 +1,69 @@ +package io.avaje.http.client; + +import java.net.http.HttpClient; +import java.time.Duration; + +import static java.util.Objects.requireNonNull; + +class DHttpClientContextBuilder implements HttpClientContext.Builder { + + private HttpClient client; + + private String baseUrl; + + private Duration requestTimeout = Duration.ofSeconds(20); + + private BodyAdapter bodyAdapter; + + private RequestListener requestListener; + + DHttpClientContextBuilder() { + } + + @Override + public HttpClientContext.Builder with(HttpClient client) { + this.client = client; + return this; + } + + @Override + public HttpClientContext.Builder withBaseUrl(String baseUrl) { + this.baseUrl = baseUrl; + return this; + } + + @Override + public HttpClientContext.Builder withRequestTimeout(Duration requestTimeout) { + this.requestTimeout = requestTimeout; + return this; + } + + @Override + public HttpClientContext.Builder withBodyAdapter(BodyAdapter adapter) { + this.bodyAdapter = adapter; + return this; + } + + @Override + public HttpClientContext.Builder withRequestListener(RequestListener requestListener) { + this.requestListener = requestListener; + return this; + } + + @Override + public HttpClientContext build() { + requireNonNull(baseUrl, "baseUrl is not specified"); + requireNonNull(requestTimeout, "requestTimeout is not specified"); + if (client == null) { + client = defaultClient(); + } + return new DHttpClientContext(client, baseUrl, requestTimeout, bodyAdapter, requestListener); + } + + private HttpClient defaultClient() { + return HttpClient.newBuilder() + .connectTimeout(Duration.ofSeconds(20)) + .build(); + } + +} diff --git a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java new file mode 100644 index 000000000..3b65c4f42 --- /dev/null +++ b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java @@ -0,0 +1,443 @@ +package io.avaje.http.client; + +import javax.net.ssl.SSLSession; +import java.io.FileNotFoundException; +import java.io.InputStream; +import java.net.URI; +import java.net.URLEncoder; +import java.net.http.HttpClient; +import java.net.http.HttpHeaders; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.nio.charset.StandardCharsets; +import java.nio.file.Path; +import java.time.Duration; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.function.Supplier; +import java.util.stream.Stream; + +import static java.net.http.HttpResponse.BodyHandlers.discarding; + +class DHttpClientRequest implements HttpClientRequest, HttpClientResponse { + + private static final String CONTENT_TYPE = "Content-Type"; + private static final String CONTENT_ENCODING = "Content-Encoding"; + + private final DHttpClientContext context; + + private final UrlBuilder url; + + private Duration requestTimeout; + + private boolean gzip; + + private BodyContent encodedRequestBody; + + private HttpRequest.BodyPublisher body; + + private HttpRequest.Builder httpRequest; + + private Map formParams; + + private Map headers; + + private boolean bodyFormEncoded; + + private long requestTimeNanos; + + private HttpResponse httpResponse; + + private BodyContent encodedResponseBody; + + public DHttpClientRequest(DHttpClientContext context, Duration requestTimeout) { + this.context = context; + this.requestTimeout = requestTimeout; + this.url = context.url(); + } + + @Override + public HttpClientRequest requestTimeout(Duration requestTimeout) { + this.requestTimeout = requestTimeout; + return this; + } + + @Override + public HttpClientRequest header(String name, String value) { + if (headers == null) { + headers = new LinkedHashMap<>(); + } + headers.put(name, value); + return this; + } + + @Override + public HttpClientRequest gzip(boolean gzip) { + this.gzip = gzip; + return this; + } + + @Override + public HttpClientRequest path(String path) { + url.path(path); + return this; + } + + @Override + public HttpClientRequest matrixParam(String name, String value) { + url.matrixParam(name, value); + return this; + } + + + @Override + public HttpClientRequest param(String name, String value) { + url.param(name, value); + return this; + } + + @Override + public HttpClientRequest formParam(String name, String value) { + if (formParams == null) { + formParams = new LinkedHashMap<>(); + } + formParams.put(name, value); + return this; + } + + @Override + public HttpClientRequest body(BodyContent bodyContent) { + encodedRequestBody = bodyContent; + return this; + } + + @Override + public HttpClientRequest body(Object bean, String contentType) { + encodedRequestBody = context.write(bean, contentType); + return this; + } + + @Override + public HttpClientRequest body(Object bean) { + return body(bean, null); + } + + @Override + public HttpClientRequest body(String body) { + this.body = HttpRequest.BodyPublishers.ofString(body); + return this; + } + + @Override + public HttpClientRequest body(byte[] bytes) { + this.body = HttpRequest.BodyPublishers.ofByteArray(bytes); + return this; + } + + @Override + public HttpClientRequest body(Supplier streamSupplier) { + this.body = HttpRequest.BodyPublishers.ofInputStream(streamSupplier); + return this; + } + + @Override + public HttpClientRequest body(Path file) throws FileNotFoundException { + this.body = HttpRequest.BodyPublishers.ofFile(file); + return this; + } + + @Override + public HttpClientRequest body(HttpRequest.BodyPublisher body) { + this.body = body; + return this; + } + + private HttpRequest.BodyPublisher body() { + if (body != null) { + return body; + } else if (encodedRequestBody != null) { + return fromEncodedBody(); + } else if (formParams != null) { + return bodyFromForm(); + } else { + return null; + } + } + + private HttpRequest.BodyPublisher bodyFromForm() { + final String content = buildEncodedFormContent(); + bodyFormEncoded = true; + return HttpRequest.BodyPublishers.ofString(content); + } + + private String buildEncodedFormContent() { + var builder = new StringBuilder(80); + for (Map.Entry entry : formParams.entrySet()) { + if (builder.length() > 0) { + builder.append("&"); + } + builder.append(URLEncoder.encode(entry.getKey(), StandardCharsets.UTF_8)); + builder.append("="); + builder.append(URLEncoder.encode(entry.getValue(), StandardCharsets.UTF_8)); + } + return builder.toString(); + } + + private HttpRequest.BodyPublisher fromEncodedBody() { + if (gzip) { + return HttpRequest.BodyPublishers.ofByteArray(GzipUtil.gzip(encodedRequestBody.content())); + } + return HttpRequest.BodyPublishers.ofByteArray(encodedRequestBody.content()); + } + + private void addHeaders() { + if (encodedRequestBody != null) { + final String contentType = encodedRequestBody.contentType(); + if (contentType != null) { + httpRequest.header(CONTENT_TYPE, contentType); + } + } else if (bodyFormEncoded) { + httpRequest.header(CONTENT_TYPE, "application/x-www-form-urlencoded"); + } + if (gzip) { + httpRequest.header(CONTENT_ENCODING, "gzip"); + } + if (headers != null) { + for (Map.Entry header : headers.entrySet()) { + httpRequest.header(header.getKey(), header.getValue()); + } + } + } + + public HttpClientResponse get() { + httpRequest = newGet(url.build()); + addHeaders(); + return this; + } + + @Override + public HttpClientResponse delete() { + httpRequest = newDelete(url.build()); + addHeaders(); + return this; + } + + @Override + public HttpClientResponse post() { + httpRequest = newPost(url.build(), body()); + addHeaders(); + return this; + } + + @Override + public HttpClientResponse put() { + httpRequest = newPut(url.build(), body()); + addHeaders(); + return this; + } + + private void readResponseContent() { + final HttpResponse response = asByteArray(); + this.httpResponse = response; + context.check(response); + encodedResponseBody = context.readContent(response); + context.afterResponse(this); + } + + @Override + public HttpResponse asVoid() { + readResponseContent(); + return new HttpVoidResponse(httpResponse); + } + + @Override + public T read(BodyReader reader) { + readResponseContent(); + return reader.read(encodedResponseBody); + } + + @Override + public T bean(Class cls) { + readResponseContent(); + return context.readBean(cls, encodedResponseBody); + } + + @Override + public List list(Class cls) { + readResponseContent(); + return context.readList(cls, encodedResponseBody); + } + + @Override + public HttpResponse withResponseHandler(HttpResponse.BodyHandler responseHandler) { + long startNanos = System.nanoTime(); + final HttpResponse response = context.send(httpRequest, responseHandler); + this.requestTimeNanos = System.nanoTime() - startNanos; + this.httpResponse = response; + context.afterResponseHandler(this); + return response; + } + + @Override + public HttpResponse asByteArray() { + return withResponseHandler(HttpResponse.BodyHandlers.ofByteArray()); + } + + @Override + public HttpResponse asString() { + return withResponseHandler(HttpResponse.BodyHandlers.ofString()); + } + + @Override + public HttpResponse asDiscarding() { + return withResponseHandler(discarding()); + } + + @Override + public HttpResponse asInputStream() { + return withResponseHandler(HttpResponse.BodyHandlers.ofInputStream()); + } + + @Override + public HttpResponse asFile(Path file) { + return withResponseHandler(HttpResponse.BodyHandlers.ofFile(file)); + } + + @Override + public HttpResponse> asLines() { + return withResponseHandler(HttpResponse.BodyHandlers.ofLines()); + } + + protected HttpRequest.Builder newGet(String url) { + return HttpRequest.newBuilder() + .uri(URI.create(url)) + .timeout(requestTimeout) + .GET(); + } + + protected HttpRequest.Builder newDelete(String url) { + return HttpRequest.newBuilder() + .uri(URI.create(url)) + .timeout(requestTimeout) + .DELETE(); + } + + public HttpRequest.Builder newPost(String url, HttpRequest.BodyPublisher body) { + return newRequest("POST", url, body); + } + + public HttpRequest.Builder newPut(String url, HttpRequest.BodyPublisher body) { + return newRequest("PUT", url, body); + } + + public HttpRequest.Builder newPatch(String url, HttpRequest.BodyPublisher body) { + return newRequest("PATCH", url, body); + } + + protected HttpRequest.Builder newRequest(String method, String url, HttpRequest.BodyPublisher body) { + if (body == null) { + throw new IllegalArgumentException("body is null but required for " + method + " to " + url); + } + return HttpRequest.newBuilder() + .uri(URI.create(url)) + .timeout(requestTimeout) + .method(method, body); + } + + RequestListener.Event listenerEvent() { + return new ListenerEvent(); + } + + private class ListenerEvent implements RequestListener.Event { + + @Override + public long requestTimeNanos() { + return requestTimeNanos; + } + + @Override + public URI uri() { + return httpResponse.uri(); + } + + @Override + public HttpResponse response() { + return httpResponse; + } + + @Override + public String requestBody() { + if (encodedRequestBody != null) { + return new String(encodedRequestBody.content(), StandardCharsets.UTF_8); + } + if (bodyFormEncoded) { + return buildEncodedFormContent(); + } + if (body != null) { + return body.toString(); + } + return null; + } + + @Override + public String responseBody() { + if (encodedResponseBody != null) { + return new String(encodedResponseBody.content(), StandardCharsets.UTF_8); + } + return null; + } + } + + static class HttpVoidResponse implements HttpResponse { + + private final HttpResponse orig; + + @SuppressWarnings({"unchecked", "raw"}) + HttpVoidResponse(HttpResponse orig) { + this.orig = orig; + } + + @Override + public int statusCode() { + return orig.statusCode(); + } + + @Override + public HttpRequest request() { + return orig.request(); + } + + @Override + public Optional> previousResponse() { + return Optional.empty(); + } + + @Override + public HttpHeaders headers() { + return orig.headers(); + } + + @Override + public Void body() { + return null; + } + + @Override + public Optional sslSession() { + return orig.sslSession(); + } + + @Override + public URI uri() { + return orig.uri(); + } + + @Override + public HttpClient.Version version() { + return orig.version(); + } + } + +} diff --git a/http-client/client/src/main/java/io/avaje/http/client/GzipUtil.java b/http-client/client/src/main/java/io/avaje/http/client/GzipUtil.java new file mode 100644 index 000000000..4b7cba1e4 --- /dev/null +++ b/http-client/client/src/main/java/io/avaje/http/client/GzipUtil.java @@ -0,0 +1,37 @@ +package io.avaje.http.client; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.util.zip.GZIPInputStream; +import java.util.zip.GZIPOutputStream; + +class GzipUtil { + + static byte[] gzip(String content) { + return gzip(content.getBytes(StandardCharsets.UTF_8)); + } + + static byte[] gzip(byte[] content) { + try { + ByteArrayOutputStream obj = new ByteArrayOutputStream(); + try (GZIPOutputStream gzip = new GZIPOutputStream(obj)) { + gzip.write(content); + } + return obj.toByteArray(); + } catch (IOException e) { + throw new RuntimeException("Error while gzip encoding content", e); + } + } + + static byte[] gzipDecode(byte[] content) { + try { + try (final GZIPInputStream unzip = new GZIPInputStream(new ByteArrayInputStream(content))) { + return unzip.readAllBytes(); + } + } catch (IOException e) { + throw new RuntimeException("Error while gzip decoding content", e); + } + } +} diff --git a/http-client/client/src/main/java/io/avaje/http/client/HttpApiProvider.java b/http-client/client/src/main/java/io/avaje/http/client/HttpApiProvider.java new file mode 100644 index 000000000..d574c1590 --- /dev/null +++ b/http-client/client/src/main/java/io/avaje/http/client/HttpApiProvider.java @@ -0,0 +1,7 @@ +package io.avaje.http.client; + +public interface HttpApiProvider { + + T provide(HttpClientContext client); + +} diff --git a/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java b/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java new file mode 100644 index 000000000..bd60abd35 --- /dev/null +++ b/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java @@ -0,0 +1,105 @@ +package io.avaje.http.client; + +import java.net.http.HttpClient; +import java.net.http.HttpResponse; +import java.time.Duration; + +/** + * The HTTP client context that we use to build and process requests. + */ +public interface HttpClientContext { + + /** + * Return the builder to config and build the client context. + */ + static HttpClientContext.Builder newBuilder() { + return new DHttpClientContextBuilder(); + } + + /** + * Create a new request. + */ + HttpClientRequest request(); + + /** + * Return a UrlBuilder to use to build an URL taking into + * account the base URL. + */ + UrlBuilder url(); + + /** + * Return the body adapter used by the client context. + */ + BodyAdapter converters(); + + /** + * Return the underlying http client. + */ + HttpClient httpClient(); + + /** + * Check the response status code and throw HttpException if the status + * code is in the error range. + */ + void checkResponse(HttpResponse response); + + /** + * Return the response content taking into account content encoding. + * + * @param httpResponse The HTTP response to decode the content from + * @return The decoded content + */ + BodyContent readContent(HttpResponse httpResponse); + + /** + * Decode the response content given the Content-Encoding http header. + * + * @param httpResponse The HTTP response + * @return The decoded content + */ + byte[] decodeContent(HttpResponse httpResponse); + + /** + * Decode the body using the given encoding. + * + * @param encoding The encoding used to decode the content + * @param content The raw content being decoded + * @return The decoded content + */ + byte[] decodeContent(String encoding, byte[] content); + + + /** + * Builds the HttpClientContext. + */ + interface Builder { + + /** + * Set the underlying HttpClient to use. + */ + Builder with(HttpClient client); + + /** + * Set the base URL to use for requests created from the context. + */ + Builder withBaseUrl(String baseUrl); + + /** + * Set the default request timeout. + */ + Builder withRequestTimeout(Duration requestTimeout); + + /** + * Set the body adapter to use to convert beans to body content + * and response content back to beans. + */ + Builder withBodyAdapter(BodyAdapter adapter); + + Builder withRequestListener(RequestListener requestListener); + + /** + * Build and return the context. + */ + HttpClientContext build(); + } +} diff --git a/http-client/client/src/main/java/io/avaje/http/client/HttpClientRequest.java b/http-client/client/src/main/java/io/avaje/http/client/HttpClientRequest.java new file mode 100644 index 000000000..0fc87ed3b --- /dev/null +++ b/http-client/client/src/main/java/io/avaje/http/client/HttpClientRequest.java @@ -0,0 +1,156 @@ +package io.avaje.http.client; + +import java.io.FileNotFoundException; +import java.io.InputStream; +import java.net.http.HttpRequest; +import java.nio.file.Path; +import java.time.Duration; +import java.util.function.Supplier; + +/** + * Http request that is built and sent to the server. + *

+ * Largely wraps the standard JDK HttpRequest with additional + * support for converting beans to body content and converting + * beans from response content. + */ +public interface HttpClientRequest { + + /** + * Set the request timeout to use for this request. When not set the default + * request timeout will be used. + * + * @param requestTimeout The request timeout to use for this request. + * @return The request being built + */ + HttpClientRequest requestTimeout(Duration requestTimeout); + + /** + * Add the header to the request. + * + * @param name The header name + * @param value The header value + * @return The request being built + */ + HttpClientRequest header(String name, String value); + + /** + * Set if body content should be gzip encoded. + * + * @param gzip Set true to gzip encode the body content. + * @return The request being built + */ + HttpClientRequest gzip(boolean gzip); + + /** + * Add a path segment to the URL. + * + * @param path The path segment to add to the URL path. + * @return The request being built + */ + HttpClientRequest path(String path); + + /** + * Add a matrix parameter to the current path segment. + * + * @param name The matrix parameter name + * @param value The matrix parameter value + * @return The request being built + */ + HttpClientRequest matrixParam(String name, String value); + + /** + * Add a query parameter + * + * @param name The name of the query parameter + * @param value The value of the query parameter + * @return The request being built + */ + HttpClientRequest param(String name, String value); + + /** + * Add a form parameter. + * + * @param name The form parameter name + * @param value The form parameter value + * @return The request being built + */ + HttpClientRequest formParam(String name, String value); + + /** + * Set encoded body content. + */ + HttpClientRequest body(BodyContent bodyContent); + + /** + * Set the body as a bean with the given content type using a BodyWriter. + */ + HttpClientRequest body(Object bean, String contentType); + + /** + * Set the body as a bean using the default content type. The default + * content type will often be application/json; charset=utf8. + */ + HttpClientRequest body(Object bean); + + /** + * Set the body content as a string. + * + * @param body The body content + * @return The request being built + */ + HttpClientRequest body(String body); + + /** + * Set the body content as a bytes. + * + * @param body The body content + * @return The request being built + */ + HttpClientRequest body(byte[] body); + + /** + * Set the body content with supplied InputStream. + * + * @param supplier The supplier of InputStream content to send as body content + * @return The request being built + */ + HttpClientRequest body(Supplier supplier); + + /** + * Set the body content with supplied InputStream. + * + * @param file The file to send as body content + * @return The request being built + */ + HttpClientRequest body(Path file) throws FileNotFoundException; + + /** + * Set the body content using http BodyPublisher. + * + * @param body The body content + * @return The request being built + */ + HttpClientRequest body(HttpRequest.BodyPublisher body); + + /** + * Execute the request as a GET. + */ + HttpClientResponse get(); + + /** + * Execute the request as a POST. + */ + HttpClientResponse post(); + + /** + * Execute the request as a PUT. + */ + HttpClientResponse put(); + + /** + * Execute the request as a DELETE. + */ + HttpClientResponse delete(); + +} diff --git a/http-client/client/src/main/java/io/avaje/http/client/HttpClientResponse.java b/http-client/client/src/main/java/io/avaje/http/client/HttpClientResponse.java new file mode 100644 index 000000000..13a9e38df --- /dev/null +++ b/http-client/client/src/main/java/io/avaje/http/client/HttpClientResponse.java @@ -0,0 +1,95 @@ +package io.avaje.http.client; + +import java.io.InputStream; +import java.net.http.HttpResponse; +import java.nio.file.Path; +import java.util.List; +import java.util.stream.Stream; + +/** + * Controls how the response is processed including potential + * conversion into beans. + */ +public interface HttpClientResponse { + + /** + * Returning the response using the given response reader. + * + * @param reader The response reader. + * @param The type that the content is converted to. + * @return The response converted into the appropriate bean via the reader. + * @throws HttpException when the response has error status codes + */ + T read(BodyReader reader); + + /** + * Return the response as a single bean. + * + * @param type The type of the bean to convert the response content into. + * @param The type that the content is converted to. + * @return The bean the response is converted into. + * @throws HttpException when the response has error status codes + */ + T bean(Class type); + + /** + * Return the response as a list of beans. + * + * @param type The type of the bean to convert the response content into. + * @param The type that the content is converted to. + * @return The list of beans the response is converted into. + * @throws HttpException when the response has error status codes + */ + List list(Class type); + + /** + * Return the response with check for 200 range status code. + *

+ * Will throw an HttpException if the status code is in the + * error range allowing the caller to access the error message + * body via {@link HttpException#bean(Class)} + *

+ * This is intended to be used for POST, PUT, DELETE requests + * where the caller is only interested in the response body + * when an error occurs (status code not in 200 range). + * + * @throws HttpException when the response has error status codes + */ + HttpResponse asVoid(); + + /** + * Return the content as string. + */ + HttpResponse asString(); + + /** + * Return the response discarding the response content. + */ + HttpResponse asDiscarding(); + + /** + * Return the content as InputStream. + */ + HttpResponse asInputStream(); + + /** + * Return the content as a stream of string lines. + */ + HttpResponse> asLines(); + + /** + * Return the content as byte array. + */ + HttpResponse asByteArray(); + + /** + * Return the content into the given file. + */ + HttpResponse asFile(Path file); + + /** + * Return the response using the given response body handler. + */ + HttpResponse withResponseHandler(HttpResponse.BodyHandler responseHandler); + +} diff --git a/http-client/client/src/main/java/io/avaje/http/client/HttpException.java b/http-client/client/src/main/java/io/avaje/http/client/HttpException.java new file mode 100644 index 000000000..12e0d5bad --- /dev/null +++ b/http-client/client/src/main/java/io/avaje/http/client/HttpException.java @@ -0,0 +1,85 @@ +package io.avaje.http.client; + +import java.net.http.HttpResponse; +import java.nio.charset.StandardCharsets; + +public class HttpException extends RuntimeException { + + private final int statusCode; + private HttpClientContext context; + private HttpResponse httpResponse; + + public HttpException(int statusCode, String message) { + super(message); + this.statusCode = statusCode; + } + + public HttpException(int statusCode, String message, Throwable cause) { + super(message, cause); + this.statusCode = statusCode; + } + + public HttpException(int statusCode, Throwable cause) { + super(cause); + this.statusCode = statusCode; + } + + HttpException(HttpResponse httpResponse, HttpClientContext context) { + super(); + this.httpResponse = httpResponse; + this.statusCode = httpResponse.statusCode(); + this.context = context; + } + + HttpException(HttpClientContext context, HttpResponse httpResponse) { + super(); + this.httpResponse = httpResponse; + this.statusCode = httpResponse.statusCode(); + this.context = context; + } + + /** + * Return the response body content as a bean + * + * @param cls The type of bean to convert the response to + * @return The response as a bean + */ + @SuppressWarnings("unchecked") + public T bean(Class cls) { + final BodyContent body = context.readContent((HttpResponse) httpResponse); + return context.converters().beanReader(cls).read(body); + } + + /** + * Return the response body content as a UTF8 string. + */ + @SuppressWarnings("unchecked") + public String bodyAsString() { + final BodyContent body = context.readContent((HttpResponse) httpResponse); + return new String(body.content(), StandardCharsets.UTF_8); + } + + /** + * Return the response body content as raw bytes. + */ + @SuppressWarnings("unchecked") + public byte[] bodyAsBytes() { + final BodyContent body = context.readContent((HttpResponse) httpResponse); + return body.content(); + } + + /** + * Return the HTTP status code. + */ + public int getStatusCode() { + return statusCode; + } + + /** + * Return the underlying HttpResponse. + */ + public HttpResponse getHttpResponse() { + return httpResponse; + } + +} diff --git a/http-client/client/src/main/java/io/avaje/http/client/JacksonBodyAdapter.java b/http-client/client/src/main/java/io/avaje/http/client/JacksonBodyAdapter.java new file mode 100644 index 000000000..df69caf9a --- /dev/null +++ b/http-client/client/src/main/java/io/avaje/http/client/JacksonBodyAdapter.java @@ -0,0 +1,107 @@ +package io.avaje.http.client; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.ObjectReader; +import com.fasterxml.jackson.databind.ObjectWriter; +import com.fasterxml.jackson.databind.type.CollectionType; + +import java.io.IOException; +import java.util.List; +import java.util.concurrent.ConcurrentHashMap; + +public class JacksonBodyAdapter implements BodyAdapter { + + private final ObjectMapper mapper; + + private final ConcurrentHashMap, BodyWriter> beanWriterCache = new ConcurrentHashMap<>(); + + private final ConcurrentHashMap, BodyReader> beanReaderCache = new ConcurrentHashMap<>(); + + private final ConcurrentHashMap, BodyReader> listReaderCache = new ConcurrentHashMap<>(); + + public JacksonBodyAdapter(ObjectMapper mapper) { + this.mapper = mapper; + } + + @Override + public BodyWriter beanWriter(Class cls) { + return beanWriterCache.computeIfAbsent(cls, aClass -> { + try { + return new JWriter(mapper.writerFor(cls)); + } catch (Exception e) { + throw new RuntimeException(e); + } + }); + } + + @SuppressWarnings("unchecked") + @Override + public BodyReader beanReader(Class cls) { + return (BodyReader) beanReaderCache.computeIfAbsent(cls, aClass -> { + try { + return new JReader<>(mapper.readerFor(cls)); + } catch (Exception e) { + throw new RuntimeException(e); + } + }); + } + + @SuppressWarnings("unchecked") + @Override + public BodyReader> listReader(Class cls) { + return (BodyReader>) listReaderCache.computeIfAbsent(cls, aClass -> { + try { + final CollectionType collectionType = mapper.getTypeFactory().constructCollectionType(List.class, cls); + final ObjectReader reader = mapper.readerFor(collectionType); + return new JReader<>(reader); + } catch (Exception e) { + throw new RuntimeException(e); + } + }); + } + + private static class JReader implements BodyReader { + + private final ObjectReader reader; + + JReader(ObjectReader reader) { + this.reader = reader; + } + + @Override + public T read(BodyContent s) { + try { + return reader.readValue(s.content()); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + } + + private static class JWriter implements BodyWriter { + + private final ObjectWriter writer; + + public JWriter(ObjectWriter writer) { + this.writer = writer; + } + + @Override + public BodyContent write(Object bean, String contentType) { + // ignoring the requested contentType and always + // writing the body as json content + return write(bean); + } + + @Override + public BodyContent write(Object bean) { + try { + return BodyContent.asJson(writer.writeValueAsBytes(bean)); + } catch (JsonProcessingException e) { + throw new RuntimeException(e); + } + } + } + +} diff --git a/http-client/client/src/main/java/io/avaje/http/client/RequestListener.java b/http-client/client/src/main/java/io/avaje/http/client/RequestListener.java new file mode 100644 index 000000000..c8ccd3afc --- /dev/null +++ b/http-client/client/src/main/java/io/avaje/http/client/RequestListener.java @@ -0,0 +1,22 @@ +package io.avaje.http.client; + +import java.net.URI; +import java.net.http.HttpResponse; + +public interface RequestListener { + + void response(Event event); + + interface Event { + + long requestTimeNanos(); + + HttpResponse response(); + + String requestBody(); + + String responseBody(); + + URI uri(); + } +} diff --git a/http-client/client/src/main/java/io/avaje/http/client/RequestLogger.java b/http-client/client/src/main/java/io/avaje/http/client/RequestLogger.java new file mode 100644 index 000000000..7d6e2366f --- /dev/null +++ b/http-client/client/src/main/java/io/avaje/http/client/RequestLogger.java @@ -0,0 +1,63 @@ +package io.avaje.http.client; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.net.http.HttpHeaders; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.util.List; +import java.util.Map; +import java.util.Set; + +public class RequestLogger implements RequestListener { + + private static final Logger log = LoggerFactory.getLogger(RequestLogger.class); + + private final String delimiter; + + public RequestLogger() { + this("\n"); + } + + public RequestLogger(String delimiter) { + this.delimiter = delimiter; + } + + @Override + public void response(Event event) { + if (log.isDebugEnabled()) { + final HttpResponse response = event.response(); + final HttpRequest request = response.request(); + long micros = event.requestTimeNanos() / 1000; + + StringBuilder sb = new StringBuilder(); + sb.append("statusCode:").append(response.statusCode()) + .append(" method:").append(request.method()) + .append(" uri:").append(event.uri()) + .append(" timeMicros:").append(micros); + + headers(sb, "req-head: ", request.headers()); + body(sb, "req-body: ", event.requestBody()); + headers(sb, "res-head: ", response.headers()); + body(sb, "res-body: ", event.responseBody()); + log.debug(sb.toString()); + } + } + + private void body(StringBuilder sb, String label, String body) { + if (body != null) { + sb.append(delimiter).append(label).append(body); + } + } + + private void headers(StringBuilder sb, String label, HttpHeaders headers) { + final Set>> entries = headers.map().entrySet(); + if (!entries.isEmpty()) { + sb.append(delimiter).append(label); + for (Map.Entry> entry : entries) { + sb.append(entry.getKey()).append("=").append(entry.getValue()).append("; "); + } + } + } +} diff --git a/http-client/client/src/main/java/io/avaje/http/client/UrlBuilder.java b/http-client/client/src/main/java/io/avaje/http/client/UrlBuilder.java new file mode 100644 index 000000000..e8449dc48 --- /dev/null +++ b/http-client/client/src/main/java/io/avaje/http/client/UrlBuilder.java @@ -0,0 +1,46 @@ +package io.avaje.http.client; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; + +public class UrlBuilder { + + private final StringBuilder buffer = new StringBuilder(100); + + boolean hasParams; + + public UrlBuilder(String base) { + buffer.append(base); + } + + public UrlBuilder path(String path) { + buffer.append("/").append(path); + return this; + } + + public UrlBuilder param(String name, String value) { + if (value != null) { + buffer.append(hasParams ? '&' : '?'); + hasParams = true; + buffer.append(enc(name)).append("=").append(enc(value)); + } + return this; + } + + public UrlBuilder matrixParam(String name, String value) { + if (value != null) { + buffer.append(';').append(enc(name)).append("=").append(enc(value)); + } + return this; + } + + public static String enc(String val) { + return URLEncoder.encode(val, StandardCharsets.UTF_8); + } + + public String build() { + return buffer.toString(); + } + + +} diff --git a/http-client/client/src/test/java/io/avaje/http/client/BaseWebTest.java b/http-client/client/src/test/java/io/avaje/http/client/BaseWebTest.java new file mode 100644 index 000000000..c424712f8 --- /dev/null +++ b/http-client/client/src/test/java/io/avaje/http/client/BaseWebTest.java @@ -0,0 +1,34 @@ +package io.avaje.http.client; + +import com.fasterxml.jackson.databind.ObjectMapper; +import io.javalin.Javalin; +import org.example.webserver.App; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; + +public class BaseWebTest { + + static Javalin webServer; + + public static String baseUrl; + + @BeforeAll + public static void init() { + webServer = App.start(8887); + baseUrl = "http://localhost:8887"; + } + + @AfterAll + public static void shutdown() { + webServer.stop(); + } + + public static HttpClientContext client() { + return HttpClientContext.newBuilder() + .withBaseUrl(baseUrl) + .withRequestListener(new RequestLogger()) + .withBodyAdapter(new JacksonBodyAdapter(new ObjectMapper())) + //.with(httpClient) + .build(); + } +} diff --git a/http-client/client/src/test/java/io/avaje/http/client/DHttpClientContextTest.java b/http-client/client/src/test/java/io/avaje/http/client/DHttpClientContextTest.java new file mode 100644 index 000000000..8d0ee1372 --- /dev/null +++ b/http-client/client/src/test/java/io/avaje/http/client/DHttpClientContextTest.java @@ -0,0 +1,60 @@ +package io.avaje.http.client; + +import org.junit.jupiter.api.Test; + +import java.net.http.HttpClient; +import java.nio.charset.StandardCharsets; + +import static org.assertj.core.api.Assertions.assertThat; + +class DHttpClientContextTest { + + private final DHttpClientContext context = new DHttpClientContext(null, null, null, null, null); + + @Test + void gzip_gzipDecode() { + + final byte[] asBytes = GzipUtil.gzip("HelloThere"); + final byte[] decoded = GzipUtil.gzipDecode(asBytes); + assertThat(new String(decoded, StandardCharsets.UTF_8)).isEqualTo("HelloThere"); + + final byte[] decoded2 = context.decodeContent("gzip", asBytes); + assertThat(new String(decoded2, StandardCharsets.UTF_8)).isEqualTo("HelloThere"); + } + + @Test + void gzip_contentDecode() { + + final byte[] asBytes = GzipUtil.gzip("HelloThere gzip_contentDecode"); + final byte[] decoded2 = context.decodeContent("gzip", asBytes); + assertThat(new String(decoded2, StandardCharsets.UTF_8)).isEqualTo("HelloThere gzip_contentDecode"); + } + + @Test + void build_basic() { + + final HttpClientContext context = + HttpClientContext.newBuilder() + .withBaseUrl("http://localhost") + .build(); + + // has default client created + assertThat(context.httpClient()).isNotNull(); + assertThat(context.httpClient().version()).isEqualTo(HttpClient.Version.HTTP_2); + + // has expected url building + assertThat(context.url().build()).isEqualTo("http://localhost"); + assertThat(context.url().path("hello").build()).isEqualTo("http://localhost/hello"); + assertThat(context.url().param("hello","there").build()).isEqualTo("http://localhost?hello=there"); + } + + @Test + void build_missingBaseUrl() { + try { + HttpClientContext.newBuilder().build(); + } catch (NullPointerException e) { + assertThat(e.getMessage()).contains("baseUrl is not specified"); + } + } + +} diff --git a/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java b/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java new file mode 100644 index 000000000..b88ec0f05 --- /dev/null +++ b/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java @@ -0,0 +1,211 @@ +package io.avaje.http.client; + +import org.example.webserver.ErrorResponse; +import org.example.webserver.HelloDto; +import org.junit.jupiter.api.Test; + +import java.net.http.HttpResponse; +import java.util.List; +import java.util.Map; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.fail; + +class HelloControllerTest extends BaseWebTest { + + final HttpClientContext clientContext = client(); + + @Test + void get_helloMessage() { + + final HttpResponse hres = clientContext.request() + .path("hello").path("message") + .get().asString(); + + assertThat(hres.body()).contains("hello world"); + assertThat(hres.statusCode()).isEqualTo(200); + } + + @Test + void get_hello_returningListOfBeans() { + + final List helloDtos = clientContext.request() + .path("hello") + .get().list(HelloDto.class); + + assertThat(helloDtos).hasSize(2); + } + + @Test + void get_withPathParamAndQueryParam_returningBean() { + + final HelloDto dto = clientContext.request() + .path("hello/43/2020-03-05").param("otherParam", "other").param("foo", null) + .get().bean(HelloDto.class); + + assertThat(dto.id).isEqualTo(43L); + assertThat(dto.name).isEqualTo("2020-03-05"); + assertThat(dto.otherParam).isEqualTo("other"); + } + + @Test + void post_bean_returningBean_usingExplicitConverters() { + + HelloDto dto = new HelloDto(12, "rob", "other"); + + final BodyWriter from = clientContext.converters().beanWriter(HelloDto.class); + final BodyReader toDto = clientContext.converters().beanReader(HelloDto.class); + + final HelloDto bean = clientContext.request() + .path("hello") + .body(from.write(dto)) + .post() + .read(toDto); + + assertEquals("posted", bean.name); + assertEquals(12, bean.id); + } + + @Test + void post_bean_returningVoid() { + + HelloDto dto = new HelloDto(12, "rob", "other"); + + final HttpResponse res = clientContext.request() + .path("hello/savebean/foo") + .body(dto).post() + .asDiscarding(); + + assertThat(res.statusCode()).isEqualTo(201); + } + + @Test + void postForm() { + + final HttpResponse res = clientContext.request() + .path("hello/saveform") + .formParam("name", "Bazz") + .formParam("email", "user@foo.com") + .formParam("url", "http://foo.com") + .formParam("startDate", "2020-12-03") + .post() + .asDiscarding(); + + assertThat(res.statusCode()).isEqualTo(201); + } + + @Test + void postForm_returningBean() { + + final HttpResponse res = clientContext.request() + .path("hello/saveform") + .formParam("name", "Bazz") + .formParam("email", "user@foo.com") + .formParam("url", "http://foo.com") + .formParam("startDate", "2020-12-03") + .post() + .asDiscarding(); + + assertThat(res.statusCode()).isEqualTo(201); + + final HelloDto bean = clientContext.request() + .path("hello/saveform3") + .formParam("name", "Bax") + .formParam("email", "Bax@foo.com") + .formParam("url", "http://foo.com") + .formParam("startDate", "2020-12-03") + .post() + .bean(HelloDto.class); + + assertThat(bean.name).isEqualTo("Bax"); + assertThat(bean.otherParam).isEqualTo("Bax@foo.com"); + assertThat(bean.id).isEqualTo(52); + } + + @Test + void postForm_asVoid_invokesValidation_expect_badRequest_extractError() { + + try { + clientContext.request() + .path("hello/saveform") + .formParam("email", "user@foo.com") + .formParam("url", "notAValidUrl") + .post() + .asVoid(); + + fail(); + + } catch (HttpException e) { + assertEquals(422, e.getStatusCode()); + + final HttpResponse httpResponse = e.getHttpResponse(); + assertNotNull(httpResponse); + assertEquals(422, httpResponse.statusCode()); + + final ErrorResponse errorResponse = e.bean(ErrorResponse.class); + + final Map errorMap = errorResponse.getErrors(); + assertThat(errorMap.get("url")).isEqualTo("must be a valid URL"); + assertThat(errorMap.get("name")).isEqualTo("must not be null"); + } + } + + @Test + void postForm_asBytes_validation_expect_badRequest_extractError() { + + try { + clientContext.request() + .path("hello/saveform") + .formParam("email", "user@foo.com") + .formParam("url", "notAValidUrl") + .post().asVoid(); + + fail(); + + } catch (HttpException e) { + assertEquals(422, e.getStatusCode()); + + final HttpResponse httpResponse = e.getHttpResponse(); + assertNotNull(httpResponse); + assertEquals(422, httpResponse.statusCode()); + + final ErrorResponse errorResponse = e.bean(ErrorResponse.class); + final Map errorMap = errorResponse.getErrors(); + assertThat(errorMap.get("url")).isEqualTo("must be a valid URL"); + assertThat(errorMap.get("name")).isEqualTo("must not be null"); + + String rawBody = e.bodyAsString(); + assertThat(rawBody).contains("must be a valid URL"); + + final byte[] rawBytes = e.bodyAsBytes(); + assertThat(rawBytes).isNotNull(); + } + } + + @Test + void delete() { + final HttpResponse res = + clientContext.request() + .path("hello/52") + .delete().asDiscarding(); + + assertThat(res.statusCode()).isEqualTo(204); + } + + @Test + void get_withMatrixParam() { + + final HttpResponse httpRes = clientContext.request() + .path("hello/withMatrix/2011") + .matrixParam("author", "rob") + .matrixParam("country", "nz") + .path("foo") + .param("extra", "banana") + .get().asString(); + + assertEquals(200, httpRes.statusCode()); + assertEquals("yr:2011 au:rob co:nz other:foo extra:banana", httpRes.body()); + } +} diff --git a/http-client/client/src/test/java/io/avaje/http/client/UrlBuilderTest.java b/http-client/client/src/test/java/io/avaje/http/client/UrlBuilderTest.java new file mode 100644 index 000000000..e721d4fc1 --- /dev/null +++ b/http-client/client/src/test/java/io/avaje/http/client/UrlBuilderTest.java @@ -0,0 +1,57 @@ +package io.avaje.http.client; + +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +class UrlBuilderTest { + + @Test + void path() { + assertThat(new UrlBuilder("https://foo").path("bar").build()).isEqualTo("https://foo/bar"); + } + + @Test + void matrixParam() { + final String url = new UrlBuilder("https://foo").path("bar").matrixParam("a", "one").matrixParam("b", "two") + .build(); + + assertThat(url).isEqualTo("https://foo/bar;a=one;b=two"); + } + + @Test + void matrixParam_null() { + final String url = new UrlBuilder("https://foo").path("bar").matrixParam("a", null).matrixParam("b", "two") + .build(); + + assertThat(url).isEqualTo("https://foo/bar;b=two"); + } + + @Test + void matrixParam_path() { + final String url = new UrlBuilder("https://foo") + .path("bar").matrixParam("a", null).matrixParam("b", "two") + .path("foo") + .build(); + + assertThat(url).isEqualTo("https://foo/bar;b=two/foo"); + } + + @Test + void param() { + assertThat(new UrlBuilder("https://foo").param("bar", null).build()).isEqualTo("https://foo"); + assertThat(new UrlBuilder("https://foo").param("bar", "a").build()).isEqualTo("https://foo?bar=a"); + assertThat(new UrlBuilder("https://foo").param("bar", "a").param("baz", "b").build()).isEqualTo("https://foo?bar=a&baz=b"); + } + + @Test + void param_encode() { + assertThat(new UrlBuilder("https://foo").param("some one", "a%b").build()).isEqualTo("https://foo?some+one=a%25b"); + } + + @Test + void env() { + assertThat(UrlBuilder.enc("some one")).isEqualTo("some+one"); + assertThat(UrlBuilder.enc("a%b")).isEqualTo("a%25b"); + } +} diff --git a/http-client/client/src/test/java/org/example/Repo.java b/http-client/client/src/test/java/org/example/Repo.java new file mode 100644 index 000000000..b33bbb68d --- /dev/null +++ b/http-client/client/src/test/java/org/example/Repo.java @@ -0,0 +1,6 @@ +package org.example; + +public class Repo { + public long id; + public String name; +} diff --git a/http-client/client/src/test/java/org/example/Simple$rc.java b/http-client/client/src/test/java/org/example/Simple$rc.java new file mode 100644 index 000000000..fdac9615a --- /dev/null +++ b/http-client/client/src/test/java/org/example/Simple$rc.java @@ -0,0 +1,79 @@ +package org.example; + +import io.avaje.http.client.BodyReader; +import io.avaje.http.client.BodyWriter; +import io.avaje.http.client.HttpApiProvider; +import io.avaje.http.client.HttpClientContext; +import io.avaje.http.client.HttpException; +import io.dinject.controller.Get; +import io.dinject.controller.Post; + +import java.io.InputStream; +import java.net.http.HttpResponse; +import java.util.List; + + +class Simple$rc implements Simple { + + private final HttpClientContext context; + private final BodyReader readRepo; + private final BodyWriter writeRepo; +// private final BodyConverter, String> toListOfRepo; + + Simple$rc(HttpClientContext context) { + this.context = context; + this.readRepo = context.converters().beanReader(Repo.class); + this.writeRepo = context.converters().beanWriter(Repo.class); +// this.toListOfRepo = context.converters().toListOf(Repo.class); + } + + @Get("users/{user}/repos") + @Override + public List listRepos(String user, String other) throws HttpException { + return context.request() + .path("users").path(user).path("repos") + .param("other", other) + .get().list(Repo.class); + } + + @Post("users") + @Override + public Repo post(Repo repo) throws HttpException { + return context.request() + .path("foo/users") + .body(writeRepo.write(repo)) + .post().read(readRepo); + } + + @Get("users/{id}") + @Override + public Repo getById(String id) { + return context.request() + .path("users").path(id) + .get().bean(Repo.class); + } + + public InputStream getById2(String id, InputStream is) { + final HttpResponse response = + context.request() + .path("users").path(id).path("stream") + .body(() -> is) + .get().withResponseHandler(HttpResponse.BodyHandlers.ofInputStream()); + + context.checkResponse(response); + return response.body(); + } + + @Override + public HttpResponse getById2(String id) { + return null; + } + + static class Provider implements HttpApiProvider { + @Override + public Simple provide(HttpClientContext client) { + return new Simple$rc(client); + } + } + +} diff --git a/http-client/client/src/test/java/org/example/Simple.java b/http-client/client/src/test/java/org/example/Simple.java new file mode 100644 index 000000000..367bdddcb --- /dev/null +++ b/http-client/client/src/test/java/org/example/Simple.java @@ -0,0 +1,32 @@ +package org.example; + +import io.avaje.http.client.HttpException; +import io.dinject.controller.Get; +import io.dinject.controller.Path; +import io.dinject.controller.Post; + +import java.net.http.HttpResponse; +import java.util.List; + +@Path("/foo") +public interface Simple { + + @Get("users/{user}/repos") + List listRepos(String user, String other) throws HttpException; + + @Get("users/{id}") + Repo getById(String id) throws HttpException; + + @Get("users/{id}") + HttpResponse getById2(String id); + + @Post("users") + Repo post(Repo repo) throws HttpException; + +// @Get("users/{id}") +// void readUsing(String id, Consumer> consumer); +// +// @Get("dwn/{id}") +// void downloadMe(String id, Consumer file); + +} diff --git a/http-client/client/src/test/java/org/example/webserver/App.java b/http-client/client/src/test/java/org/example/webserver/App.java new file mode 100644 index 000000000..58ce7fb11 --- /dev/null +++ b/http-client/client/src/test/java/org/example/webserver/App.java @@ -0,0 +1,74 @@ +package org.example.webserver; + +import io.dinject.SystemContext; +import io.dinject.controller.InvalidPathArgumentException; +import io.dinject.controller.InvalidTypeArgumentException; +import io.dinject.controller.ValidationException; +import io.dinject.controller.WebRoutes; +import io.javalin.Javalin; +import io.javalin.http.staticfiles.Location; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +public class App { + + private static final Logger log = LoggerFactory.getLogger(App.class); + + public static void main(String[] args) { + start(8082); + } + + public static Javalin start(int port) { + + Javalin app = Javalin.create(config -> { + config.showJavalinBanner = false; + config.accessManager((handler, ctx, permittedRoles) -> { + log.debug("allow access ..."); + handler.handle(ctx); + }); + }); + + app.exception(ValidationException.class, (exception, ctx) -> { + + Map map = new LinkedHashMap<>(); + map.put("message", exception.getMessage()); + map.put("errors", exception.getErrors()); + ctx.status(exception.getStatus()); + ctx.json(map); + }); + + app.exception(InvalidTypeArgumentException.class, (exception, ctx) -> { + + Map map = new LinkedHashMap<>(); + map.put("path", ctx.path()); + map.put("message", "invalid type argument"); + ctx.status(400); + ctx.json(map); + }); + + app.exception(InvalidPathArgumentException.class, (exception, ctx) -> { + + Map map = new LinkedHashMap<>(); + map.put("path", ctx.path()); + map.put("message", "invalid path argument"); + ctx.status(404); + ctx.json(map); + }); + + + app.get("/", ctx -> { + ctx.result("Hello World"); + }); + + // All WebRoutes / Controllers ... from DI Context + List webRoutes = SystemContext.getBeans(WebRoutes.class); + app.routes(() -> webRoutes.forEach(WebRoutes::registerRoutes)); + + app.start(port); + return app; + } +} diff --git a/http-client/client/src/test/java/org/example/webserver/ErrorResponse.java b/http-client/client/src/test/java/org/example/webserver/ErrorResponse.java new file mode 100644 index 000000000..cf6a26845 --- /dev/null +++ b/http-client/client/src/test/java/org/example/webserver/ErrorResponse.java @@ -0,0 +1,27 @@ +package org.example.webserver; + +import java.util.LinkedHashMap; +import java.util.Map; + +public class ErrorResponse { + + private String message; + + private Map errors = new LinkedHashMap<>(); + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public Map getErrors() { + return errors; + } + + public void setErrors(Map errors) { + this.errors = errors; + } +} diff --git a/http-client/client/src/test/java/org/example/webserver/HelloController.java b/http-client/client/src/test/java/org/example/webserver/HelloController.java new file mode 100644 index 000000000..282ae2212 --- /dev/null +++ b/http-client/client/src/test/java/org/example/webserver/HelloController.java @@ -0,0 +1,136 @@ +package org.example.webserver; + +import io.dinject.controller.Controller; +import io.dinject.controller.Delete; +import io.dinject.controller.Form; +import io.dinject.controller.Get; +import io.dinject.controller.MediaType; +import io.dinject.controller.Path; +import io.dinject.controller.Post; +import io.dinject.controller.Produces; +import io.javalin.http.Context; +import io.swagger.v3.oas.annotations.Hidden; + +import javax.inject.Inject; +import javax.validation.Valid; +import java.time.LocalDate; +import java.util.ArrayList; +import java.util.List; + +import static java.util.Objects.requireNonNull; + +/** + * Hello resource manager. + *

+ * Simple API for Hello resources. + */ +//@Hidden +@Valid +@Controller +@Path("/hello") +class HelloController { + + private final MyService myService; + + @Inject + HelloController(MyService myService) { + this.myService = myService; + } + + @Produces(MediaType.TEXT_PLAIN) + @Get("message") + String getPlainMessage() { + return "hello world"; + } + + /** + * Return the Hello DTO. + * + * @param id The hello Id. + * @param date The name of the hello + * @param otherParam Optional other parameter + * @return The Hello DTO given the id and name. + * @deprecated Please migrate away + */ + @Get("/:id/:date") + HelloDto hello(int id, LocalDate date, String otherParam) { + return new HelloDto(id, date.toString(), otherParam); + } + + /** + * Find Hellos by name. + * + * @param name The name to search for + * @param otherParam My option parameter + * @return The Hellos that we found. + */ + @Get("/findbyname/:name") + List findByName(String name, String otherParam) { + return new ArrayList<>(); + } + + /** + * Simple example post with JSON body response. + */ + @Post + HelloDto post(HelloDto dto) { + dto.name = "posted"; + return dto; + } + + /** + * Save the hello using json body. + * + * @param foo The hello doo id + * @param dto The hello body as json + */ +// @Roles({ADMIN}) + @Post("/savebean/:foo") + void saveBean(String foo, HelloDto dto, Context context) { + // save hello data ... + System.out.println("save " + foo + " dto:" + dto); + requireNonNull(foo); + requireNonNull(dto); + requireNonNull(context); + } + + /** + * Create the new Hello using a form. + */ + @Post("saveform") + @Form + void saveForm(HelloForm helloForm) { + System.out.println("saving " + helloForm); + } + + + @Post("saveform2") + @Form + void saveForm2(String name, String email, String url) { + System.out.println("name " + name + " email:" + email + " url:" + url); + } + + @Post("saveform3") + @Form + HelloDto saveForm3(HelloForm helloForm) { + return new HelloDto(52, helloForm.name, helloForm.email); + } + + @Hidden + @Get + List getAll() { + return myService.findAll(); + } + + // @Hidden + @Delete(":id") + void deleteById(int id) { + System.out.println("deleting " + id); + } + + @Produces("text/plain") + @Get("/withMatrix/:year;author;country/:other") + String getWithMatrixParam(int year, String author, String country, String other, String extra) { + return "yr:" + year + " au:" + author + " co:" + country + " other:" + other + " extra:" + extra; + } +} diff --git a/http-client/client/src/test/java/org/example/webserver/HelloDto.java b/http-client/client/src/test/java/org/example/webserver/HelloDto.java new file mode 100644 index 000000000..29c64ddf1 --- /dev/null +++ b/http-client/client/src/test/java/org/example/webserver/HelloDto.java @@ -0,0 +1,48 @@ +package org.example.webserver; + +import java.time.Instant; +import java.util.UUID; + +public class HelloDto { + + public int id; + public String name; + public String otherParam; + private UUID gid; + + private Instant whenAction; + + public HelloDto(int id, String name, String otherParam) { + this.id = id; + this.name = name; + this.otherParam = otherParam; + } + + /** + * Jackson constructor. + */ + public HelloDto() { + } + + public UUID getGid() { + return gid; + } + + public void setGid(UUID gid) { + this.gid = gid; + } + + public Instant getWhenAction() { + return whenAction; + } + + public void setWhenAction(Instant whenAction) { + this.whenAction = whenAction; + } + + @Override + public String toString() { + return "id:" + id + " name:" + name + " other:" + otherParam; + } + +} diff --git a/http-client/client/src/test/java/org/example/webserver/HelloForm.java b/http-client/client/src/test/java/org/example/webserver/HelloForm.java new file mode 100644 index 000000000..6eaf10dd6 --- /dev/null +++ b/http-client/client/src/test/java/org/example/webserver/HelloForm.java @@ -0,0 +1,43 @@ +package org.example.webserver; + +//import org.hibernate.validator.constraints.URL; + +import org.hibernate.validator.constraints.URL; + +import javax.validation.Valid; +import javax.validation.constraints.Email; +import javax.validation.constraints.Future; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; +import java.time.LocalDate; + +@Valid +public class HelloForm { + + @NotNull @Size(min = 2, max = 150) + String name; + + @Email @Size(max = 100) + String email; + + @URL + String url; + + @Future + LocalDate startDate; + + public HelloForm(String name, String email) { + this.name = name; + this.email = email; + } + + @Override + public String toString() { + return "HelloForm{" + + "name='" + name + '\'' + + ", email='" + email + '\'' + + ", url='" + url + '\'' + + ", startDate=" + startDate + + '}'; + } +} diff --git a/http-client/client/src/test/java/org/example/webserver/MyService.java b/http-client/client/src/test/java/org/example/webserver/MyService.java new file mode 100644 index 000000000..2763682d5 --- /dev/null +++ b/http-client/client/src/test/java/org/example/webserver/MyService.java @@ -0,0 +1,16 @@ +package org.example.webserver; + +import javax.inject.Singleton; +import java.util.ArrayList; +import java.util.List; + +@Singleton +public class MyService { + + public List findAll() { + List list = new ArrayList<>(); + list.add(new HelloDto(12, "Jim", "asd")); + list.add(new HelloDto(13, "Spock", "456456")); + return list; + } +} diff --git a/http-client/client/src/test/resources/logback-test.xml b/http-client/client/src/test/resources/logback-test.xml new file mode 100644 index 000000000..9c0fc96ee --- /dev/null +++ b/http-client/client/src/test/resources/logback-test.xml @@ -0,0 +1,19 @@ + + + + TRACE + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + + + + + diff --git a/http-client/pom.xml b/http-client/pom.xml new file mode 100644 index 000000000..e54a22e16 --- /dev/null +++ b/http-client/pom.xml @@ -0,0 +1,17 @@ + + + 4.0.0 + + io.avaje + avaje-http-client-parent + 1 + pom + + + + + client + + + + From 6e5b446d7a9c0996c8cbb1f16fbfd4e818caf10e Mon Sep 17 00:00:00 2001 From: rob bygrave Date: Thu, 27 Aug 2020 17:37:02 +1200 Subject: [PATCH 0013/1323] Update parent pom --- http-client/client/pom.xml | 31 ++++++------------------------- 1 file changed, 6 insertions(+), 25 deletions(-) diff --git a/http-client/client/pom.xml b/http-client/client/pom.xml index 9900cd777..be7c2a16e 100644 --- a/http-client/client/pom.xml +++ b/http-client/client/pom.xml @@ -5,7 +5,7 @@ java11-oss org.avaje - 2.1.2 + 2.1.3 4.0.0 @@ -14,6 +14,11 @@ avaje-http-client 0.1-SNAPSHOT + + scm:git:git@github.com:avaje/avaje-http-client.git + HEAD + + @@ -106,28 +111,4 @@ - - - - org.apache.maven.plugins - maven-surefire-plugin - 2.22.2 - - - --illegal-access=permit - - - - - org.apache.maven.plugins - maven-failsafe-plugin - 2.22.2 - - - --illegal-access=permit - - - - - From b1270f458f9fc3b10c3e43d3f391e243c3519f3c Mon Sep 17 00:00:00 2001 From: rob bygrave Date: Thu, 27 Aug 2020 17:38:16 +1200 Subject: [PATCH 0014/1323] [maven-release-plugin] prepare release avaje-http-client-0.1 --- http-client/client/pom.xml | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/http-client/client/pom.xml b/http-client/client/pom.xml index be7c2a16e..9b86d1e33 100644 --- a/http-client/client/pom.xml +++ b/http-client/client/pom.xml @@ -1,7 +1,5 @@ - + java11-oss org.avaje @@ -12,11 +10,11 @@ io.avaje avaje-http-client - 0.1-SNAPSHOT + 0.1 scm:git:git@github.com:avaje/avaje-http-client.git - HEAD + avaje-http-client-0.1 From 53811d466b3190a3486dc9c28181d764c4778e34 Mon Sep 17 00:00:00 2001 From: rob bygrave Date: Thu, 27 Aug 2020 17:38:26 +1200 Subject: [PATCH 0015/1323] [maven-release-plugin] prepare for next development iteration --- http-client/client/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/http-client/client/pom.xml b/http-client/client/pom.xml index 9b86d1e33..2f9a27276 100644 --- a/http-client/client/pom.xml +++ b/http-client/client/pom.xml @@ -10,11 +10,11 @@ io.avaje avaje-http-client - 0.1 + 0.2-SNAPSHOT scm:git:git@github.com:avaje/avaje-http-client.git - avaje-http-client-0.1 + HEAD From 22c29a754468f3363b13815ab164becd7c7ee3ef Mon Sep 17 00:00:00 2001 From: rob bygrave Date: Thu, 27 Aug 2020 20:41:08 +1200 Subject: [PATCH 0016/1323] Add Gson BodyAdapter implementation --- http-client/client/pom.xml | 6 + .../avaje/http/client/JacksonBodyAdapter.java | 14 ++ .../io/avaje/http/client/BaseWebTest.java | 2 +- http-client/gson-adapter/pom.xml | 55 +++++++ .../http/client/gson/GsonBodyAdapter.java | 144 ++++++++++++++++++ .../java/io/avaje/http/client/gson/Foo.java | 9 ++ .../http/client/gson/GsonBodyAdapterTest.java | 57 +++++++ http-client/pom.xml | 1 + 8 files changed, 287 insertions(+), 1 deletion(-) create mode 100644 http-client/gson-adapter/pom.xml create mode 100644 http-client/gson-adapter/src/main/java/io/avaje/http/client/gson/GsonBodyAdapter.java create mode 100644 http-client/gson-adapter/src/test/java/io/avaje/http/client/gson/Foo.java create mode 100644 http-client/gson-adapter/src/test/java/io/avaje/http/client/gson/GsonBodyAdapterTest.java diff --git a/http-client/client/pom.xml b/http-client/client/pom.xml index 2f9a27276..625600c21 100644 --- a/http-client/client/pom.xml +++ b/http-client/client/pom.xml @@ -35,6 +35,12 @@ + + + + + + org.junit.jupiter junit-jupiter-api diff --git a/http-client/client/src/main/java/io/avaje/http/client/JacksonBodyAdapter.java b/http-client/client/src/main/java/io/avaje/http/client/JacksonBodyAdapter.java index df69caf9a..c6f50a69f 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/JacksonBodyAdapter.java +++ b/http-client/client/src/main/java/io/avaje/http/client/JacksonBodyAdapter.java @@ -10,6 +10,20 @@ import java.util.List; import java.util.concurrent.ConcurrentHashMap; +/** + * Jackson BodyAdapter to read and write beans as JSON. + * + *

{@code
+ *
+ *   HttpClientContext.newBuilder()
+ *       .withBaseUrl(baseUrl)
+ *       .withRequestListener(new RequestLogger())
+ *       .withBodyAdapter(new JacksonBodyAdapter(new ObjectMapper()))
+ *       //.withBodyAdapter(new GsonBodyAdapter(new Gson()))
+ *       .build();
+ *
+ * }
+ */ public class JacksonBodyAdapter implements BodyAdapter { private final ObjectMapper mapper; diff --git a/http-client/client/src/test/java/io/avaje/http/client/BaseWebTest.java b/http-client/client/src/test/java/io/avaje/http/client/BaseWebTest.java index c424712f8..dd9f68eb4 100644 --- a/http-client/client/src/test/java/io/avaje/http/client/BaseWebTest.java +++ b/http-client/client/src/test/java/io/avaje/http/client/BaseWebTest.java @@ -28,7 +28,7 @@ public static HttpClientContext client() { .withBaseUrl(baseUrl) .withRequestListener(new RequestLogger()) .withBodyAdapter(new JacksonBodyAdapter(new ObjectMapper())) - //.with(httpClient) +// .withBodyAdapter(new GsonBodyAdapter(new Gson())) .build(); } } diff --git a/http-client/gson-adapter/pom.xml b/http-client/gson-adapter/pom.xml new file mode 100644 index 000000000..afe8b11f1 --- /dev/null +++ b/http-client/gson-adapter/pom.xml @@ -0,0 +1,55 @@ + + + + java11-oss + org.avaje + 2.1.3 + + + 4.0.0 + + io.avaje + avaje-http-client-gson + 0.2-SNAPSHOT + + + scm:git:git@github.com:avaje/avaje-http-client.git + HEAD + + + + + + io.avaje + avaje-http-client + 0.1 + + + + com.google.code.gson + gson + 2.8.6 + + + + + + org.junit.jupiter + junit-jupiter-api + 5.6.2 + test + + + + org.junit.jupiter + junit-jupiter-engine + 5.6.2 + test + + + + + + diff --git a/http-client/gson-adapter/src/main/java/io/avaje/http/client/gson/GsonBodyAdapter.java b/http-client/gson-adapter/src/main/java/io/avaje/http/client/gson/GsonBodyAdapter.java new file mode 100644 index 000000000..c5798fca6 --- /dev/null +++ b/http-client/gson-adapter/src/main/java/io/avaje/http/client/gson/GsonBodyAdapter.java @@ -0,0 +1,144 @@ +package io.avaje.http.client.gson; + +import com.google.gson.Gson; +import com.google.gson.TypeAdapter; +import com.google.gson.reflect.TypeToken; +import com.google.gson.stream.JsonReader; +import com.google.gson.stream.JsonWriter; +import io.avaje.http.client.BodyAdapter; +import io.avaje.http.client.BodyContent; +import io.avaje.http.client.BodyReader; +import io.avaje.http.client.BodyWriter; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.util.List; +import java.util.concurrent.ConcurrentHashMap; + +import static java.nio.charset.StandardCharsets.UTF_8; + +/** + * Gson BodyAdapter. + * + *
{@code
+ *
+ *   HttpClientContext.newBuilder()
+ *       .withBaseUrl(baseUrl)
+ *       .withRequestListener(new RequestLogger())
+ *       //.withBodyAdapter(new JacksonBodyAdapter(new ObjectMapper()))
+ *       .withBodyAdapter(new GsonBodyAdapter(new Gson()))
+ *       .build();
+ *
+ * }
+ */ +public class GsonBodyAdapter implements BodyAdapter { + + private final Gson gson; + + private final ConcurrentHashMap, BodyWriter> beanWriterCache = new ConcurrentHashMap<>(); + + private final ConcurrentHashMap, BodyReader> beanReaderCache = new ConcurrentHashMap<>(); + + private final ConcurrentHashMap, BodyReader> listReaderCache = new ConcurrentHashMap<>(); + + /** + * Create passing the Gson instance to use. + */ + public GsonBodyAdapter(Gson gson) { + this.gson = gson; + } + + @Override + public BodyWriter beanWriter(Class cls) { + return beanWriterCache.computeIfAbsent(cls, aClass -> { + try { + final TypeAdapter adapter = gson.getAdapter(cls); + return new Writer(gson, adapter); + } catch (Exception e) { + throw new RuntimeException(e); + } + }); + } + + @SuppressWarnings("unchecked") + @Override + public BodyReader beanReader(Class cls) { + return (BodyReader) beanReaderCache.computeIfAbsent(cls, aClass -> { + try { + final TypeAdapter adapter = gson.getAdapter(cls); + return new Reader<>(gson, adapter); + } catch (Exception e) { + throw new RuntimeException(e); + } + }); + } + + @SuppressWarnings("unchecked") + @Override + public BodyReader> listReader(Class cls) { + return (BodyReader>) listReaderCache.computeIfAbsent(cls, aClass -> { + try { + final TypeToken listType = TypeToken.getParameterized(List.class, cls); + final TypeAdapter adapter = gson.getAdapter(listType); + return new Reader(gson, adapter); + } catch (Exception e) { + throw new RuntimeException(e); + } + }); + } + + private static class Reader implements BodyReader { + + private final Gson gson; + private final TypeAdapter adapter; + + Reader(Gson gson, TypeAdapter adapter) { + this.gson = gson; + this.adapter = adapter; + } + + @Override + public T read(BodyContent body) { + try { + InputStreamReader reader = new InputStreamReader(new ByteArrayInputStream(body.content())); + final JsonReader jsonReader = gson.newJsonReader(reader); + return adapter.read(jsonReader); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + } + + @SuppressWarnings({"rawtypes"}) + private static class Writer implements BodyWriter { + + private final Gson gson; + private final TypeAdapter adapter; + + Writer(Gson gson, TypeAdapter adapter) { + this.gson = gson; + this.adapter = adapter; + } + + @Override + public BodyContent write(Object bean, String contentType) { + return write(bean); + } + + @Override + public BodyContent write(Object bean) { + try { + ByteArrayOutputStream os = new ByteArrayOutputStream(200); + JsonWriter jsonWriter = gson.newJsonWriter(new OutputStreamWriter(os, UTF_8)); + adapter.write(jsonWriter, bean); + jsonWriter.close(); + return BodyContent.asJson(os.toByteArray()); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + } +} diff --git a/http-client/gson-adapter/src/test/java/io/avaje/http/client/gson/Foo.java b/http-client/gson-adapter/src/test/java/io/avaje/http/client/gson/Foo.java new file mode 100644 index 000000000..dbd90e105 --- /dev/null +++ b/http-client/gson-adapter/src/test/java/io/avaje/http/client/gson/Foo.java @@ -0,0 +1,9 @@ +package io.avaje.http.client.gson; + +public class Foo { + + public long id; + + public String name; + +} diff --git a/http-client/gson-adapter/src/test/java/io/avaje/http/client/gson/GsonBodyAdapterTest.java b/http-client/gson-adapter/src/test/java/io/avaje/http/client/gson/GsonBodyAdapterTest.java new file mode 100644 index 000000000..e8ff31587 --- /dev/null +++ b/http-client/gson-adapter/src/test/java/io/avaje/http/client/gson/GsonBodyAdapterTest.java @@ -0,0 +1,57 @@ +package io.avaje.http.client.gson; + +import com.google.gson.Gson; +import io.avaje.http.client.BodyContent; +import io.avaje.http.client.BodyReader; +import io.avaje.http.client.BodyWriter; +import org.junit.jupiter.api.Test; + +import java.nio.charset.StandardCharsets; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +class GsonBodyAdapterTest { + + private final GsonBodyAdapter adapter = new GsonBodyAdapter(new Gson()); + + @Test + void beanWriter() { + + final Foo foo = new Foo(); + foo.id = 42; + foo.name = "bar"; + + final BodyWriter writer = adapter.beanWriter(Foo.class); + final BodyContent content = writer.write(foo); + + final String json = new String(content.content(), StandardCharsets.UTF_8); + assertEquals("{\"id\":42,\"name\":\"bar\"}", json); + } + + @Test + void beanReader() { + + final BodyReader reader = adapter.beanReader(Foo.class); + + final Foo read = reader.read(content("{\"id\":42, \"name\":\"bar\"}")); + assertEquals(42, read.id); + assertEquals("bar", read.name); + } + + @Test + void listReader() { + + final BodyReader> reader = adapter.listReader(Foo.class); + + final List read = reader.read(content("[{\"id\":42, \"name\":\"bar\"},{\"id\":43, \"name\":\"baz\"}]")); + + assertEquals(2, read.size()); + assertEquals(42, read.get(0).id); + assertEquals(43, read.get(1).id); + } + + BodyContent content(String raw) { + return new BodyContent("not-used", raw.getBytes()); + } +} diff --git a/http-client/pom.xml b/http-client/pom.xml index e54a22e16..2562a9e88 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -11,6 +11,7 @@ client + gson-adapter
From 2f98b6899ca3e6127509ccb2490e5b565c700524 Mon Sep 17 00:00:00 2001 From: rob bygrave Date: Thu, 27 Aug 2020 20:42:12 +1200 Subject: [PATCH 0017/1323] Set version to 0.1-SNAPSHOT --- http-client/gson-adapter/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/http-client/gson-adapter/pom.xml b/http-client/gson-adapter/pom.xml index afe8b11f1..833a67d55 100644 --- a/http-client/gson-adapter/pom.xml +++ b/http-client/gson-adapter/pom.xml @@ -12,7 +12,7 @@ io.avaje avaje-http-client-gson - 0.2-SNAPSHOT + 0.1-SNAPSHOT scm:git:git@github.com:avaje/avaje-http-client.git From df37c5c69c621c3e80434c93a5e8d5736efc83c9 Mon Sep 17 00:00:00 2001 From: rob bygrave Date: Thu, 27 Aug 2020 20:43:08 +1200 Subject: [PATCH 0018/1323] [maven-release-plugin] prepare release avaje-http-client-gson-0.1 --- http-client/gson-adapter/pom.xml | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/http-client/gson-adapter/pom.xml b/http-client/gson-adapter/pom.xml index 833a67d55..c9f948521 100644 --- a/http-client/gson-adapter/pom.xml +++ b/http-client/gson-adapter/pom.xml @@ -1,7 +1,5 @@ - + java11-oss org.avaje @@ -12,11 +10,11 @@ io.avaje avaje-http-client-gson - 0.1-SNAPSHOT + 0.1 scm:git:git@github.com:avaje/avaje-http-client.git - HEAD + avaje-http-client-gson-0.1 From ad0a03bdd3f369eaa469b0e525e0f5673d6bedbd Mon Sep 17 00:00:00 2001 From: rob bygrave Date: Thu, 27 Aug 2020 20:43:19 +1200 Subject: [PATCH 0019/1323] [maven-release-plugin] prepare for next development iteration --- http-client/gson-adapter/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/http-client/gson-adapter/pom.xml b/http-client/gson-adapter/pom.xml index c9f948521..79fc8880a 100644 --- a/http-client/gson-adapter/pom.xml +++ b/http-client/gson-adapter/pom.xml @@ -10,11 +10,11 @@ io.avaje avaje-http-client-gson - 0.1 + 0.2-SNAPSHOT scm:git:git@github.com:avaje/avaje-http-client.git - avaje-http-client-gson-0.1 + HEAD From ad89f479a3c2d11714d5b4fd35fa663c286c5ab7 Mon Sep 17 00:00:00 2001 From: rob bygrave Date: Fri, 28 Aug 2020 18:10:58 +1200 Subject: [PATCH 0020/1323] Tidy test dependencies --- http-client/client/pom.xml | 29 ++++------------------------- http-client/gson-adapter/pom.xml | 14 +++----------- 2 files changed, 7 insertions(+), 36 deletions(-) diff --git a/http-client/client/pom.xml b/http-client/client/pom.xml index 625600c21..edf0f707d 100644 --- a/http-client/client/pom.xml +++ b/http-client/client/pom.xml @@ -3,7 +3,7 @@ java11-oss org.avaje - 2.1.3 + 2.2 4.0.0 @@ -32,33 +32,12 @@ true - - - - - - - - - org.junit.jupiter - junit-jupiter-api - 5.6.2 - test - - - org.junit.jupiter - junit-jupiter-engine - 5.6.2 - test - - - - org.assertj - assertj-core - 3.16.1 + org.avaje.composite + junit + 5.0 test diff --git a/http-client/gson-adapter/pom.xml b/http-client/gson-adapter/pom.xml index 79fc8880a..ba0d2eea8 100644 --- a/http-client/gson-adapter/pom.xml +++ b/http-client/gson-adapter/pom.xml @@ -34,20 +34,12 @@ - org.junit.jupiter - junit-jupiter-api - 5.6.2 - test - - - - org.junit.jupiter - junit-jupiter-engine - 5.6.2 + org.avaje.composite + junit + 5.0 test - From c89eb295b3069bd3982feab4c4b80917ad934e42 Mon Sep 17 00:00:00 2001 From: rob bygrave Date: Fri, 28 Aug 2020 18:29:37 +1200 Subject: [PATCH 0021/1323] #1 - Refactor rename withRequestListener() to withResponseListener() --- .../avaje/http/client/DHttpClientContext.java | 14 ++-- .../client/DHttpClientContextBuilder.java | 8 +-- .../avaje/http/client/DHttpClientRequest.java | 11 ++- .../avaje/http/client/HttpClientContext.java | 7 +- .../io/avaje/http/client/RequestListener.java | 22 ------ .../io/avaje/http/client/RequestLogger.java | 4 +- .../avaje/http/client/ResponseListener.java | 70 +++++++++++++++++++ .../io/avaje/http/client/BaseWebTest.java | 2 +- 8 files changed, 98 insertions(+), 40 deletions(-) delete mode 100644 http-client/client/src/main/java/io/avaje/http/client/RequestListener.java create mode 100644 http-client/client/src/main/java/io/avaje/http/client/ResponseListener.java diff --git a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContext.java b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContext.java index fe51524af..cfc10bf29 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContext.java +++ b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContext.java @@ -15,14 +15,14 @@ class DHttpClientContext implements HttpClientContext { private final String baseUrl; private final Duration requestTimeout; private final BodyAdapter bodyAdapter; - private final RequestListener requestListener; + private final ResponseListener responseListener; - DHttpClientContext(HttpClient httpClient, String baseUrl, Duration requestTimeout, BodyAdapter bodyAdapter, RequestListener requestListener) { + DHttpClientContext(HttpClient httpClient, String baseUrl, Duration requestTimeout, BodyAdapter bodyAdapter, ResponseListener responseListener) { this.httpClient = httpClient; this.baseUrl = baseUrl; this.requestTimeout = requestTimeout; this.bodyAdapter = bodyAdapter; - this.requestListener = requestListener; + this.responseListener = responseListener; } @Override @@ -128,14 +128,14 @@ List readList(Class cls, BodyContent content) { void afterResponse(DHttpClientRequest request) { - if (requestListener != null) { - requestListener.response(request.listenerEvent()); + if (responseListener != null) { + responseListener.response(request.listenerEvent()); } } void afterResponseHandler(DHttpClientRequest request) { - if (requestListener != null) { - requestListener.response(request.listenerEvent()); + if (responseListener != null) { + responseListener.response(request.listenerEvent()); } } } diff --git a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContextBuilder.java b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContextBuilder.java index 35ab87e62..cd198e8ac 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContextBuilder.java +++ b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContextBuilder.java @@ -15,7 +15,7 @@ class DHttpClientContextBuilder implements HttpClientContext.Builder { private BodyAdapter bodyAdapter; - private RequestListener requestListener; + private ResponseListener responseListener; DHttpClientContextBuilder() { } @@ -45,8 +45,8 @@ public HttpClientContext.Builder withBodyAdapter(BodyAdapter adapter) { } @Override - public HttpClientContext.Builder withRequestListener(RequestListener requestListener) { - this.requestListener = requestListener; + public HttpClientContext.Builder withResponseListener(ResponseListener responseListener) { + this.responseListener = responseListener; return this; } @@ -57,7 +57,7 @@ public HttpClientContext build() { if (client == null) { client = defaultClient(); } - return new DHttpClientContext(client, baseUrl, requestTimeout, bodyAdapter, requestListener); + return new DHttpClientContext(client, baseUrl, requestTimeout, bodyAdapter, responseListener); } private HttpClient defaultClient() { diff --git a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java index 3b65c4f42..2c0013109 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java +++ b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java @@ -346,14 +346,14 @@ protected HttpRequest.Builder newRequest(String method, String url, HttpRequest. .method(method, body); } - RequestListener.Event listenerEvent() { + ResponseListener.Event listenerEvent() { return new ListenerEvent(); } - private class ListenerEvent implements RequestListener.Event { + private class ListenerEvent implements ResponseListener.Event { @Override - public long requestTimeNanos() { + public long responseTimeNanos() { return requestTimeNanos; } @@ -367,6 +367,11 @@ public HttpResponse response() { return httpResponse; } + @Override + public HttpRequest request() { + return httpResponse.request(); + } + @Override public String requestBody() { if (encodedRequestBody != null) { diff --git a/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java b/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java index bd60abd35..d504da83d 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java +++ b/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java @@ -95,7 +95,12 @@ interface Builder { */ Builder withBodyAdapter(BodyAdapter adapter); - Builder withRequestListener(RequestListener requestListener); + /** + * Add a response listener. Note that {@link RequestLogger} is an + * implementation for debug logging request/response headers and + * content. + */ + Builder withResponseListener(ResponseListener requestListener); /** * Build and return the context. diff --git a/http-client/client/src/main/java/io/avaje/http/client/RequestListener.java b/http-client/client/src/main/java/io/avaje/http/client/RequestListener.java deleted file mode 100644 index c8ccd3afc..000000000 --- a/http-client/client/src/main/java/io/avaje/http/client/RequestListener.java +++ /dev/null @@ -1,22 +0,0 @@ -package io.avaje.http.client; - -import java.net.URI; -import java.net.http.HttpResponse; - -public interface RequestListener { - - void response(Event event); - - interface Event { - - long requestTimeNanos(); - - HttpResponse response(); - - String requestBody(); - - String responseBody(); - - URI uri(); - } -} diff --git a/http-client/client/src/main/java/io/avaje/http/client/RequestLogger.java b/http-client/client/src/main/java/io/avaje/http/client/RequestLogger.java index 7d6e2366f..8d385060b 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/RequestLogger.java +++ b/http-client/client/src/main/java/io/avaje/http/client/RequestLogger.java @@ -10,7 +10,7 @@ import java.util.Map; import java.util.Set; -public class RequestLogger implements RequestListener { +public class RequestLogger implements ResponseListener { private static final Logger log = LoggerFactory.getLogger(RequestLogger.class); @@ -29,7 +29,7 @@ public void response(Event event) { if (log.isDebugEnabled()) { final HttpResponse response = event.response(); final HttpRequest request = response.request(); - long micros = event.requestTimeNanos() / 1000; + long micros = event.responseTimeNanos() / 1000; StringBuilder sb = new StringBuilder(); sb.append("statusCode:").append(response.statusCode()) diff --git a/http-client/client/src/main/java/io/avaje/http/client/ResponseListener.java b/http-client/client/src/main/java/io/avaje/http/client/ResponseListener.java new file mode 100644 index 000000000..b52327e0e --- /dev/null +++ b/http-client/client/src/main/java/io/avaje/http/client/ResponseListener.java @@ -0,0 +1,70 @@ +package io.avaje.http.client; + +import java.net.URI; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; + +/** + * Listen to responses. + *

+ * {@link RequestLogger} is an implementation for debug logging the + * requests and responses. + */ +public interface ResponseListener { + + /** + * Handle the response. + */ + void response(Event event); + + /** + * The response event details. + */ + interface Event { + + /** + * Return the time from request to response in nanos. + */ + long responseTimeNanos(); + + /** + * Return the URI for the request. + */ + URI uri(); + + /** + * Return the response. + */ + HttpResponse response(); + + /** + * Return the related request. + */ + HttpRequest request(); + + /** + * Return the response body as string content if applicable. + *

+ * This is primarily here to assist logging of responses for debug and + * trace purposes. + *

+ * This will return null if the response is not String or byte array + * encoded string content. For example, when requests use response + * handlers for InputStream, Path, Stream etc this will return null. + *

+ */ + String responseBody(); + + /** + * Return the related request body as string content if available. + *

+ * This is primarily here to assist logging of requests for debug and + * trace purposes. + *

+ * This will return null if the related request content was not + * String or byte array encoded string content. + */ + String requestBody(); + + } +} diff --git a/http-client/client/src/test/java/io/avaje/http/client/BaseWebTest.java b/http-client/client/src/test/java/io/avaje/http/client/BaseWebTest.java index dd9f68eb4..353065ce5 100644 --- a/http-client/client/src/test/java/io/avaje/http/client/BaseWebTest.java +++ b/http-client/client/src/test/java/io/avaje/http/client/BaseWebTest.java @@ -26,7 +26,7 @@ public static void shutdown() { public static HttpClientContext client() { return HttpClientContext.newBuilder() .withBaseUrl(baseUrl) - .withRequestListener(new RequestLogger()) + .withResponseListener(new RequestLogger()) .withBodyAdapter(new JacksonBodyAdapter(new ObjectMapper())) // .withBodyAdapter(new GsonBodyAdapter(new Gson())) .build(); From 1ba48cc4d35cc37584cc800f7a74bd1d1a6b7a24 Mon Sep 17 00:00:00 2001 From: rob bygrave Date: Fri, 28 Aug 2020 18:30:44 +1200 Subject: [PATCH 0022/1323] Bump to 0.5-SNAPSHOT --- http-client/client/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/http-client/client/pom.xml b/http-client/client/pom.xml index edf0f707d..127809ced 100644 --- a/http-client/client/pom.xml +++ b/http-client/client/pom.xml @@ -10,7 +10,7 @@ io.avaje avaje-http-client - 0.2-SNAPSHOT + 0.5-SNAPSHOT scm:git:git@github.com:avaje/avaje-http-client.git From 138ff80867efe40274d849e77444835e4adba776 Mon Sep 17 00:00:00 2001 From: rob bygrave Date: Fri, 28 Aug 2020 18:31:31 +1200 Subject: [PATCH 0023/1323] Bump to 0.5-SNAPSHOT --- http-client/gson-adapter/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/http-client/gson-adapter/pom.xml b/http-client/gson-adapter/pom.xml index ba0d2eea8..6fa0875f4 100644 --- a/http-client/gson-adapter/pom.xml +++ b/http-client/gson-adapter/pom.xml @@ -3,14 +3,14 @@ java11-oss org.avaje - 2.1.3 + 2.2 4.0.0 io.avaje avaje-http-client-gson - 0.2-SNAPSHOT + 0.5-SNAPSHOT scm:git:git@github.com:avaje/avaje-http-client.git From 3af91f6a5a9c53477344496e931a884f9610dc33 Mon Sep 17 00:00:00 2001 From: rob bygrave Date: Fri, 28 Aug 2020 18:32:02 +1200 Subject: [PATCH 0024/1323] [maven-release-plugin] prepare release avaje-http-client-0.5 --- http-client/client/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/http-client/client/pom.xml b/http-client/client/pom.xml index 127809ced..3e748fa6f 100644 --- a/http-client/client/pom.xml +++ b/http-client/client/pom.xml @@ -10,11 +10,11 @@ io.avaje avaje-http-client - 0.5-SNAPSHOT + 0.5 scm:git:git@github.com:avaje/avaje-http-client.git - HEAD + avaje-http-client-0.5 From b60e8e6ffaf532c559fcd683ae68dfabe991f5df Mon Sep 17 00:00:00 2001 From: rob bygrave Date: Fri, 28 Aug 2020 18:32:12 +1200 Subject: [PATCH 0025/1323] [maven-release-plugin] prepare for next development iteration --- http-client/client/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/http-client/client/pom.xml b/http-client/client/pom.xml index 3e748fa6f..8e80e6a4d 100644 --- a/http-client/client/pom.xml +++ b/http-client/client/pom.xml @@ -10,11 +10,11 @@ io.avaje avaje-http-client - 0.5 + 0.6-SNAPSHOT scm:git:git@github.com:avaje/avaje-http-client.git - avaje-http-client-0.5 + HEAD From 84f54f2864be5c7c2af83650b429686cb295db8e Mon Sep 17 00:00:00 2001 From: rob bygrave Date: Fri, 28 Aug 2020 20:40:12 +1200 Subject: [PATCH 0026/1323] Bump to 0.5-SNAPSHOT --- http-client/gson-adapter/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/http-client/gson-adapter/pom.xml b/http-client/gson-adapter/pom.xml index 6fa0875f4..65a8ad149 100644 --- a/http-client/gson-adapter/pom.xml +++ b/http-client/gson-adapter/pom.xml @@ -22,7 +22,7 @@ io.avaje avaje-http-client - 0.1 + 0.5 From d8c0810245482b8c5c7cde908745e2ed0d1adf45 Mon Sep 17 00:00:00 2001 From: rob bygrave Date: Fri, 28 Aug 2020 20:40:39 +1200 Subject: [PATCH 0027/1323] [maven-release-plugin] prepare release avaje-http-client-gson-0.5 --- http-client/gson-adapter/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/http-client/gson-adapter/pom.xml b/http-client/gson-adapter/pom.xml index 65a8ad149..83e1a985a 100644 --- a/http-client/gson-adapter/pom.xml +++ b/http-client/gson-adapter/pom.xml @@ -10,11 +10,11 @@ io.avaje avaje-http-client-gson - 0.5-SNAPSHOT + 0.5 scm:git:git@github.com:avaje/avaje-http-client.git - HEAD + avaje-http-client-gson-0.5 From b8dd130d64874d40d982fa0e2b0182cac8cdea6a Mon Sep 17 00:00:00 2001 From: rob bygrave Date: Fri, 28 Aug 2020 20:40:49 +1200 Subject: [PATCH 0028/1323] [maven-release-plugin] prepare for next development iteration --- http-client/gson-adapter/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/http-client/gson-adapter/pom.xml b/http-client/gson-adapter/pom.xml index 83e1a985a..4178c3ce9 100644 --- a/http-client/gson-adapter/pom.xml +++ b/http-client/gson-adapter/pom.xml @@ -10,11 +10,11 @@ io.avaje avaje-http-client-gson - 0.5 + 0.6-SNAPSHOT scm:git:git@github.com:avaje/avaje-http-client.git - avaje-http-client-gson-0.5 + HEAD From 0036813a99102215ce729f2ffc7a8ec31e608103 Mon Sep 17 00:00:00 2001 From: rob bygrave Date: Fri, 25 Sep 2020 16:24:52 +1200 Subject: [PATCH 0029/1323] Default to using CookieManager --- .../client/DHttpClientContextBuilder.java | 20 +++++++++++++++--- .../avaje/http/client/HttpClientContext.java | 6 ++++++ .../http/client/DHttpClientContextTest.java | 21 +++++++++++++++++++ 3 files changed, 44 insertions(+), 3 deletions(-) diff --git a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContextBuilder.java b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContextBuilder.java index cd198e8ac..54b476200 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContextBuilder.java +++ b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContextBuilder.java @@ -1,5 +1,7 @@ package io.avaje.http.client; +import java.net.CookieHandler; +import java.net.CookieManager; import java.net.http.HttpClient; import java.time.Duration; @@ -17,6 +19,8 @@ class DHttpClientContextBuilder implements HttpClientContext.Builder { private ResponseListener responseListener; + private CookieHandler cookieHandler = new CookieManager(); + DHttpClientContextBuilder() { } @@ -50,6 +54,12 @@ public HttpClientContext.Builder withResponseListener(ResponseListener responseL return this; } + @Override + public HttpClientContext.Builder withCookieHandler(CookieHandler cookieHandler) { + this.cookieHandler = cookieHandler; + return this; + } + @Override public HttpClientContext build() { requireNonNull(baseUrl, "baseUrl is not specified"); @@ -61,9 +71,13 @@ public HttpClientContext build() { } private HttpClient defaultClient() { - return HttpClient.newBuilder() - .connectTimeout(Duration.ofSeconds(20)) - .build(); + final HttpClient.Builder builder = + HttpClient.newBuilder() + .connectTimeout(Duration.ofSeconds(20)); + if (cookieHandler != null) { + builder.cookieHandler(cookieHandler); + } + return builder.build(); } } diff --git a/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java b/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java index d504da83d..6650ab310 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java +++ b/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java @@ -1,5 +1,6 @@ package io.avaje.http.client; +import java.net.CookieHandler; import java.net.http.HttpClient; import java.net.http.HttpResponse; import java.time.Duration; @@ -102,6 +103,11 @@ interface Builder { */ Builder withResponseListener(ResponseListener requestListener); + /** + * Specify a cookie handler to use on the HttpClient. This would override the default cookie handler. + */ + Builder withCookieHandler(CookieHandler cookieHandler); + /** * Build and return the context. */ diff --git a/http-client/client/src/test/java/io/avaje/http/client/DHttpClientContextTest.java b/http-client/client/src/test/java/io/avaje/http/client/DHttpClientContextTest.java index 8d0ee1372..661c24f7b 100644 --- a/http-client/client/src/test/java/io/avaje/http/client/DHttpClientContextTest.java +++ b/http-client/client/src/test/java/io/avaje/http/client/DHttpClientContextTest.java @@ -41,6 +41,27 @@ void build_basic() { // has default client created assertThat(context.httpClient()).isNotNull(); assertThat(context.httpClient().version()).isEqualTo(HttpClient.Version.HTTP_2); + assertThat(context.httpClient().cookieHandler()).isPresent(); + + // has expected url building + assertThat(context.url().build()).isEqualTo("http://localhost"); + assertThat(context.url().path("hello").build()).isEqualTo("http://localhost/hello"); + assertThat(context.url().param("hello","there").build()).isEqualTo("http://localhost?hello=there"); + } + + @Test + void build_noCookieHandler() { + + final HttpClientContext context = + HttpClientContext.newBuilder() + .withBaseUrl("http://localhost") + .withCookieHandler(null) + .build(); + + // has default client created + assertThat(context.httpClient()).isNotNull(); + assertThat(context.httpClient().version()).isEqualTo(HttpClient.Version.HTTP_2); + assertThat(context.httpClient().cookieHandler()).isEmpty(); // has expected url building assertThat(context.url().build()).isEqualTo("http://localhost"); From 58d94e14524c44bb2046b04cda5ee728e0067d50 Mon Sep 17 00:00:00 2001 From: rob bygrave Date: Fri, 25 Sep 2020 16:26:08 +1200 Subject: [PATCH 0030/1323] [maven-release-plugin] prepare release avaje-http-client-0.6 --- http-client/client/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/http-client/client/pom.xml b/http-client/client/pom.xml index 8e80e6a4d..2905e5506 100644 --- a/http-client/client/pom.xml +++ b/http-client/client/pom.xml @@ -10,11 +10,11 @@ io.avaje avaje-http-client - 0.6-SNAPSHOT + 0.6 scm:git:git@github.com:avaje/avaje-http-client.git - HEAD + avaje-http-client-0.6 From 3c63d8807ec0364cc3a6816b11d45e30746200db Mon Sep 17 00:00:00 2001 From: rob bygrave Date: Fri, 25 Sep 2020 16:26:19 +1200 Subject: [PATCH 0031/1323] [maven-release-plugin] prepare for next development iteration --- http-client/client/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/http-client/client/pom.xml b/http-client/client/pom.xml index 2905e5506..abe2cbb2e 100644 --- a/http-client/client/pom.xml +++ b/http-client/client/pom.xml @@ -10,11 +10,11 @@ io.avaje avaje-http-client - 0.6 + 0.7-SNAPSHOT scm:git:git@github.com:avaje/avaje-http-client.git - avaje-http-client-0.6 + HEAD From 10f7637f63ef7405afd06db66324e8453de0c870 Mon Sep 17 00:00:00 2001 From: rob bygrave Date: Fri, 25 Sep 2020 17:06:49 +1200 Subject: [PATCH 0032/1323] Rename param() to queryParam() --- .../java/io/avaje/http/client/DHttpClientRequest.java | 4 ++-- .../main/java/io/avaje/http/client/HttpClientRequest.java | 2 +- .../src/main/java/io/avaje/http/client/UrlBuilder.java | 2 +- .../java/io/avaje/http/client/DHttpClientContextTest.java | 4 ++-- .../java/io/avaje/http/client/HelloControllerTest.java | 4 ++-- .../test/java/io/avaje/http/client/UrlBuilderTest.java | 8 ++++---- .../client/src/test/java/org/example/Simple$rc.java | 2 +- 7 files changed, 13 insertions(+), 13 deletions(-) diff --git a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java index 2c0013109..2a180a126 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java +++ b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java @@ -93,8 +93,8 @@ public HttpClientRequest matrixParam(String name, String value) { @Override - public HttpClientRequest param(String name, String value) { - url.param(name, value); + public HttpClientRequest queryParam(String name, String value) { + url.queryParam(name, value); return this; } diff --git a/http-client/client/src/main/java/io/avaje/http/client/HttpClientRequest.java b/http-client/client/src/main/java/io/avaje/http/client/HttpClientRequest.java index 0fc87ed3b..e860425b2 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/HttpClientRequest.java +++ b/http-client/client/src/main/java/io/avaje/http/client/HttpClientRequest.java @@ -66,7 +66,7 @@ public interface HttpClientRequest { * @param value The value of the query parameter * @return The request being built */ - HttpClientRequest param(String name, String value); + HttpClientRequest queryParam(String name, String value); /** * Add a form parameter. diff --git a/http-client/client/src/main/java/io/avaje/http/client/UrlBuilder.java b/http-client/client/src/main/java/io/avaje/http/client/UrlBuilder.java index e8449dc48..c726982ad 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/UrlBuilder.java +++ b/http-client/client/src/main/java/io/avaje/http/client/UrlBuilder.java @@ -18,7 +18,7 @@ public UrlBuilder path(String path) { return this; } - public UrlBuilder param(String name, String value) { + public UrlBuilder queryParam(String name, String value) { if (value != null) { buffer.append(hasParams ? '&' : '?'); hasParams = true; diff --git a/http-client/client/src/test/java/io/avaje/http/client/DHttpClientContextTest.java b/http-client/client/src/test/java/io/avaje/http/client/DHttpClientContextTest.java index 661c24f7b..52044b188 100644 --- a/http-client/client/src/test/java/io/avaje/http/client/DHttpClientContextTest.java +++ b/http-client/client/src/test/java/io/avaje/http/client/DHttpClientContextTest.java @@ -46,7 +46,7 @@ void build_basic() { // has expected url building assertThat(context.url().build()).isEqualTo("http://localhost"); assertThat(context.url().path("hello").build()).isEqualTo("http://localhost/hello"); - assertThat(context.url().param("hello","there").build()).isEqualTo("http://localhost?hello=there"); + assertThat(context.url().queryParam("hello","there").build()).isEqualTo("http://localhost?hello=there"); } @Test @@ -66,7 +66,7 @@ void build_noCookieHandler() { // has expected url building assertThat(context.url().build()).isEqualTo("http://localhost"); assertThat(context.url().path("hello").build()).isEqualTo("http://localhost/hello"); - assertThat(context.url().param("hello","there").build()).isEqualTo("http://localhost?hello=there"); + assertThat(context.url().queryParam("hello","there").build()).isEqualTo("http://localhost?hello=there"); } @Test diff --git a/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java b/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java index b88ec0f05..256cd0387 100644 --- a/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java +++ b/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java @@ -42,7 +42,7 @@ void get_hello_returningListOfBeans() { void get_withPathParamAndQueryParam_returningBean() { final HelloDto dto = clientContext.request() - .path("hello/43/2020-03-05").param("otherParam", "other").param("foo", null) + .path("hello/43/2020-03-05").queryParam("otherParam", "other").queryParam("foo", null) .get().bean(HelloDto.class); assertThat(dto.id).isEqualTo(43L); @@ -202,7 +202,7 @@ void get_withMatrixParam() { .matrixParam("author", "rob") .matrixParam("country", "nz") .path("foo") - .param("extra", "banana") + .queryParam("extra", "banana") .get().asString(); assertEquals(200, httpRes.statusCode()); diff --git a/http-client/client/src/test/java/io/avaje/http/client/UrlBuilderTest.java b/http-client/client/src/test/java/io/avaje/http/client/UrlBuilderTest.java index e721d4fc1..684a7e0bb 100644 --- a/http-client/client/src/test/java/io/avaje/http/client/UrlBuilderTest.java +++ b/http-client/client/src/test/java/io/avaje/http/client/UrlBuilderTest.java @@ -39,14 +39,14 @@ void matrixParam_path() { @Test void param() { - assertThat(new UrlBuilder("https://foo").param("bar", null).build()).isEqualTo("https://foo"); - assertThat(new UrlBuilder("https://foo").param("bar", "a").build()).isEqualTo("https://foo?bar=a"); - assertThat(new UrlBuilder("https://foo").param("bar", "a").param("baz", "b").build()).isEqualTo("https://foo?bar=a&baz=b"); + assertThat(new UrlBuilder("https://foo").queryParam("bar", null).build()).isEqualTo("https://foo"); + assertThat(new UrlBuilder("https://foo").queryParam("bar", "a").build()).isEqualTo("https://foo?bar=a"); + assertThat(new UrlBuilder("https://foo").queryParam("bar", "a").queryParam("baz", "b").build()).isEqualTo("https://foo?bar=a&baz=b"); } @Test void param_encode() { - assertThat(new UrlBuilder("https://foo").param("some one", "a%b").build()).isEqualTo("https://foo?some+one=a%25b"); + assertThat(new UrlBuilder("https://foo").queryParam("some one", "a%b").build()).isEqualTo("https://foo?some+one=a%25b"); } @Test diff --git a/http-client/client/src/test/java/org/example/Simple$rc.java b/http-client/client/src/test/java/org/example/Simple$rc.java index fdac9615a..224c904c8 100644 --- a/http-client/client/src/test/java/org/example/Simple$rc.java +++ b/http-client/client/src/test/java/org/example/Simple$rc.java @@ -32,7 +32,7 @@ class Simple$rc implements Simple { public List listRepos(String user, String other) throws HttpException { return context.request() .path("users").path(user).path("repos") - .param("other", other) + .queryParam("other", other) .get().list(Repo.class); } From 0b14dc558a51623506e5a599bafda493d3746220 Mon Sep 17 00:00:00 2001 From: rob bygrave Date: Fri, 25 Sep 2020 17:07:19 +1200 Subject: [PATCH 0033/1323] [maven-release-plugin] prepare release avaje-http-client-0.7 --- http-client/client/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/http-client/client/pom.xml b/http-client/client/pom.xml index abe2cbb2e..9228aa7ff 100644 --- a/http-client/client/pom.xml +++ b/http-client/client/pom.xml @@ -10,11 +10,11 @@ io.avaje avaje-http-client - 0.7-SNAPSHOT + 0.7 scm:git:git@github.com:avaje/avaje-http-client.git - HEAD + avaje-http-client-0.7 From 55e7af7bbb131ceb11b6937be8015de67fec2915 Mon Sep 17 00:00:00 2001 From: rob bygrave Date: Fri, 25 Sep 2020 17:07:30 +1200 Subject: [PATCH 0034/1323] [maven-release-plugin] prepare for next development iteration --- http-client/client/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/http-client/client/pom.xml b/http-client/client/pom.xml index 9228aa7ff..3ee77f8ea 100644 --- a/http-client/client/pom.xml +++ b/http-client/client/pom.xml @@ -10,11 +10,11 @@ io.avaje avaje-http-client - 0.7 + 0.8-SNAPSHOT scm:git:git@github.com:avaje/avaje-http-client.git - avaje-http-client-0.7 + HEAD From 5dafe77b6c6fe180d9cb7d99b53a8895520ede4a Mon Sep 17 00:00:00 2001 From: rob bygrave Date: Mon, 28 Sep 2020 20:48:55 +1300 Subject: [PATCH 0035/1323] Default to Redirect policy NORMAL. --- .../avaje/http/client/DHttpClientContextBuilder.java | 11 ++++++++++- .../java/io/avaje/http/client/HttpClientContext.java | 5 +++++ .../io/avaje/http/client/DHttpClientContextTest.java | 1 + 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContextBuilder.java b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContextBuilder.java index 54b476200..16fbe5446 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContextBuilder.java +++ b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContextBuilder.java @@ -21,6 +21,8 @@ class DHttpClientContextBuilder implements HttpClientContext.Builder { private CookieHandler cookieHandler = new CookieManager(); + private HttpClient.Redirect redirect = HttpClient.Redirect.NORMAL; + DHttpClientContextBuilder() { } @@ -60,6 +62,12 @@ public HttpClientContext.Builder withCookieHandler(CookieHandler cookieHandler) return this; } + @Override + public HttpClientContext.Builder withRedirect(HttpClient.Redirect redirect) { + this.redirect = redirect; + return this; + } + @Override public HttpClientContext build() { requireNonNull(baseUrl, "baseUrl is not specified"); @@ -73,7 +81,8 @@ public HttpClientContext build() { private HttpClient defaultClient() { final HttpClient.Builder builder = HttpClient.newBuilder() - .connectTimeout(Duration.ofSeconds(20)); + .followRedirects(redirect) + .connectTimeout(Duration.ofSeconds(20)); if (cookieHandler != null) { builder.cookieHandler(cookieHandler); } diff --git a/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java b/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java index 6650ab310..c8222a11f 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java +++ b/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java @@ -108,6 +108,11 @@ interface Builder { */ Builder withCookieHandler(CookieHandler cookieHandler); + /** + * Specify the redirect policy. Defaults to HttpClient.Redirect.NORMAL. + */ + Builder withRedirect(HttpClient.Redirect redirect); + /** * Build and return the context. */ diff --git a/http-client/client/src/test/java/io/avaje/http/client/DHttpClientContextTest.java b/http-client/client/src/test/java/io/avaje/http/client/DHttpClientContextTest.java index 52044b188..5405dd270 100644 --- a/http-client/client/src/test/java/io/avaje/http/client/DHttpClientContextTest.java +++ b/http-client/client/src/test/java/io/avaje/http/client/DHttpClientContextTest.java @@ -56,6 +56,7 @@ void build_noCookieHandler() { HttpClientContext.newBuilder() .withBaseUrl("http://localhost") .withCookieHandler(null) + .withRedirect(HttpClient.Redirect.ALWAYS) .build(); // has default client created From 235dd30d30fe3c1e82c3a4aa18b0b3149fa9aa0c Mon Sep 17 00:00:00 2001 From: rob bygrave Date: Mon, 28 Sep 2020 20:57:06 +1300 Subject: [PATCH 0036/1323] [maven-release-plugin] prepare release avaje-http-client-0.8 --- http-client/client/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/http-client/client/pom.xml b/http-client/client/pom.xml index 3ee77f8ea..04dceabca 100644 --- a/http-client/client/pom.xml +++ b/http-client/client/pom.xml @@ -10,11 +10,11 @@ io.avaje avaje-http-client - 0.8-SNAPSHOT + 0.8 scm:git:git@github.com:avaje/avaje-http-client.git - HEAD + avaje-http-client-0.8 From 5a6473b5874692783eb8056c30d06cd15e22d01e Mon Sep 17 00:00:00 2001 From: rob bygrave Date: Mon, 28 Sep 2020 20:57:31 +1300 Subject: [PATCH 0037/1323] [maven-release-plugin] prepare for next development iteration --- http-client/client/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/http-client/client/pom.xml b/http-client/client/pom.xml index 04dceabca..91f8c16ab 100644 --- a/http-client/client/pom.xml +++ b/http-client/client/pom.xml @@ -10,11 +10,11 @@ io.avaje avaje-http-client - 0.8 + 0.9-SNAPSHOT scm:git:git@github.com:avaje/avaje-http-client.git - avaje-http-client-0.8 + HEAD From fb410cdec58778ca531eeaa781154c8ec0d01973 Mon Sep 17 00:00:00 2001 From: rob bygrave Date: Wed, 30 Sep 2020 09:36:24 +1300 Subject: [PATCH 0038/1323] Make headers and formParams multi-value --- .../avaje/http/client/DHttpClientRequest.java | 29 +++++++++++-------- 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java index 2a180a126..2cc6a6e57 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java +++ b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java @@ -12,6 +12,7 @@ import java.nio.charset.StandardCharsets; import java.nio.file.Path; import java.time.Duration; +import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -40,9 +41,9 @@ class DHttpClientRequest implements HttpClientRequest, HttpClientResponse { private HttpRequest.Builder httpRequest; - private Map formParams; + private Map> formParams; - private Map headers; + private Map> headers; private boolean bodyFormEncoded; @@ -69,7 +70,7 @@ public HttpClientRequest header(String name, String value) { if (headers == null) { headers = new LinkedHashMap<>(); } - headers.put(name, value); + headers.computeIfAbsent(name, s -> new ArrayList<>()).add(value); return this; } @@ -103,7 +104,7 @@ public HttpClientRequest formParam(String name, String value) { if (formParams == null) { formParams = new LinkedHashMap<>(); } - formParams.put(name, value); + formParams.computeIfAbsent(name, s -> new ArrayList<>()).add(value); return this; } @@ -174,13 +175,15 @@ private HttpRequest.BodyPublisher bodyFromForm() { private String buildEncodedFormContent() { var builder = new StringBuilder(80); - for (Map.Entry entry : formParams.entrySet()) { - if (builder.length() > 0) { - builder.append("&"); + for (Map.Entry> entry : formParams.entrySet()) { + for (String value : entry.getValue()) { + if (builder.length() > 0) { + builder.append("&"); + } + builder.append(URLEncoder.encode(entry.getKey(), StandardCharsets.UTF_8)); + builder.append("="); + builder.append(URLEncoder.encode(value, StandardCharsets.UTF_8)); } - builder.append(URLEncoder.encode(entry.getKey(), StandardCharsets.UTF_8)); - builder.append("="); - builder.append(URLEncoder.encode(entry.getValue(), StandardCharsets.UTF_8)); } return builder.toString(); } @@ -205,8 +208,10 @@ private void addHeaders() { httpRequest.header(CONTENT_ENCODING, "gzip"); } if (headers != null) { - for (Map.Entry header : headers.entrySet()) { - httpRequest.header(header.getKey(), header.getValue()); + for (Map.Entry> header : headers.entrySet()) { + for (String value : header.getValue()) { + httpRequest.header(header.getKey(), value); + } } } } From 2476c1134058a9611cb6c636ac6483585572c165 Mon Sep 17 00:00:00 2001 From: rob bygrave Date: Wed, 30 Sep 2020 09:56:10 +1300 Subject: [PATCH 0039/1323] Javadoc improvements --- .../io/avaje/http/client/BodyAdapter.java | 26 ++++++++++++++++--- .../io/avaje/http/client/BodyContent.java | 17 ++++++++++++ .../io/avaje/http/client/HttpException.java | 16 ++++++++++++ .../io/avaje/http/client/RequestLogger.java | 3 +++ .../java/io/avaje/http/client/UrlBuilder.java | 2 +- 5 files changed, 60 insertions(+), 4 deletions(-) diff --git a/http-client/client/src/main/java/io/avaje/http/client/BodyAdapter.java b/http-client/client/src/main/java/io/avaje/http/client/BodyAdapter.java index 7f6c06e2e..7306887b8 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/BodyAdapter.java +++ b/http-client/client/src/main/java/io/avaje/http/client/BodyAdapter.java @@ -2,12 +2,32 @@ import java.util.List; +/** + * Adaptor between beans and content of a request or response. + *

+ * Typically converts between beans as JSON content. + */ public interface BodyAdapter { - BodyWriter beanWriter(Class cls); + /** + * Return a BodyWriter to write beans of this type as request content. + * + * @param type The type of the bean this writer is for + */ + BodyWriter beanWriter(Class type); - BodyReader beanReader(Class cls); + /** + * Return a BodyReader to read response content and convert to a bean. + * + * @param type The bean type to convert the content to. + */ + BodyReader beanReader(Class type); - BodyReader> listReader(Class cls); + /** + * Return a BodyReader to read response content and convert to a list of beans. + * + * @param type The bean type to convert the content to. + */ + BodyReader> listReader(Class type); } diff --git a/http-client/client/src/main/java/io/avaje/http/client/BodyContent.java b/http-client/client/src/main/java/io/avaje/http/client/BodyContent.java index ad3667d52..eb4427d09 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/BodyContent.java +++ b/http-client/client/src/main/java/io/avaje/http/client/BodyContent.java @@ -1,5 +1,10 @@ package io.avaje.http.client; +/** + * Content of request or response body used for adapting to beans. + *

+ * This is not used for streaming content. + */ public class BodyContent { public static final String JSON_UTF8 = "application/json; charset=UTF-8"; @@ -8,19 +13,31 @@ public class BodyContent { private final byte[] content; + /** + * Create and return as JSON body content given raw content. + */ public static BodyContent asJson(byte[] content) { return new BodyContent(JSON_UTF8, content); } + /** + * Create with content type and content. + */ public BodyContent(String contentType, byte[] content) { this.contentType = contentType; this.content = content; } + /** + * Return the content type. + */ public String contentType() { return contentType; } + /** + * Return the raw content. + */ public byte[] content() { return content; } diff --git a/http-client/client/src/main/java/io/avaje/http/client/HttpException.java b/http-client/client/src/main/java/io/avaje/http/client/HttpException.java index 12e0d5bad..21b183f1a 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/HttpException.java +++ b/http-client/client/src/main/java/io/avaje/http/client/HttpException.java @@ -3,22 +3,38 @@ import java.net.http.HttpResponse; import java.nio.charset.StandardCharsets; +/** + * HTTP Exception with support for converting the error response body into a bean. + *

+ * Wraps an underlying HttpResponse with helper methods to get the response body + * as string or as a bean. + *

+ */ public class HttpException extends RuntimeException { private final int statusCode; private HttpClientContext context; private HttpResponse httpResponse; + /** + * Create with status code and message. + */ public HttpException(int statusCode, String message) { super(message); this.statusCode = statusCode; } + /** + * Create with status code, message and throwable. + */ public HttpException(int statusCode, String message, Throwable cause) { super(message, cause); this.statusCode = statusCode; } + /** + * Create with status code and throwable. + */ public HttpException(int statusCode, Throwable cause) { super(cause); this.statusCode = statusCode; diff --git a/http-client/client/src/main/java/io/avaje/http/client/RequestLogger.java b/http-client/client/src/main/java/io/avaje/http/client/RequestLogger.java index 8d385060b..efb13897b 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/RequestLogger.java +++ b/http-client/client/src/main/java/io/avaje/http/client/RequestLogger.java @@ -10,6 +10,9 @@ import java.util.Map; import java.util.Set; +/** + * Logs request and response details for debug logging purposes. + */ public class RequestLogger implements ResponseListener { private static final Logger log = LoggerFactory.getLogger(RequestLogger.class); diff --git a/http-client/client/src/main/java/io/avaje/http/client/UrlBuilder.java b/http-client/client/src/main/java/io/avaje/http/client/UrlBuilder.java index c726982ad..57f7c3f9b 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/UrlBuilder.java +++ b/http-client/client/src/main/java/io/avaje/http/client/UrlBuilder.java @@ -7,7 +7,7 @@ public class UrlBuilder { private final StringBuilder buffer = new StringBuilder(100); - boolean hasParams; + private boolean hasParams; public UrlBuilder(String base) { buffer.append(base); From f80438bd0dbc65d63ea831eaf96ab92f4b49812a Mon Sep 17 00:00:00 2001 From: rob bygrave Date: Sun, 4 Oct 2020 14:19:25 +1300 Subject: [PATCH 0040/1323] [maven-release-plugin] prepare release avaje-http-client-0.9 --- http-client/client/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/http-client/client/pom.xml b/http-client/client/pom.xml index 91f8c16ab..c759197a6 100644 --- a/http-client/client/pom.xml +++ b/http-client/client/pom.xml @@ -10,11 +10,11 @@ io.avaje avaje-http-client - 0.9-SNAPSHOT + 0.9 scm:git:git@github.com:avaje/avaje-http-client.git - HEAD + avaje-http-client-0.9 From 5ff8c5e05e18e56f36c46d636ed711fe4663413a Mon Sep 17 00:00:00 2001 From: rob bygrave Date: Sun, 4 Oct 2020 14:19:37 +1300 Subject: [PATCH 0041/1323] [maven-release-plugin] prepare for next development iteration --- http-client/client/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/http-client/client/pom.xml b/http-client/client/pom.xml index c759197a6..f261a8c5d 100644 --- a/http-client/client/pom.xml +++ b/http-client/client/pom.xml @@ -10,11 +10,11 @@ io.avaje avaje-http-client - 0.9 + 0.10-SNAPSHOT scm:git:git@github.com:avaje/avaje-http-client.git - avaje-http-client-0.9 + HEAD From 69329435440d655baa63c3e3e5706266330288e4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 13 Oct 2020 14:10:24 +0000 Subject: [PATCH 0042/1323] Bump junit from 4.11 to 4.13.1 Bumps [junit](https://github.com/junit-team/junit4) from 4.11 to 4.13.1. - [Release notes](https://github.com/junit-team/junit4/releases) - [Changelog](https://github.com/junit-team/junit4/blob/main/doc/ReleaseNotes4.11.md) - [Commits](https://github.com/junit-team/junit4/compare/r4.11...r4.13.1) Signed-off-by: dependabot[bot] --- openapi-maven-plugin/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openapi-maven-plugin/pom.xml b/openapi-maven-plugin/pom.xml index 0206d76ac..a02fbadb9 100644 --- a/openapi-maven-plugin/pom.xml +++ b/openapi-maven-plugin/pom.xml @@ -44,7 +44,7 @@ junit junit - 4.11 + 4.13.1 test From ff0373ebb238b13ef9b953a283830cc4f2847fbe Mon Sep 17 00:00:00 2001 From: rob bygrave Date: Tue, 3 Nov 2020 20:40:31 +1300 Subject: [PATCH 0043/1323] Bump slf4j-api dependency t0 1.7.30 --- http-client/client/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/http-client/client/pom.xml b/http-client/client/pom.xml index f261a8c5d..1250b33d7 100644 --- a/http-client/client/pom.xml +++ b/http-client/client/pom.xml @@ -22,7 +22,7 @@ org.slf4j slf4j-api - 1.7.25 + 1.7.30 From 31d0f0b0424f13281229247891465c67babdb4c8 Mon Sep 17 00:00:00 2001 From: rob bygrave Date: Tue, 3 Nov 2020 21:59:48 +1300 Subject: [PATCH 0044/1323] Update README.md --- http-client/README.md | 113 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 112 insertions(+), 1 deletion(-) diff --git a/http-client/README.md b/http-client/README.md index b6459902b..69f30c0b4 100644 --- a/http-client/README.md +++ b/http-client/README.md @@ -1 +1,112 @@ -# avaje-http-client \ No newline at end of file +# avaje-http-client + +Create a HttpClientContext with a baseUrl, Jackson or Gson based JSON + body adapter, logger. + +```java + public HttpClientContext client() { + return HttpClientContext.newBuilder() + .withBaseUrl(baseUrl) + .withResponseListener(new RequestLogger()) + .withBodyAdapter(new JacksonBodyAdapter(new ObjectMapper())) +// .withBodyAdapter(new GsonBodyAdapter(new Gson())) + .build(); + } + +``` + +From HttpClientContext: + - Create a request + - Build the url via path(), matrixParam(), queryParam() + - Optionally set headers(), cookies() etc + - Optionally specify a request body (JSON, form, or raw BodyPublisher) + - Http verbs - get(), post(), put(), delete() + - Optionally return response body as a bean, list of beans, or raw + +## Examples + +GET as String +```java + final HttpResponse hres = clientContext.request() + .path("hello") + .get().asString(); + +``` + +GET as json to single bean +```java +final HelloDto bean = clientContext.request() + .path("hello/there") + .get().bean(HelloDto.class); +``` + +POST a bean as json request body +```java +HelloDto bean = new HelloDto(12, "rob", "other"); + +final HttpResponse res = clientContext.request() + .path("hello/savebean") + .body(bean).post() + .asDiscarding(); + +assertThat(res.statusCode()).isEqualTo(201); + +``` + +GET as json to list of beans +```java +final List beans = clientContext.request() + .path("hello") + .get().list(HelloDto.class); +``` + +Path +```java +final HttpResponse res = clientContext.request() + .path("hello") + .path("withMatrix") + .path("2011") + .get().asString(); + +// is the same as ... + +final HttpResponse res = clientContext.request() + .path("hello/withMatrix/2011") + .get().asString(); +``` + +MatrixParam +```java +final HttpResponse httpRes = clientContext.request() + .path("hello") + .matrixParam("author", "rob") + .matrixParam("country", "nz") + .path("foo") + .matrixParam("extra", "banana") + .get().asString(); +``` + +QueryParam +```java +final List beans = clientContext.request() + .path("hello") + .queryParam("sortBy", "name") + .queryParam("maxCount", "100") + .get().list(HelloDto.class); +``` + +FormParam +```java +final HttpResponse res = clientContext.request() + .path("hello/saveform") + .formParam("name", "Bazz") + .formParam("email", "user@foo.com") + .formParam("url", "http://foo.com") + .formParam("startDate", "2020-12-03") + .post() + .asDiscarding(); + +assertThat(res.statusCode()).isEqualTo(201); +``` + +## Currently NO support for POSTing multipart-form From 907f33543f7e9e099a67f92ceaccec39e056b566 Mon Sep 17 00:00:00 2001 From: rob bygrave Date: Wed, 11 Nov 2020 10:24:28 +1300 Subject: [PATCH 0045/1323] #2 - Add HttpApi for obtaining client implementations of an interface --- http-client/client/pom.xml | 52 +++++--- .../java/io/avaje/http/client/DHttpApi.java | 49 +++++++ .../java/io/avaje/http/client/HttpApi.java | 18 +++ .../io/avaje/http/client/HttpApiProvider.java | 13 ++ .../client/src/main/java/module-info.java | 10 ++ .../io/avaje/http/client/BaseWebTest.java | 2 +- .../io/avaje/http/client/DHttpApiTest.java | 35 +++++ .../http/client/HelloControllerTest.java | 1 - .../java/org/example/github/GithubTest.java | 33 +++++ .../test/java/org/example/github/Repo.java | 6 + .../java/org/example/{ => github}/Simple.java | 10 +- .../SimpleHttpClient.java} | 20 ++- .../test/java/org/example/webserver/App.java | 24 ++-- .../webserver/HelloController$route.java | 122 ++++++++++++++++++ .../example/webserver/HelloController.java | 35 +++-- .../java/org/example/webserver/HelloForm.java | 8 +- .../java/org/example/webserver/MyService.java | 16 --- http-client/gson-adapter/pom.xml | 13 +- http-client/pom.xml | 6 + http-client/test/pom.xml | 49 +++++++ .../src/main/java/example/github}/Repo.java | 2 +- .../src/main/java/example/github/Simple.java | 15 +++ .../java/example/github/SimpleHttpClient.java | 45 +++++++ .../test/src/main/java/module-info.java | 12 ++ .../io.avaje.http.client.HttpApiProvider | 1 + .../test/java/example/github/GithubTest.java | 51 ++++++++ .../test/src/test/resources/logback-test.xml | 19 +++ 27 files changed, 575 insertions(+), 92 deletions(-) create mode 100644 http-client/client/src/main/java/io/avaje/http/client/DHttpApi.java create mode 100644 http-client/client/src/main/java/io/avaje/http/client/HttpApi.java create mode 100644 http-client/client/src/main/java/module-info.java create mode 100644 http-client/client/src/test/java/io/avaje/http/client/DHttpApiTest.java create mode 100644 http-client/client/src/test/java/org/example/github/GithubTest.java create mode 100644 http-client/client/src/test/java/org/example/github/Repo.java rename http-client/client/src/test/java/org/example/{ => github}/Simple.java (81%) rename http-client/client/src/test/java/org/example/{Simple$rc.java => github/SimpleHttpClient.java} (83%) create mode 100644 http-client/client/src/test/java/org/example/webserver/HelloController$route.java delete mode 100644 http-client/client/src/test/java/org/example/webserver/MyService.java create mode 100644 http-client/test/pom.xml rename http-client/{client/src/test/java/org/example => test/src/main/java/example/github}/Repo.java (72%) create mode 100644 http-client/test/src/main/java/example/github/Simple.java create mode 100644 http-client/test/src/main/java/example/github/SimpleHttpClient.java create mode 100644 http-client/test/src/main/java/module-info.java create mode 100644 http-client/test/src/main/resources/META-INF/services/io.avaje.http.client.HttpApiProvider create mode 100644 http-client/test/src/test/java/example/github/GithubTest.java create mode 100644 http-client/test/src/test/resources/logback-test.xml diff --git a/http-client/client/pom.xml b/http-client/client/pom.xml index 1250b33d7..c9f49c183 100644 --- a/http-client/client/pom.xml +++ b/http-client/client/pom.xml @@ -1,5 +1,6 @@ - + java11-oss org.avaje @@ -49,23 +50,23 @@ - io.dinject - dinject - 2.3 + io.avaje + avaje-inject + 3.0 test - io.dinject - dinject-controller - 1.21 + io.avaje + avaje-http-api + 1.0 test - io.dinject - controller-validator-hibernate - 1.1 + io.avaje + avaje-http-hibernate-validator + 1.0 test @@ -79,19 +80,30 @@ - io.dinject - dinject-generator - 2.3 - test - - - - io.dinject - javalin-generator - 1.21 + io.avaje + avaje-inject-generator + 3.0 test + + + + maven-surefire-plugin + 3.0.0-M4 + + + --add-modules com.fasterxml.jackson.databind + --add-opens io.avaje.http.client/io.avaje.http.client=ALL-UNNAMED + --add-opens io.avaje.http.client/org.example.webserver=ALL-UNNAMED + --add-opens io.avaje.http.client/org.example.webserver=com.fasterxml.jackson.databind + --add-opens io.avaje.http.client/org.example.github=com.fasterxml.jackson.databind + + + + + +
diff --git a/http-client/client/src/main/java/io/avaje/http/client/DHttpApi.java b/http-client/client/src/main/java/io/avaje/http/client/DHttpApi.java new file mode 100644 index 000000000..3bbbdbc26 --- /dev/null +++ b/http-client/client/src/main/java/io/avaje/http/client/DHttpApi.java @@ -0,0 +1,49 @@ +package io.avaje.http.client; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.HashMap; +import java.util.Map; +import java.util.ServiceLoader; + +/** + * Service loads the HttpApiProvider for HttpApi. + */ +class DHttpApi { + + private static final Logger log = LoggerFactory.getLogger(DHttpApi.class); + + private static final DHttpApi INSTANCE = new DHttpApi(); + + private final Map, HttpApiProvider> providerMap = new HashMap<>(); + + DHttpApi() { + init(); + } + + @SuppressWarnings("rawtypes") + void init() { + for (HttpApiProvider apiProvider : ServiceLoader.load(HttpApiProvider.class)) { + addProvider(apiProvider); + } + log.debug("providers for {}", providerMap.keySet()); + } + + void addProvider(HttpApiProvider apiProvider) { + providerMap.put(apiProvider.type(), apiProvider); + } + + @SuppressWarnings("unchecked") + T provideFor(Class type, HttpClientContext clientContext) { + final HttpApiProvider apiProvider = (HttpApiProvider) providerMap.get(type); + if (apiProvider == null) { + throw new IllegalArgumentException("No registered HttpApiProvider for type: " + type); + } + return apiProvider.provide(clientContext); + } + + static T provide(Class type, HttpClientContext clientContext) { + return INSTANCE.provideFor(type, clientContext); + } +} diff --git a/http-client/client/src/main/java/io/avaje/http/client/HttpApi.java b/http-client/client/src/main/java/io/avaje/http/client/HttpApi.java new file mode 100644 index 000000000..5294f3848 --- /dev/null +++ b/http-client/client/src/main/java/io/avaje/http/client/HttpApi.java @@ -0,0 +1,18 @@ +package io.avaje.http.client; + +/** + * Provides Http client service implementations for a given interface type. + */ +public interface HttpApi { + + /** + * Provide the http client implementation for the given interface type. + * + * @param interfaceType The interface type + * @param clientContext The http client context used for executing the requests + * @return The http client implementation for the given interface type + */ + static T provide(Class interfaceType, HttpClientContext clientContext) { + return DHttpApi.provide(interfaceType, clientContext); + } +} diff --git a/http-client/client/src/main/java/io/avaje/http/client/HttpApiProvider.java b/http-client/client/src/main/java/io/avaje/http/client/HttpApiProvider.java index d574c1590..00829724c 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/HttpApiProvider.java +++ b/http-client/client/src/main/java/io/avaje/http/client/HttpApiProvider.java @@ -1,7 +1,20 @@ package io.avaje.http.client; +/** + * Provides http client implementations for an interface. + * + * @param The interface type + */ public interface HttpApiProvider { + /** + * Return the interface type this API implements. + */ + Class type(); + + /** + * Return the provided implementation of the API. + */ T provide(HttpClientContext client); } diff --git a/http-client/client/src/main/java/module-info.java b/http-client/client/src/main/java/module-info.java new file mode 100644 index 000000000..385d4f19a --- /dev/null +++ b/http-client/client/src/main/java/module-info.java @@ -0,0 +1,10 @@ +module io.avaje.http.client { + + uses io.avaje.http.client.HttpApiProvider; + + requires transitive java.net.http; + requires transitive org.slf4j; + requires static com.fasterxml.jackson.databind; + + exports io.avaje.http.client; +} diff --git a/http-client/client/src/test/java/io/avaje/http/client/BaseWebTest.java b/http-client/client/src/test/java/io/avaje/http/client/BaseWebTest.java index 353065ce5..7e95e9c70 100644 --- a/http-client/client/src/test/java/io/avaje/http/client/BaseWebTest.java +++ b/http-client/client/src/test/java/io/avaje/http/client/BaseWebTest.java @@ -1,8 +1,8 @@ package io.avaje.http.client; import com.fasterxml.jackson.databind.ObjectMapper; -import io.javalin.Javalin; import org.example.webserver.App; +import io.javalin.Javalin; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; diff --git a/http-client/client/src/test/java/io/avaje/http/client/DHttpApiTest.java b/http-client/client/src/test/java/io/avaje/http/client/DHttpApiTest.java new file mode 100644 index 000000000..06c6dc3b5 --- /dev/null +++ b/http-client/client/src/test/java/io/avaje/http/client/DHttpApiTest.java @@ -0,0 +1,35 @@ +package io.avaje.http.client; + +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.example.github.Repo; +import org.example.github.Simple; +import org.example.github.SimpleHttpClient; +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +public class DHttpApiTest { + + @Test + void test_github_listRepos() { + + JacksonBodyAdapter bodyAdapter = new JacksonBodyAdapter(new ObjectMapper() + .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)); + + final HttpClientContext clientContext = HttpClientContext.newBuilder() + .withBaseUrl("https://api.github.com") + .withBodyAdapter(bodyAdapter) + .build(); + + DHttpApi httpApi = new DHttpApi(); + httpApi.addProvider(new SimpleHttpClient.Provider()); + final Simple simple = httpApi.provideFor(Simple.class, clientContext); + + final List repos = simple.listRepos("rbygrave", "junk"); + assertThat(repos).isNotEmpty(); + } + +} diff --git a/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java b/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java index 256cd0387..2c6735ded 100644 --- a/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java +++ b/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java @@ -154,7 +154,6 @@ void postForm_asVoid_invokesValidation_expect_badRequest_extractError() { @Test void postForm_asBytes_validation_expect_badRequest_extractError() { - try { clientContext.request() .path("hello/saveform") diff --git a/http-client/client/src/test/java/org/example/github/GithubTest.java b/http-client/client/src/test/java/org/example/github/GithubTest.java new file mode 100644 index 000000000..2bbdfb1ba --- /dev/null +++ b/http-client/client/src/test/java/org/example/github/GithubTest.java @@ -0,0 +1,33 @@ +package org.example.github; + +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import io.avaje.http.client.HttpApi; +import io.avaje.http.client.HttpClientContext; +import io.avaje.http.client.JacksonBodyAdapter; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +public class GithubTest { + + @Test @Disabled + void test() { + + JacksonBodyAdapter bodyAdapter = new JacksonBodyAdapter(new ObjectMapper() + .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)); + + final HttpClientContext clientContext = HttpClientContext.newBuilder() + .withBaseUrl("https://api.github.com") + .withBodyAdapter(bodyAdapter) + .build(); + + final Simple simple = HttpApi.provide(Simple.class, clientContext); + + final List repos = simple.listRepos("rbygrave", "junk"); + assertThat(repos).isNotEmpty(); + } +} diff --git a/http-client/client/src/test/java/org/example/github/Repo.java b/http-client/client/src/test/java/org/example/github/Repo.java new file mode 100644 index 000000000..a2823f8f8 --- /dev/null +++ b/http-client/client/src/test/java/org/example/github/Repo.java @@ -0,0 +1,6 @@ +package org.example.github; + +public class Repo { + public long id; + public String name; +} diff --git a/http-client/client/src/test/java/org/example/Simple.java b/http-client/client/src/test/java/org/example/github/Simple.java similarity index 81% rename from http-client/client/src/test/java/org/example/Simple.java rename to http-client/client/src/test/java/org/example/github/Simple.java index 367bdddcb..9929c4000 100644 --- a/http-client/client/src/test/java/org/example/Simple.java +++ b/http-client/client/src/test/java/org/example/github/Simple.java @@ -1,14 +1,14 @@ -package org.example; +package org.example.github; import io.avaje.http.client.HttpException; -import io.dinject.controller.Get; -import io.dinject.controller.Path; -import io.dinject.controller.Post; +import io.avaje.http.api.Get; +import io.avaje.http.api.Path; +import io.avaje.http.api.Post; import java.net.http.HttpResponse; import java.util.List; -@Path("/foo") +@Path("/") public interface Simple { @Get("users/{user}/repos") diff --git a/http-client/client/src/test/java/org/example/Simple$rc.java b/http-client/client/src/test/java/org/example/github/SimpleHttpClient.java similarity index 83% rename from http-client/client/src/test/java/org/example/Simple$rc.java rename to http-client/client/src/test/java/org/example/github/SimpleHttpClient.java index 224c904c8..c3eea1897 100644 --- a/http-client/client/src/test/java/org/example/Simple$rc.java +++ b/http-client/client/src/test/java/org/example/github/SimpleHttpClient.java @@ -1,26 +1,26 @@ -package org.example; +package org.example.github; import io.avaje.http.client.BodyReader; import io.avaje.http.client.BodyWriter; import io.avaje.http.client.HttpApiProvider; import io.avaje.http.client.HttpClientContext; import io.avaje.http.client.HttpException; -import io.dinject.controller.Get; -import io.dinject.controller.Post; +import io.avaje.http.api.Get; +import io.avaje.http.api.Post; import java.io.InputStream; import java.net.http.HttpResponse; import java.util.List; -class Simple$rc implements Simple { +public class SimpleHttpClient implements Simple { private final HttpClientContext context; private final BodyReader readRepo; private final BodyWriter writeRepo; // private final BodyConverter, String> toListOfRepo; - Simple$rc(HttpClientContext context) { + SimpleHttpClient(HttpClientContext context) { this.context = context; this.readRepo = context.converters().beanReader(Repo.class); this.writeRepo = context.converters().beanWriter(Repo.class); @@ -69,10 +69,16 @@ public HttpResponse getById2(String id) { return null; } - static class Provider implements HttpApiProvider { + public static class Provider implements HttpApiProvider { + + @Override + public Class type() { + return Simple.class; + } + @Override public Simple provide(HttpClientContext client) { - return new Simple$rc(client); + return new SimpleHttpClient(client); } } diff --git a/http-client/client/src/test/java/org/example/webserver/App.java b/http-client/client/src/test/java/org/example/webserver/App.java index 58ce7fb11..02e4825d0 100644 --- a/http-client/client/src/test/java/org/example/webserver/App.java +++ b/http-client/client/src/test/java/org/example/webserver/App.java @@ -1,17 +1,14 @@ package org.example.webserver; -import io.dinject.SystemContext; -import io.dinject.controller.InvalidPathArgumentException; -import io.dinject.controller.InvalidTypeArgumentException; -import io.dinject.controller.ValidationException; -import io.dinject.controller.WebRoutes; +import io.avaje.http.api.InvalidPathArgumentException; +import io.avaje.http.api.InvalidTypeArgumentException; +import io.avaje.http.api.ValidationException; +import io.avaje.http.hibernate.validator.BeanValidator; import io.javalin.Javalin; -import io.javalin.http.staticfiles.Location; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.LinkedHashMap; -import java.util.List; import java.util.Map; public class App { @@ -34,7 +31,7 @@ public static Javalin start(int port) { app.exception(ValidationException.class, (exception, ctx) -> { - Map map = new LinkedHashMap<>(); + Map map = new LinkedHashMap<>(); map.put("message", exception.getMessage()); map.put("errors", exception.getErrors()); ctx.status(exception.getStatus()); @@ -59,14 +56,17 @@ public static Javalin start(int port) { ctx.json(map); }); - app.get("/", ctx -> { ctx.result("Hello World"); }); - // All WebRoutes / Controllers ... from DI Context - List webRoutes = SystemContext.getBeans(WebRoutes.class); - app.routes(() -> webRoutes.forEach(WebRoutes::registerRoutes)); +// // All WebRoutes / Controllers ... from DI Context +// List webRoutes = context.getBeans(WebRoutes.class); +// app.routes(() -> webRoutes.forEach(WebRoutes::registerRoutes)); + + // programmatically create http endpoints + HelloController$route bean = new HelloController$route(new HelloController(), new BeanValidator()); + app.routes(bean::registerRoutes); app.start(port); return app; diff --git a/http-client/client/src/test/java/org/example/webserver/HelloController$route.java b/http-client/client/src/test/java/org/example/webserver/HelloController$route.java new file mode 100644 index 000000000..9bf2f370c --- /dev/null +++ b/http-client/client/src/test/java/org/example/webserver/HelloController$route.java @@ -0,0 +1,122 @@ +package org.example.webserver; + +import io.avaje.http.api.PathSegment; +import io.avaje.http.api.Validator; +import io.avaje.http.api.WebRoutes; +import io.javalin.apibuilder.ApiBuilder; + +import javax.inject.Singleton; +import java.time.LocalDate; + +import static io.avaje.http.api.PathTypeConversion.asInt; +import static io.avaje.http.api.PathTypeConversion.asLocalDate; +import static io.avaje.http.api.PathTypeConversion.toLocalDate; + +@Singleton +public class HelloController$route implements WebRoutes { + + private final HelloController controller; + private final Validator validator; + + public HelloController$route(HelloController controller, Validator validator) { + this.controller = controller; + this.validator = validator; + } + + @Override + public void registerRoutes() { + + ApiBuilder.get("/hello/message", ctx -> { + ctx.status(200); + ctx.contentType("text/plain").result(controller.getPlainMessage()); + }); + + ApiBuilder.get("/hello/:id/:date", ctx -> { + ctx.status(200); + int id = asInt(ctx.pathParam("id")); + LocalDate date = asLocalDate(ctx.pathParam("date")); + String otherParam = ctx.queryParam("otherParam"); + ctx.json(controller.hello(id, date, otherParam)); + }); + + ApiBuilder.get("/hello/findbyname/:name", ctx -> { + ctx.status(200); + String name = ctx.pathParam("name"); + String otherParam = ctx.queryParam("otherParam"); + ctx.json(controller.findByName(name, otherParam)); + }); + + ApiBuilder.post("/hello", ctx -> { + ctx.status(201); + HelloDto dto = ctx.bodyAsClass(HelloDto.class); + validator.validate(dto); + ctx.json(controller.post(dto)); + }); + + ApiBuilder.post("/hello/savebean/:foo", ctx -> { + ctx.status(201); + String foo = ctx.pathParam("foo"); + HelloDto dto = ctx.bodyAsClass(HelloDto.class); + validator.validate(dto); + controller.saveBean(foo, dto, ctx); + }); + + ApiBuilder.post("/hello/saveform", ctx -> { + ctx.status(201); + HelloForm helloForm = new HelloForm( + ctx.formParam("name"), + ctx.formParam("email") + ); + helloForm.url = ctx.formParam("url"); + helloForm.startDate = toLocalDate(ctx.formParam("startDate")); + + validator.validate(helloForm); + controller.saveForm(helloForm); + }); + + ApiBuilder.post("/hello/saveform2", ctx -> { + ctx.status(201); + String name = ctx.formParam("name"); + String email = ctx.formParam("email"); + String url = ctx.formParam("url"); + controller.saveForm2(name, email, url); + }); + + ApiBuilder.post("/hello/saveform3", ctx -> { + ctx.status(201); + HelloForm helloForm = new HelloForm( + ctx.formParam("name"), + ctx.formParam("email") + ); + helloForm.url = ctx.formParam("url"); + helloForm.startDate = toLocalDate(ctx.formParam("startDate")); + + validator.validate(helloForm); + ctx.json(controller.saveForm3(helloForm)); + }); + + ApiBuilder.get("/hello", ctx -> { + ctx.status(200); + ctx.json(controller.getAll()); + }); + + ApiBuilder.delete("/hello/:id", ctx -> { + ctx.status(204); + int id = asInt(ctx.pathParam("id")); + controller.deleteById(id); + }); + + ApiBuilder.get("/hello/withMatrix/:year_segment/:other", ctx -> { + ctx.status(200); + PathSegment year_segment = PathSegment.of(ctx.pathParam("year_segment")); + int year = asInt(year_segment.val()); + String author = year_segment.matrix("author"); + String country = year_segment.matrix("country"); + String other = ctx.pathParam("other"); + String extra = ctx.queryParam("extra"); + ctx.contentType("text/plain").result(controller.getWithMatrixParam(year, author, country, other, extra)); + }); + + } + +} diff --git a/http-client/client/src/test/java/org/example/webserver/HelloController.java b/http-client/client/src/test/java/org/example/webserver/HelloController.java index 282ae2212..12077ba7f 100644 --- a/http-client/client/src/test/java/org/example/webserver/HelloController.java +++ b/http-client/client/src/test/java/org/example/webserver/HelloController.java @@ -1,17 +1,15 @@ package org.example.webserver; -import io.dinject.controller.Controller; -import io.dinject.controller.Delete; -import io.dinject.controller.Form; -import io.dinject.controller.Get; -import io.dinject.controller.MediaType; -import io.dinject.controller.Path; -import io.dinject.controller.Post; -import io.dinject.controller.Produces; +import io.avaje.http.api.Controller; +import io.avaje.http.api.Delete; +import io.avaje.http.api.Form; +import io.avaje.http.api.Get; +import io.avaje.http.api.MediaType; +import io.avaje.http.api.Path; +import io.avaje.http.api.Post; +import io.avaje.http.api.Produces; import io.javalin.http.Context; -import io.swagger.v3.oas.annotations.Hidden; -import javax.inject.Inject; import javax.validation.Valid; import java.time.LocalDate; import java.util.ArrayList; @@ -30,13 +28,6 @@ @Path("/hello") class HelloController { - private final MyService myService; - - @Inject - HelloController(MyService myService) { - this.myService = myService; - } - @Produces(MediaType.TEXT_PLAIN) @Get("message") String getPlainMessage() { @@ -116,10 +107,9 @@ HelloDto saveForm3(HelloForm helloForm) { return new HelloDto(52, helloForm.name, helloForm.email); } - @Hidden @Get List getAll() { - return myService.findAll(); + return findAll(); } // @Hidden @@ -133,4 +123,11 @@ void deleteById(int id) { String getWithMatrixParam(int year, String author, String country, String other, String extra) { return "yr:" + year + " au:" + author + " co:" + country + " other:" + other + " extra:" + extra; } + + private List findAll() { + List list = new ArrayList<>(); + list.add(new HelloDto(12, "Jim", "asd")); + list.add(new HelloDto(13, "Spock", "456456")); + return list; + } } diff --git a/http-client/client/src/test/java/org/example/webserver/HelloForm.java b/http-client/client/src/test/java/org/example/webserver/HelloForm.java index 6eaf10dd6..fdf1a34cf 100644 --- a/http-client/client/src/test/java/org/example/webserver/HelloForm.java +++ b/http-client/client/src/test/java/org/example/webserver/HelloForm.java @@ -15,16 +15,16 @@ public class HelloForm { @NotNull @Size(min = 2, max = 150) - String name; + public String name; @Email @Size(max = 100) - String email; + public String email; @URL - String url; + public String url; @Future - LocalDate startDate; + public LocalDate startDate; public HelloForm(String name, String email) { this.name = name; diff --git a/http-client/client/src/test/java/org/example/webserver/MyService.java b/http-client/client/src/test/java/org/example/webserver/MyService.java deleted file mode 100644 index 2763682d5..000000000 --- a/http-client/client/src/test/java/org/example/webserver/MyService.java +++ /dev/null @@ -1,16 +0,0 @@ -package org.example.webserver; - -import javax.inject.Singleton; -import java.util.ArrayList; -import java.util.List; - -@Singleton -public class MyService { - - public List findAll() { - List list = new ArrayList<>(); - list.add(new HelloDto(12, "Jim", "asd")); - list.add(new HelloDto(13, "Spock", "456456")); - return list; - } -} diff --git a/http-client/gson-adapter/pom.xml b/http-client/gson-adapter/pom.xml index 4178c3ce9..8fbbe1ff6 100644 --- a/http-client/gson-adapter/pom.xml +++ b/http-client/gson-adapter/pom.xml @@ -19,18 +19,19 @@ - - io.avaje - avaje-http-client - 0.5 - - com.google.code.gson gson 2.8.6 + + io.avaje + avaje-http-client + 0.5 + provided + + diff --git a/http-client/pom.xml b/http-client/pom.xml index 2562a9e88..8de9f6d32 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -1,6 +1,11 @@ 4.0.0 + + java11-oss + org.avaje + 2.2 + io.avaje avaje-http-client-parent @@ -12,6 +17,7 @@ client gson-adapter + test diff --git a/http-client/test/pom.xml b/http-client/test/pom.xml new file mode 100644 index 000000000..3bc31c772 --- /dev/null +++ b/http-client/test/pom.xml @@ -0,0 +1,49 @@ + + + + avaje-http-client-parent + io.avaje + 1 + + 4.0.0 + + test + + + + + io.avaje + avaje-http-client + 0.10-SNAPSHOT + + + + io.avaje + avaje-http-client-gson + 0.6-SNAPSHOT + + + + io.avaje + avaje-http-api + 1.0 + + + + org.avaje.composite + junit + 5.0 + test + + + + org.avaje.composite + logback + 1.1 + + + + + diff --git a/http-client/client/src/test/java/org/example/Repo.java b/http-client/test/src/main/java/example/github/Repo.java similarity index 72% rename from http-client/client/src/test/java/org/example/Repo.java rename to http-client/test/src/main/java/example/github/Repo.java index b33bbb68d..73564f763 100644 --- a/http-client/client/src/test/java/org/example/Repo.java +++ b/http-client/test/src/main/java/example/github/Repo.java @@ -1,4 +1,4 @@ -package org.example; +package example.github; public class Repo { public long id; diff --git a/http-client/test/src/main/java/example/github/Simple.java b/http-client/test/src/main/java/example/github/Simple.java new file mode 100644 index 000000000..f39f9638c --- /dev/null +++ b/http-client/test/src/main/java/example/github/Simple.java @@ -0,0 +1,15 @@ +package example.github; + +//import io.avaje.http.api.Get; +//import io.avaje.http.api.Path; +import io.avaje.http.client.HttpException; + +import java.util.List; + +//@Path("/") +public interface Simple { + + //@Get("users/{user}/repos") + List listRepos(String user, String other) throws HttpException; + +} diff --git a/http-client/test/src/main/java/example/github/SimpleHttpClient.java b/http-client/test/src/main/java/example/github/SimpleHttpClient.java new file mode 100644 index 000000000..ad2d33c88 --- /dev/null +++ b/http-client/test/src/main/java/example/github/SimpleHttpClient.java @@ -0,0 +1,45 @@ +package example.github; + +//import io.avaje.http.api.Get; + +import io.avaje.http.client.HttpApiProvider; +import io.avaje.http.client.HttpClientContext; +import io.avaje.http.client.HttpException; + +import java.util.List; + +/** + * This code could be generated from the interface definition. + */ +public class SimpleHttpClient implements HttpApiProvider { + + @Override + public Class type() { + return Simple.class; + } + + @Override + public Simple provide(HttpClientContext client) { + return new SimpleClient(client); + } + + private static class SimpleClient implements Simple { + + private final HttpClientContext context; + + SimpleClient(HttpClientContext context) { + this.context = context; + } + + //@Get("users/{user}/repos") + @Override + public List listRepos(String user, String other) throws HttpException { + return context.request() + .path("users").path(user).path("repos") + .queryParam("other", other) + .get().list(Repo.class); + } + + } + +} diff --git a/http-client/test/src/main/java/module-info.java b/http-client/test/src/main/java/module-info.java new file mode 100644 index 000000000..0c8db39c5 --- /dev/null +++ b/http-client/test/src/main/java/module-info.java @@ -0,0 +1,12 @@ +import example.github.SimpleHttpClient; + +module test { + + requires io.avaje.http.client; + requires com.fasterxml.jackson.databind; + requires com.google.gson; + + provides io.avaje.http.client.HttpApiProvider with SimpleHttpClient; + + exports example.github; +} diff --git a/http-client/test/src/main/resources/META-INF/services/io.avaje.http.client.HttpApiProvider b/http-client/test/src/main/resources/META-INF/services/io.avaje.http.client.HttpApiProvider new file mode 100644 index 000000000..e15a847cf --- /dev/null +++ b/http-client/test/src/main/resources/META-INF/services/io.avaje.http.client.HttpApiProvider @@ -0,0 +1 @@ +example.github.SimpleHttpClient diff --git a/http-client/test/src/test/java/example/github/GithubTest.java b/http-client/test/src/test/java/example/github/GithubTest.java new file mode 100644 index 000000000..78685671c --- /dev/null +++ b/http-client/test/src/test/java/example/github/GithubTest.java @@ -0,0 +1,51 @@ +package example.github; + +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.gson.Gson; +import io.avaje.http.client.BodyAdapter; +import io.avaje.http.client.HttpApi; +import io.avaje.http.client.HttpClientContext; +import io.avaje.http.client.JacksonBodyAdapter; +import io.avaje.http.client.RequestLogger; +import io.avaje.http.client.gson.GsonBodyAdapter; +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +public class GithubTest { + + @Test + void test_with_jackson() { + assertListRepos(jacksonBodyAdapter()); + } + + @Test + void test_with_gson() { + assertListRepos(gsonBodyAdapter()); + } + + private void assertListRepos(BodyAdapter bodyAdapter) { + final HttpClientContext clientContext = HttpClientContext.newBuilder() + .withBaseUrl("https://api.github.com") + .withBodyAdapter(bodyAdapter) + .withResponseListener(new RequestLogger()) + .build(); + + final Simple simple = HttpApi.provide(Simple.class, clientContext); + + final List repos = simple.listRepos("rbygrave", "junk"); + assertThat(repos).isNotEmpty(); + } + + private BodyAdapter jacksonBodyAdapter() { + return new JacksonBodyAdapter(new ObjectMapper() + .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)); + } + + private BodyAdapter gsonBodyAdapter() { + return new GsonBodyAdapter(new Gson()); + } +} diff --git a/http-client/test/src/test/resources/logback-test.xml b/http-client/test/src/test/resources/logback-test.xml new file mode 100644 index 000000000..5705ccc25 --- /dev/null +++ b/http-client/test/src/test/resources/logback-test.xml @@ -0,0 +1,19 @@ + + + + TRACE + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + + + + + From 824895737f6918eb42474efacb547802043069af Mon Sep 17 00:00:00 2001 From: rob bygrave Date: Wed, 11 Nov 2020 10:26:30 +1300 Subject: [PATCH 0046/1323] [maven-release-plugin] prepare release avaje-http-client-0.10 --- http-client/client/pom.xml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/http-client/client/pom.xml b/http-client/client/pom.xml index c9f49c183..a8375ed9b 100644 --- a/http-client/client/pom.xml +++ b/http-client/client/pom.xml @@ -1,6 +1,5 @@ - + java11-oss org.avaje @@ -11,11 +10,11 @@ io.avaje avaje-http-client - 0.10-SNAPSHOT + 0.10 scm:git:git@github.com:avaje/avaje-http-client.git - HEAD + avaje-http-client-0.10 From 7fcc3b87690ccfc33f593f1fe729d7e9dda891df Mon Sep 17 00:00:00 2001 From: rob bygrave Date: Wed, 11 Nov 2020 10:26:41 +1300 Subject: [PATCH 0047/1323] [maven-release-plugin] prepare for next development iteration --- http-client/client/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/http-client/client/pom.xml b/http-client/client/pom.xml index a8375ed9b..b6bd3a537 100644 --- a/http-client/client/pom.xml +++ b/http-client/client/pom.xml @@ -10,11 +10,11 @@ io.avaje avaje-http-client - 0.10 + 0.11-SNAPSHOT scm:git:git@github.com:avaje/avaje-http-client.git - avaje-http-client-0.10 + HEAD From fe90e3cc0484ed73d46e2dd53fb3f2d648c9b1cf Mon Sep 17 00:00:00 2001 From: rob bygrave Date: Wed, 11 Nov 2020 10:32:27 +1300 Subject: [PATCH 0048/1323] Bump for release --- http-client/gson-adapter/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/http-client/gson-adapter/pom.xml b/http-client/gson-adapter/pom.xml index 8fbbe1ff6..0f731719a 100644 --- a/http-client/gson-adapter/pom.xml +++ b/http-client/gson-adapter/pom.xml @@ -10,7 +10,7 @@ io.avaje avaje-http-client-gson - 0.6-SNAPSHOT + 0.10-SNAPSHOT scm:git:git@github.com:avaje/avaje-http-client.git @@ -28,7 +28,7 @@ io.avaje avaje-http-client - 0.5 + 0.10 provided From b5aa7737592d5a09c1081521f3acc9fab58f0cf1 Mon Sep 17 00:00:00 2001 From: rob bygrave Date: Wed, 11 Nov 2020 10:33:01 +1300 Subject: [PATCH 0049/1323] [maven-release-plugin] prepare release avaje-http-client-gson-0.10 --- http-client/gson-adapter/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/http-client/gson-adapter/pom.xml b/http-client/gson-adapter/pom.xml index 0f731719a..3c7a4cff8 100644 --- a/http-client/gson-adapter/pom.xml +++ b/http-client/gson-adapter/pom.xml @@ -10,11 +10,11 @@ io.avaje avaje-http-client-gson - 0.10-SNAPSHOT + 0.10 scm:git:git@github.com:avaje/avaje-http-client.git - HEAD + avaje-http-client-gson-0.10 From f5ec55f3388c71fd43fd770912ffa131797af2cd Mon Sep 17 00:00:00 2001 From: rob bygrave Date: Wed, 11 Nov 2020 10:33:11 +1300 Subject: [PATCH 0050/1323] [maven-release-plugin] prepare for next development iteration --- http-client/gson-adapter/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/http-client/gson-adapter/pom.xml b/http-client/gson-adapter/pom.xml index 3c7a4cff8..c515bff70 100644 --- a/http-client/gson-adapter/pom.xml +++ b/http-client/gson-adapter/pom.xml @@ -10,11 +10,11 @@ io.avaje avaje-http-client-gson - 0.10 + 0.11-SNAPSHOT scm:git:git@github.com:avaje/avaje-http-client.git - avaje-http-client-gson-0.10 + HEAD From a0d29efb9fec3c936c80137bc8048598a2c42039 Mon Sep 17 00:00:00 2001 From: rob bygrave Date: Wed, 16 Dec 2020 15:17:01 +1300 Subject: [PATCH 0051/1323] Bump for release 1.0 --- http-client/client/pom.xml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/http-client/client/pom.xml b/http-client/client/pom.xml index b6bd3a537..c452b0d0d 100644 --- a/http-client/client/pom.xml +++ b/http-client/client/pom.xml @@ -1,16 +1,15 @@ + 4.0.0 java11-oss org.avaje - 2.2 + 2.3 - 4.0.0 - io.avaje avaje-http-client - 0.11-SNAPSHOT + 1.0 scm:git:git@github.com:avaje/avaje-http-client.git From 368d86ded9f086c39b8c4081bd44b7bd6977f6df Mon Sep 17 00:00:00 2001 From: rob bygrave Date: Wed, 16 Dec 2020 15:23:45 +1300 Subject: [PATCH 0052/1323] Update test dependencies --- http-client/client/pom.xml | 8 ++++---- .../java/io/avaje/http/client/HelloControllerTest.java | 6 +++--- .../org/example/webserver/HelloController$route.java | 2 +- .../java/org/example/webserver/HelloController.java | 10 +++++----- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/http-client/client/pom.xml b/http-client/client/pom.xml index c452b0d0d..bf59f731e 100644 --- a/http-client/client/pom.xml +++ b/http-client/client/pom.xml @@ -50,21 +50,21 @@ io.avaje avaje-inject - 3.0 + 4.1 test io.avaje avaje-http-api - 1.0 + 1.2 test io.avaje avaje-http-hibernate-validator - 1.0 + 2.0 test @@ -80,7 +80,7 @@ io.avaje avaje-inject-generator - 3.0 + 4.1 test diff --git a/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java b/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java index 2c6735ded..5c42d86c6 100644 --- a/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java +++ b/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java @@ -89,7 +89,7 @@ void postForm() { .formParam("name", "Bazz") .formParam("email", "user@foo.com") .formParam("url", "http://foo.com") - .formParam("startDate", "2020-12-03") + .formParam("startDate", "2030-12-03") .post() .asDiscarding(); @@ -104,7 +104,7 @@ void postForm_returningBean() { .formParam("name", "Bazz") .formParam("email", "user@foo.com") .formParam("url", "http://foo.com") - .formParam("startDate", "2020-12-03") + .formParam("startDate", "2030-12-03") .post() .asDiscarding(); @@ -115,7 +115,7 @@ void postForm_returningBean() { .formParam("name", "Bax") .formParam("email", "Bax@foo.com") .formParam("url", "http://foo.com") - .formParam("startDate", "2020-12-03") + .formParam("startDate", "2030-12-03") .post() .bean(HelloDto.class); diff --git a/http-client/client/src/test/java/org/example/webserver/HelloController$route.java b/http-client/client/src/test/java/org/example/webserver/HelloController$route.java index 9bf2f370c..08ca7dfae 100644 --- a/http-client/client/src/test/java/org/example/webserver/HelloController$route.java +++ b/http-client/client/src/test/java/org/example/webserver/HelloController$route.java @@ -5,7 +5,7 @@ import io.avaje.http.api.WebRoutes; import io.javalin.apibuilder.ApiBuilder; -import javax.inject.Singleton; +import jakarta.inject.Singleton; import java.time.LocalDate; import static io.avaje.http.api.PathTypeConversion.asInt; diff --git a/http-client/client/src/test/java/org/example/webserver/HelloController.java b/http-client/client/src/test/java/org/example/webserver/HelloController.java index 12077ba7f..8949419e5 100644 --- a/http-client/client/src/test/java/org/example/webserver/HelloController.java +++ b/http-client/client/src/test/java/org/example/webserver/HelloController.java @@ -43,7 +43,7 @@ String getPlainMessage() { * @return The Hello DTO given the id and name. * @deprecated Please migrate away */ - @Get("/:id/:date") + @Get("/{id}/{date}") HelloDto hello(int id, LocalDate date, String otherParam) { return new HelloDto(id, date.toString(), otherParam); } @@ -55,7 +55,7 @@ HelloDto hello(int id, LocalDate date, String otherParam) { * @param otherParam My option parameter * @return The Hellos that we found. */ - @Get("/findbyname/:name") + @Get("/findbyname/{name}") List findByName(String name, String otherParam) { return new ArrayList<>(); } @@ -76,7 +76,7 @@ HelloDto post(HelloDto dto) { * @param dto The hello body as json */ // @Roles({ADMIN}) - @Post("/savebean/:foo") + @Post("/savebean/{foo}") void saveBean(String foo, HelloDto dto, Context context) { // save hello data ... System.out.println("save " + foo + " dto:" + dto); @@ -113,13 +113,13 @@ List getAll() { } // @Hidden - @Delete(":id") + @Delete("{id}") void deleteById(int id) { System.out.println("deleting " + id); } @Produces("text/plain") - @Get("/withMatrix/:year;author;country/:other") + @Get("/withMatrix/{year};author;country/{other}") String getWithMatrixParam(int year, String author, String country, String other, String extra) { return "yr:" + year + " au:" + author + " co:" + country + " other:" + other + " extra:" + extra; } From 1e6385146987641fc3a8874bacf78a496c46c12d Mon Sep 17 00:00:00 2001 From: rob bygrave Date: Wed, 16 Dec 2020 15:25:56 +1300 Subject: [PATCH 0053/1323] Bump for release 1.0 --- http-client/gson-adapter/pom.xml | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/http-client/gson-adapter/pom.xml b/http-client/gson-adapter/pom.xml index c515bff70..59551d3a9 100644 --- a/http-client/gson-adapter/pom.xml +++ b/http-client/gson-adapter/pom.xml @@ -1,16 +1,15 @@ + 4.0.0 java11-oss org.avaje - 2.2 + 2.3 - 4.0.0 - io.avaje avaje-http-client-gson - 0.11-SNAPSHOT + 1.0 scm:git:git@github.com:avaje/avaje-http-client.git @@ -28,7 +27,7 @@ io.avaje avaje-http-client - 0.10 + 1.0 provided From 88cdedf995f1998c352171f0ac6d2faa272b9998 Mon Sep 17 00:00:00 2001 From: rob bygrave Date: Wed, 16 Dec 2020 15:33:18 +1300 Subject: [PATCH 0054/1323] Bump integration test dependencies --- http-client/test/pom.xml | 12 +++++++++--- http-client/test/src/main/java/module-info.java | 2 +- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/http-client/test/pom.xml b/http-client/test/pom.xml index 3bc31c772..eff661549 100644 --- a/http-client/test/pom.xml +++ b/http-client/test/pom.xml @@ -16,19 +16,25 @@ io.avaje avaje-http-client - 0.10-SNAPSHOT + 1.0 io.avaje avaje-http-client-gson - 0.6-SNAPSHOT + 1.0 io.avaje avaje-http-api - 1.0 + 1.2 + + + + com.fasterxml.jackson.core + jackson-databind + 2.11.1 diff --git a/http-client/test/src/main/java/module-info.java b/http-client/test/src/main/java/module-info.java index 0c8db39c5..af18dba30 100644 --- a/http-client/test/src/main/java/module-info.java +++ b/http-client/test/src/main/java/module-info.java @@ -1,6 +1,6 @@ import example.github.SimpleHttpClient; -module test { +open module test { requires io.avaje.http.client; requires com.fasterxml.jackson.databind; From 34762364ee909a8c55761de2143d132c91b80acd Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Thu, 8 Apr 2021 14:30:57 +1200 Subject: [PATCH 0055/1323] Update README.md --- http-client/README.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/http-client/README.md b/http-client/README.md index 69f30c0b4..35b35f22e 100644 --- a/http-client/README.md +++ b/http-client/README.md @@ -1,5 +1,18 @@ # avaje-http-client + +### Dependency + +```xml + + io.avaje + avaje-http-client + 1.0 + +``` + +### Create HttpClientContext + Create a HttpClientContext with a baseUrl, Jackson or Gson based JSON body adapter, logger. @@ -15,6 +28,8 @@ Create a HttpClientContext with a baseUrl, Jackson or Gson based JSON ``` +### Requests + From HttpClientContext: - Create a request - Build the url via path(), matrixParam(), queryParam() From 330ea7ec2bbb147e255baf041a768c7b427592d0 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Thu, 8 Apr 2021 14:35:45 +1200 Subject: [PATCH 0056/1323] Update README.md --- http-client/README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/http-client/README.md b/http-client/README.md index 35b35f22e..26fd10e58 100644 --- a/http-client/README.md +++ b/http-client/README.md @@ -1,5 +1,12 @@ # avaje-http-client +A light weight wrapper to the JDK 11+ Java Http Client + +- Adds a fluid API for request constructing URL and payload +- Adds JSON marshalling/unmarshalling of request and response using Jackson or Gson +- Adds request/response logging + + ### Dependency From 706626d5f7daa7dffdc8e90b86659286ddfdfcbf Mon Sep 17 00:00:00 2001 From: Robin Bygrave Date: Mon, 12 Apr 2021 13:52:15 +1200 Subject: [PATCH 0057/1323] Bump java11-oss parent pom version to 3.1 --- http-client/client/pom.xml | 4 ++-- http-client/gson-adapter/pom.xml | 2 +- http-client/pom.xml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/http-client/client/pom.xml b/http-client/client/pom.xml index bf59f731e..2c8126828 100644 --- a/http-client/client/pom.xml +++ b/http-client/client/pom.xml @@ -4,12 +4,12 @@ java11-oss org.avaje - 2.3 + 3.1 io.avaje avaje-http-client - 1.0 + 1.1-SNAPSHOT scm:git:git@github.com:avaje/avaje-http-client.git diff --git a/http-client/gson-adapter/pom.xml b/http-client/gson-adapter/pom.xml index 59551d3a9..0b65827ff 100644 --- a/http-client/gson-adapter/pom.xml +++ b/http-client/gson-adapter/pom.xml @@ -4,7 +4,7 @@ java11-oss org.avaje - 2.3 + 3.1 io.avaje diff --git a/http-client/pom.xml b/http-client/pom.xml index 8de9f6d32..e9e54b3e0 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,7 +4,7 @@ java11-oss org.avaje - 2.2 + 3.1 io.avaje From 1803c348e906aafbd98c15596716332422c283e6 Mon Sep 17 00:00:00 2001 From: Robin Bygrave Date: Mon, 12 Apr 2021 13:56:13 +1200 Subject: [PATCH 0058/1323] Bump version of optional jackson dependency --- http-client/client/pom.xml | 2 +- http-client/test/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/http-client/client/pom.xml b/http-client/client/pom.xml index 2c8126828..ff0fb5b7d 100644 --- a/http-client/client/pom.xml +++ b/http-client/client/pom.xml @@ -27,7 +27,7 @@ com.fasterxml.jackson.core jackson-databind - 2.11.1 + 2.12.2 true diff --git a/http-client/test/pom.xml b/http-client/test/pom.xml index eff661549..1efa21623 100644 --- a/http-client/test/pom.xml +++ b/http-client/test/pom.xml @@ -34,7 +34,7 @@ com.fasterxml.jackson.core jackson-databind - 2.11.1 + 2.12.2 From bae7bbf627307d5fe804d55fafd0675196322f97 Mon Sep 17 00:00:00 2001 From: Robin Bygrave Date: Mon, 12 Apr 2021 15:35:17 +1200 Subject: [PATCH 0059/1323] #3 - Improve Request/Response logging with plain String body and response --- .../avaje/http/client/DHttpClientRequest.java | 25 +++++++++++-------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java index 2cc6a6e57..668279ed1 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java +++ b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java @@ -28,30 +28,25 @@ class DHttpClientRequest implements HttpClientRequest, HttpClientResponse { private static final String CONTENT_ENCODING = "Content-Encoding"; private final DHttpClientContext context; - private final UrlBuilder url; - private Duration requestTimeout; - private boolean gzip; private BodyContent encodedRequestBody; - private HttpRequest.BodyPublisher body; + private String rawRequestBody; private HttpRequest.Builder httpRequest; private Map> formParams; - private Map> headers; private boolean bodyFormEncoded; - private long requestTimeNanos; private HttpResponse httpResponse; - private BodyContent encodedResponseBody; + private boolean loggableResponseBody; public DHttpClientRequest(DHttpClientContext context, Duration requestTimeout) { this.context = context; @@ -127,6 +122,7 @@ public HttpClientRequest body(Object bean) { @Override public HttpClientRequest body(String body) { + this.rawRequestBody = body; this.body = HttpRequest.BodyPublishers.ofString(body); return this; } @@ -292,6 +288,7 @@ public HttpResponse asByteArray() { @Override public HttpResponse asString() { + loggableResponseBody = true; return withResponseHandler(HttpResponse.BodyHandlers.ofString()); } @@ -381,11 +378,11 @@ public HttpRequest request() { public String requestBody() { if (encodedRequestBody != null) { return new String(encodedRequestBody.content(), StandardCharsets.UTF_8); - } - if (bodyFormEncoded) { + } else if (bodyFormEncoded) { return buildEncodedFormContent(); - } - if (body != null) { + } else if (rawRequestBody != null) { + return rawRequestBody; + } else if (body != null) { return body.toString(); } return null; @@ -395,6 +392,12 @@ public String requestBody() { public String responseBody() { if (encodedResponseBody != null) { return new String(encodedResponseBody.content(), StandardCharsets.UTF_8); + } else if (httpResponse != null && loggableResponseBody) { + String strBody = httpResponse.body().toString(); + if (strBody.length() > 1_000) { + return strBody.substring(0, 1_000) + "..."; + } + return strBody; } return null; } From 9a200c81f5c299045907321ad68924cd0f8e49ce Mon Sep 17 00:00:00 2001 From: Robin Bygrave Date: Mon, 12 Apr 2021 15:38:39 +1200 Subject: [PATCH 0060/1323] #4 - ENH: Add withVersion() and withExecutor() methods to HttpClientContext.Builder --- .../client/DHttpClientContextBuilder.java | 20 ++++++++++++++++ .../avaje/http/client/HttpClientContext.java | 24 +++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContextBuilder.java b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContextBuilder.java index 16fbe5446..efaf6f277 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContextBuilder.java +++ b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContextBuilder.java @@ -4,6 +4,7 @@ import java.net.CookieManager; import java.net.http.HttpClient; import java.time.Duration; +import java.util.concurrent.Executor; import static java.util.Objects.requireNonNull; @@ -23,6 +24,9 @@ class DHttpClientContextBuilder implements HttpClientContext.Builder { private HttpClient.Redirect redirect = HttpClient.Redirect.NORMAL; + private HttpClient.Version version; + private Executor executor; + DHttpClientContextBuilder() { } @@ -67,6 +71,16 @@ public HttpClientContext.Builder withRedirect(HttpClient.Redirect redirect) { this.redirect = redirect; return this; } + @Override + public HttpClientContext.Builder withVersion(HttpClient.Version version) { + this.version = version; + return this; + } + @Override + public HttpClientContext.Builder withExecutor(Executor executor) { + this.executor = executor; + return this; + } @Override public HttpClientContext build() { @@ -86,6 +100,12 @@ private HttpClient defaultClient() { if (cookieHandler != null) { builder.cookieHandler(cookieHandler); } + if (version != null) { + builder.version(version); + } + if (executor != null) { + builder.executor(executor); + } return builder.build(); } diff --git a/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java b/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java index c8222a11f..7fce52a2c 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java +++ b/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java @@ -4,6 +4,7 @@ import java.net.http.HttpClient; import java.net.http.HttpResponse; import java.time.Duration; +import java.util.concurrent.Executor; /** * The HTTP client context that we use to build and process requests. @@ -77,6 +78,8 @@ interface Builder { /** * Set the underlying HttpClient to use. + *

+ * Used when we wish to control all options of the HttpClient. */ Builder with(HttpClient client); @@ -87,6 +90,8 @@ interface Builder { /** * Set the default request timeout. + * + * @see java.net.http.HttpRequest.Builder#timeout(Duration) */ Builder withRequestTimeout(Duration requestTimeout); @@ -105,14 +110,33 @@ interface Builder { /** * Specify a cookie handler to use on the HttpClient. This would override the default cookie handler. + * + * @see HttpClient.Builder#cookieHandler(CookieHandler) */ Builder withCookieHandler(CookieHandler cookieHandler); /** * Specify the redirect policy. Defaults to HttpClient.Redirect.NORMAL. + * + * @see HttpClient.Builder#followRedirects(HttpClient.Redirect) */ Builder withRedirect(HttpClient.Redirect redirect); + /** + * Specify the HTTP version. Defaults to not set. + * + * @see HttpClient.Builder#version(HttpClient.Version) + */ + Builder withVersion(HttpClient.Version version); + + /** + * Specify the Executor to use for asynchronous tasks. + * If not specified a default executor will be used. + * + * @see HttpClient.Builder#executor(Executor) + */ + Builder withExecutor(Executor executor); + /** * Build and return the context. */ From ea8f1eca05184b1045f86feda492c887138ce44d Mon Sep 17 00:00:00 2001 From: Robin Bygrave Date: Mon, 12 Apr 2021 16:04:50 +1200 Subject: [PATCH 0061/1323] Minor adjustment to request/response logging --- .../src/main/java/io/avaje/http/client/RequestLogger.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/http-client/client/src/main/java/io/avaje/http/client/RequestLogger.java b/http-client/client/src/main/java/io/avaje/http/client/RequestLogger.java index efb13897b..05c8d31ce 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/RequestLogger.java +++ b/http-client/client/src/main/java/io/avaje/http/client/RequestLogger.java @@ -59,7 +59,7 @@ private void headers(StringBuilder sb, String label, HttpHeaders headers) { if (!entries.isEmpty()) { sb.append(delimiter).append(label); for (Map.Entry> entry : entries) { - sb.append(entry.getKey()).append("=").append(entry.getValue()).append("; "); + sb.append(entry.getKey()).append("=").append(entry.getValue()).append(", "); } } } From 7202d8c1267850c2db6c59a76336751eed016769 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Mon, 12 Apr 2021 16:39:02 +1200 Subject: [PATCH 0062/1323] Bump release version 1.1 and java11-oss parent to 3.2 --- http-client/client/pom.xml | 4 ++-- http-client/gson-adapter/pom.xml | 4 ++-- http-client/pom.xml | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/http-client/client/pom.xml b/http-client/client/pom.xml index ff0fb5b7d..518da1375 100644 --- a/http-client/client/pom.xml +++ b/http-client/client/pom.xml @@ -4,12 +4,12 @@ java11-oss org.avaje - 3.1 + 3.2 io.avaje avaje-http-client - 1.1-SNAPSHOT + 1.1 scm:git:git@github.com:avaje/avaje-http-client.git diff --git a/http-client/gson-adapter/pom.xml b/http-client/gson-adapter/pom.xml index 0b65827ff..f7a0d6a1d 100644 --- a/http-client/gson-adapter/pom.xml +++ b/http-client/gson-adapter/pom.xml @@ -4,12 +4,12 @@ java11-oss org.avaje - 3.1 + 3.2 io.avaje avaje-http-client-gson - 1.0 + 1.1 scm:git:git@github.com:avaje/avaje-http-client.git diff --git a/http-client/pom.xml b/http-client/pom.xml index e9e54b3e0..79d059d20 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,7 +4,7 @@ java11-oss org.avaje - 3.1 + 3.2 io.avaje From f30d1f5989d37ddbf4c1445933a4c0d1f6161b15 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Thu, 22 Apr 2021 13:50:07 +1200 Subject: [PATCH 0063/1323] #5 - Add HttpClientRequest.url(String url) - ability to replace the base url --- .../java/io/avaje/http/client/BodyReader.java | 6 ++ .../avaje/http/client/DHttpClientRequest.java | 6 ++ .../avaje/http/client/HttpClientContext.java | 66 ++++++++++++++++++- .../avaje/http/client/HttpClientRequest.java | 27 ++++++++ .../java/io/avaje/http/client/UrlBuilder.java | 37 ++++++++++- .../io/avaje/http/client/package-info.java | 22 +++++++ .../http/client/HelloControllerTest.java | 12 ++++ .../io/avaje/http/client/UrlBuilderTest.java | 6 ++ 8 files changed, 180 insertions(+), 2 deletions(-) create mode 100644 http-client/client/src/main/java/io/avaje/http/client/package-info.java diff --git a/http-client/client/src/main/java/io/avaje/http/client/BodyReader.java b/http-client/client/src/main/java/io/avaje/http/client/BodyReader.java index e7faf3899..2bfe4a210 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/BodyReader.java +++ b/http-client/client/src/main/java/io/avaje/http/client/BodyReader.java @@ -1,7 +1,13 @@ package io.avaje.http.client; +/** + * Read content as a java type. + */ public interface BodyReader { + /** + * Read the content returning it as a java type. + */ T read(BodyContent content); } diff --git a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java index 668279ed1..4d60d4b67 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java +++ b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java @@ -75,6 +75,12 @@ public HttpClientRequest gzip(boolean gzip) { return this; } + @Override + public HttpClientRequest url(String baseUrl) { + url.url(baseUrl); + return this; + } + @Override public HttpClientRequest path(String path) { url.path(path); diff --git a/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java b/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java index 7fce52a2c..6d161281f 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java +++ b/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java @@ -8,11 +8,40 @@ /** * The HTTP client context that we use to build and process requests. + * + *

{@code
+ *
+ *   HttpClientContext ctx = HttpClientContext.newBuilder()
+ *       .withBaseUrl("http://localhost:8080")
+ *       .withBodyAdapter(new JacksonBodyAdapter(new ObjectMapper()))
+ *       .build();
+ *
+ *  HelloDto dto = ctx.request()
+ *       .path("hello")
+ *       .queryParam("name", "Rob")
+ *       .queryParam("say", "Ki ora")
+ *       .get()
+ *       .bean(HelloDto.class);
+ *
+ * }
*/ public interface HttpClientContext { /** * Return the builder to config and build the client context. + * + *
{@code
+   *
+   *   HttpClientContext ctx = HttpClientContext.newBuilder()
+   *       .withBaseUrl("http://localhost:8080")
+   *       .withBodyAdapter(new JacksonBodyAdapter(new ObjectMapper()))
+   *       .build();
+   *
+   *  HttpResponse res = ctx.request()
+   *       .path("hello")
+   *       .get().asString();
+   *
+   * }
*/ static HttpClientContext.Builder newBuilder() { return new DHttpClientContextBuilder(); @@ -31,6 +60,9 @@ static HttpClientContext.Builder newBuilder() { /** * Return the body adapter used by the client context. + *

+ * This is the body adapter used to convert request and response + * bodies to java types. For example using Jackson with JSON payloads. */ BodyAdapter converters(); @@ -70,9 +102,24 @@ static HttpClientContext.Builder newBuilder() { */ byte[] decodeContent(String encoding, byte[] content); - /** * Builds the HttpClientContext. + * + *

{@code
+   *
+   *   HttpClientContext ctx = HttpClientContext.newBuilder()
+   *       .withBaseUrl("http://localhost:8080")
+   *       .withBodyAdapter(new JacksonBodyAdapter(new ObjectMapper()))
+   *       .build();
+   *
+   *  HelloDto dto = ctx.request()
+   *       .path("hello")
+   *       .queryParam("name", "Rob")
+   *       .queryParam("say", "Ki ora")
+   *       .get()
+   *       .bean(HelloDto.class);
+   *
+   * }
*/ interface Builder { @@ -85,6 +132,8 @@ interface Builder { /** * Set the base URL to use for requests created from the context. + *

+ * Note that the base url can be replaced via {@link HttpClientRequest#url(String)}. */ Builder withBaseUrl(String baseUrl); @@ -139,6 +188,21 @@ interface Builder { /** * Build and return the context. + * + *

{@code
+     *
+     *   HttpClientContext ctx = HttpClientContext.newBuilder()
+     *       .withBaseUrl("http://localhost:8080")
+     *       .withBodyAdapter(new JacksonBodyAdapter(new ObjectMapper()))
+     *       .build();
+     *
+     *  HelloDto dto = ctx.request()
+     *       .path("hello")
+     *       .queryParam("say", "Ki ora")
+     *       .get()
+     *       .bean(HelloDto.class);
+     *
+     * }
*/ HttpClientContext build(); } diff --git a/http-client/client/src/main/java/io/avaje/http/client/HttpClientRequest.java b/http-client/client/src/main/java/io/avaje/http/client/HttpClientRequest.java index e860425b2..8e0820f2e 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/HttpClientRequest.java +++ b/http-client/client/src/main/java/io/avaje/http/client/HttpClientRequest.java @@ -13,6 +13,16 @@ * Largely wraps the standard JDK HttpRequest with additional * support for converting beans to body content and converting * beans from response content. + * + *
{@code
+ *
+ *  HelloDto dto = clientContext.request()
+ *       .path("hello").queryParam("name", "Rob").queryParam("say", "Ki ora")
+ *       .get().bean(HelloDto.class);
+ *
+ * }
+ * + * @see HttpClientContext */ public interface HttpClientRequest { @@ -42,6 +52,23 @@ public interface HttpClientRequest { */ HttpClientRequest gzip(boolean gzip); + /** + * Set the URL to use replacing the base URL. + *
{code
+   *
+   *  HttpResponse res = clientContext.request()
+   *       .url("http://127.0.0.1:8887")
+   *       .path("hello")
+   *       .get().asString();
+   *
+   * }
+ * + * @param url The url effectively replacing the base url. + * @return The request being built + * @see HttpClientContext.Builder#withBaseUrl(String) + */ + HttpClientRequest url(String url); + /** * Add a path segment to the URL. * diff --git a/http-client/client/src/main/java/io/avaje/http/client/UrlBuilder.java b/http-client/client/src/main/java/io/avaje/http/client/UrlBuilder.java index 57f7c3f9b..07d1a0cad 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/UrlBuilder.java +++ b/http-client/client/src/main/java/io/avaje/http/client/UrlBuilder.java @@ -3,21 +3,46 @@ import java.net.URLEncoder; import java.nio.charset.StandardCharsets; +/** + * Build a URL typically using a base url and adding path and query parameters. + */ public class UrlBuilder { private final StringBuilder buffer = new StringBuilder(100); private boolean hasParams; + /** + * Create with a base url. + */ public UrlBuilder(String base) { buffer.append(base); } + /** + * Set the url. This effectively replaces a base url. + */ + public UrlBuilder url(String url) { + buffer.delete(0, buffer.length()); + buffer.append(url); + return this; + } + + /** + * Add a path segment to the url. + *

+ * This includes appending a "/" prefix with the path. + */ public UrlBuilder path(String path) { buffer.append("/").append(path); return this; } + /** + * Append a query parameter. + *

+ * The name and value parameters are url encoded. + */ public UrlBuilder queryParam(String name, String value) { if (value != null) { buffer.append(hasParams ? '&' : '?'); @@ -27,6 +52,11 @@ public UrlBuilder queryParam(String name, String value) { return this; } + /** + * Append a matrix parameter. + *

+ * The name and value parameters are url encoded. + */ public UrlBuilder matrixParam(String name, String value) { if (value != null) { buffer.append(';').append(enc(name)).append("=").append(enc(value)); @@ -34,13 +64,18 @@ public UrlBuilder matrixParam(String name, String value) { return this; } + /** + * URL encode the value. + */ public static String enc(String val) { return URLEncoder.encode(val, StandardCharsets.UTF_8); } + /** + * Return the full URL. + */ public String build() { return buffer.toString(); } - } diff --git a/http-client/client/src/main/java/io/avaje/http/client/package-info.java b/http-client/client/src/main/java/io/avaje/http/client/package-info.java new file mode 100644 index 000000000..3ad25d449 --- /dev/null +++ b/http-client/client/src/main/java/io/avaje/http/client/package-info.java @@ -0,0 +1,22 @@ +/** + * Provides a HTTP client with support for adapting body content + * (like JSON) to java types. + *

+ * Uses the Java http client + * + *

{@code
+ *
+ *   HttpClientContext ctx = HttpClientContext.newBuilder()
+ *       .withBaseUrl("http://localhost:8080")
+ *       .withBodyAdapter(new JacksonBodyAdapter(new ObjectMapper()))
+ *       .build();
+ *
+ *  HelloDto dto = ctx.request()
+ *       .path("hello")
+ *       .queryParam("say", "Ki ora")
+ *       .get()
+ *       .bean(HelloDto.class);
+ *
+ * }
+ */ +package io.avaje.http.client; diff --git a/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java b/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java index 5c42d86c6..3881deb22 100644 --- a/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java +++ b/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java @@ -28,6 +28,18 @@ void get_helloMessage() { assertThat(hres.statusCode()).isEqualTo(200); } + @Test + void get_helloMessage_via_url() { + + final HttpResponse hres = clientContext.request() + .url("http://127.0.0.1:8887") + .path("hello").path("message") + .get().asString(); + + assertThat(hres.body()).contains("hello world"); + assertThat(hres.statusCode()).isEqualTo(200); + } + @Test void get_hello_returningListOfBeans() { diff --git a/http-client/client/src/test/java/io/avaje/http/client/UrlBuilderTest.java b/http-client/client/src/test/java/io/avaje/http/client/UrlBuilderTest.java index 684a7e0bb..2c44105cd 100644 --- a/http-client/client/src/test/java/io/avaje/http/client/UrlBuilderTest.java +++ b/http-client/client/src/test/java/io/avaje/http/client/UrlBuilderTest.java @@ -6,6 +6,12 @@ class UrlBuilderTest { + @Test + void url() { + String url = new UrlBuilder("https://foo").url("http://bar").path("bazz").build(); + assertThat(url).isEqualTo("http://bar/bazz"); + } + @Test void path() { assertThat(new UrlBuilder("https://foo").path("bar").build()).isEqualTo("https://foo/bar"); From 6355bf0c32b1db646c0fc0681b18476e77869869 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Thu, 22 Apr 2021 13:56:33 +1200 Subject: [PATCH 0064/1323] API - Refactor rename ResponseListener to RequestListener #6 --- .../io/avaje/http/client/DHttpClientContext.java | 14 +++++++------- .../http/client/DHttpClientContextBuilder.java | 8 ++++---- .../io/avaje/http/client/DHttpClientRequest.java | 4 ++-- .../io/avaje/http/client/HttpClientContext.java | 4 ++-- ...{ResponseListener.java => RequestListener.java} | 6 +++--- .../java/io/avaje/http/client/RequestLogger.java | 2 +- .../java/io/avaje/http/client/BaseWebTest.java | 2 +- 7 files changed, 20 insertions(+), 20 deletions(-) rename http-client/client/src/main/java/io/avaje/http/client/{ResponseListener.java => RequestListener.java} (91%) diff --git a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContext.java b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContext.java index cfc10bf29..fe51524af 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContext.java +++ b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContext.java @@ -15,14 +15,14 @@ class DHttpClientContext implements HttpClientContext { private final String baseUrl; private final Duration requestTimeout; private final BodyAdapter bodyAdapter; - private final ResponseListener responseListener; + private final RequestListener requestListener; - DHttpClientContext(HttpClient httpClient, String baseUrl, Duration requestTimeout, BodyAdapter bodyAdapter, ResponseListener responseListener) { + DHttpClientContext(HttpClient httpClient, String baseUrl, Duration requestTimeout, BodyAdapter bodyAdapter, RequestListener requestListener) { this.httpClient = httpClient; this.baseUrl = baseUrl; this.requestTimeout = requestTimeout; this.bodyAdapter = bodyAdapter; - this.responseListener = responseListener; + this.requestListener = requestListener; } @Override @@ -128,14 +128,14 @@ List readList(Class cls, BodyContent content) { void afterResponse(DHttpClientRequest request) { - if (responseListener != null) { - responseListener.response(request.listenerEvent()); + if (requestListener != null) { + requestListener.response(request.listenerEvent()); } } void afterResponseHandler(DHttpClientRequest request) { - if (responseListener != null) { - responseListener.response(request.listenerEvent()); + if (requestListener != null) { + requestListener.response(request.listenerEvent()); } } } diff --git a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContextBuilder.java b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContextBuilder.java index efaf6f277..cb8227a95 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContextBuilder.java +++ b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContextBuilder.java @@ -18,7 +18,7 @@ class DHttpClientContextBuilder implements HttpClientContext.Builder { private BodyAdapter bodyAdapter; - private ResponseListener responseListener; + private RequestListener requestListener; private CookieHandler cookieHandler = new CookieManager(); @@ -55,8 +55,8 @@ public HttpClientContext.Builder withBodyAdapter(BodyAdapter adapter) { } @Override - public HttpClientContext.Builder withResponseListener(ResponseListener responseListener) { - this.responseListener = responseListener; + public HttpClientContext.Builder withRequestListener(RequestListener requestListener) { + this.requestListener = requestListener; return this; } @@ -89,7 +89,7 @@ public HttpClientContext build() { if (client == null) { client = defaultClient(); } - return new DHttpClientContext(client, baseUrl, requestTimeout, bodyAdapter, responseListener); + return new DHttpClientContext(client, baseUrl, requestTimeout, bodyAdapter, requestListener); } private HttpClient defaultClient() { diff --git a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java index 4d60d4b67..a53007808 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java +++ b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java @@ -354,11 +354,11 @@ protected HttpRequest.Builder newRequest(String method, String url, HttpRequest. .method(method, body); } - ResponseListener.Event listenerEvent() { + RequestListener.Event listenerEvent() { return new ListenerEvent(); } - private class ListenerEvent implements ResponseListener.Event { + private class ListenerEvent implements RequestListener.Event { @Override public long responseTimeNanos() { diff --git a/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java b/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java index 6d161281f..3759ebf2d 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java +++ b/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java @@ -151,11 +151,11 @@ interface Builder { Builder withBodyAdapter(BodyAdapter adapter); /** - * Add a response listener. Note that {@link RequestLogger} is an + * Add a request listener. Note that {@link RequestLogger} is an * implementation for debug logging request/response headers and * content. */ - Builder withResponseListener(ResponseListener requestListener); + Builder withRequestListener(RequestListener requestListener); /** * Specify a cookie handler to use on the HttpClient. This would override the default cookie handler. diff --git a/http-client/client/src/main/java/io/avaje/http/client/ResponseListener.java b/http-client/client/src/main/java/io/avaje/http/client/RequestListener.java similarity index 91% rename from http-client/client/src/main/java/io/avaje/http/client/ResponseListener.java rename to http-client/client/src/main/java/io/avaje/http/client/RequestListener.java index b52327e0e..1a8c46971 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/ResponseListener.java +++ b/http-client/client/src/main/java/io/avaje/http/client/RequestListener.java @@ -7,10 +7,10 @@ /** * Listen to responses. *

- * {@link RequestLogger} is an implementation for debug logging the - * requests and responses. + * {@link RequestLogger} is an implementation for debug logging + * the requests and responses. */ -public interface ResponseListener { +public interface RequestListener { /** * Handle the response. diff --git a/http-client/client/src/main/java/io/avaje/http/client/RequestLogger.java b/http-client/client/src/main/java/io/avaje/http/client/RequestLogger.java index 05c8d31ce..d6c293410 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/RequestLogger.java +++ b/http-client/client/src/main/java/io/avaje/http/client/RequestLogger.java @@ -13,7 +13,7 @@ /** * Logs request and response details for debug logging purposes. */ -public class RequestLogger implements ResponseListener { +public class RequestLogger implements RequestListener { private static final Logger log = LoggerFactory.getLogger(RequestLogger.class); diff --git a/http-client/client/src/test/java/io/avaje/http/client/BaseWebTest.java b/http-client/client/src/test/java/io/avaje/http/client/BaseWebTest.java index 7e95e9c70..c2a8eb07b 100644 --- a/http-client/client/src/test/java/io/avaje/http/client/BaseWebTest.java +++ b/http-client/client/src/test/java/io/avaje/http/client/BaseWebTest.java @@ -26,7 +26,7 @@ public static void shutdown() { public static HttpClientContext client() { return HttpClientContext.newBuilder() .withBaseUrl(baseUrl) - .withResponseListener(new RequestLogger()) + .withRequestListener(new RequestLogger()) .withBodyAdapter(new JacksonBodyAdapter(new ObjectMapper())) // .withBodyAdapter(new GsonBodyAdapter(new Gson())) .build(); From 63e5c91b40ba85bdbee77c1ff7b31c3a7df4bf5e Mon Sep 17 00:00:00 2001 From: rbygrave Date: Thu, 22 Apr 2021 17:29:35 +1200 Subject: [PATCH 0065/1323] Merge afterResponse() and afterResponseHandler() --- .../io/avaje/http/client/DHttpClientContext.java | 7 ------- .../io/avaje/http/client/DHttpClientRequest.java | 9 ++++----- .../io/avaje/http/client/HelloControllerTest.java | 14 +++++++++++++- 3 files changed, 17 insertions(+), 13 deletions(-) diff --git a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContext.java b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContext.java index fe51524af..03c36251b 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContext.java +++ b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContext.java @@ -126,16 +126,9 @@ List readList(Class cls, BodyContent content) { return bodyAdapter.listReader(cls).read(content); } - void afterResponse(DHttpClientRequest request) { if (requestListener != null) { requestListener.response(request.listenerEvent()); } } - - void afterResponseHandler(DHttpClientRequest request) { - if (requestListener != null) { - requestListener.response(request.listenerEvent()); - } - } } diff --git a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java index a53007808..69b1482ce 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java +++ b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java @@ -250,7 +250,6 @@ private void readResponseContent() { this.httpResponse = response; context.check(response); encodedResponseBody = context.readContent(response); - context.afterResponse(this); } @Override @@ -279,11 +278,11 @@ public List list(Class cls) { @Override public HttpResponse withResponseHandler(HttpResponse.BodyHandler responseHandler) { - long startNanos = System.nanoTime(); + final long startNanos = System.nanoTime(); final HttpResponse response = context.send(httpRequest, responseHandler); - this.requestTimeNanos = System.nanoTime() - startNanos; - this.httpResponse = response; - context.afterResponseHandler(this); + requestTimeNanos = System.nanoTime() - startNanos; + httpResponse = response; + context.afterResponse(this); return response; } diff --git a/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java b/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java index 3881deb22..8b5a035ea 100644 --- a/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java +++ b/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java @@ -137,8 +137,20 @@ void postForm_returningBean() { } @Test - void postForm_asVoid_invokesValidation_expect_badRequest_extractError() { + void postForm_asVoid_validResponse() { + HttpResponse res = clientContext.request() + .path("hello/saveform") + .formParam("name", "baz") + .formParam("email", "user@foo.com") + .formParam("url", "http://foo") + .post() + .asVoid(); + assertEquals(201, res.statusCode()); + } + + @Test + void postForm_asVoid_invokesValidation_expect_badRequest_extractError() { try { clientContext.request() .path("hello/saveform") From 7b5ab758aad41f6a675ccbddde4b98c209aa8478 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Fri, 23 Apr 2021 08:51:21 +1200 Subject: [PATCH 0066/1323] #8 - ENH: Add in support for Authorization bearer token - AuthTokenProvider --- .../java/io/avaje/http/client/AuthToken.java | 55 +++++++++++++ .../avaje/http/client/AuthTokenProvider.java | 40 +++++++++ .../avaje/http/client/DHttpClientContext.java | 32 +++++++- .../client/DHttpClientContextBuilder.java | 32 +++++++- .../avaje/http/client/DHttpClientRequest.java | 21 ++++- .../http/client/DRequestInterceptors.java | 37 +++++++++ .../avaje/http/client/HttpClientContext.java | 17 ++++ .../avaje/http/client/HttpClientRequest.java | 8 ++ .../avaje/http/client/RequestIntercept.java | 22 +++++ .../io/avaje/http/client/AuthTokenTest.java | 82 +++++++++++++++++++ .../http/client/DHttpClientContextTest.java | 2 +- .../http/client/DRequestInterceptorsTest.java | 51 ++++++++++++ 12 files changed, 392 insertions(+), 7 deletions(-) create mode 100644 http-client/client/src/main/java/io/avaje/http/client/AuthToken.java create mode 100644 http-client/client/src/main/java/io/avaje/http/client/AuthTokenProvider.java create mode 100644 http-client/client/src/main/java/io/avaje/http/client/DRequestInterceptors.java create mode 100644 http-client/client/src/main/java/io/avaje/http/client/RequestIntercept.java create mode 100644 http-client/client/src/test/java/io/avaje/http/client/AuthTokenTest.java create mode 100644 http-client/client/src/test/java/io/avaje/http/client/DRequestInterceptorsTest.java diff --git a/http-client/client/src/main/java/io/avaje/http/client/AuthToken.java b/http-client/client/src/main/java/io/avaje/http/client/AuthToken.java new file mode 100644 index 000000000..7ff198273 --- /dev/null +++ b/http-client/client/src/main/java/io/avaje/http/client/AuthToken.java @@ -0,0 +1,55 @@ +package io.avaje.http.client; + +import java.time.Instant; + +/** + * Represents an Authorization Bearer token that can be held on the context. + *

+ * Typically the token will be valid for a period and then expire. + */ +public interface AuthToken { + + /** + * Return the Authorization bearer token. + */ + String token(); + + /** + * Return true if the token has expired or is no longer valid. + */ + boolean isExpired(); + + /** + * Create an return a AuthToken with the given token and time it is valid until. + */ + static AuthToken of(String token, Instant validUntil) { + return new Basic(token, validUntil); + } + + /** + * Standard AuthToken implementation. + */ + class Basic implements AuthToken { + + private final String token; + private final Instant validUntil; + + /** + * Create with token and valid until time. + */ + public Basic(String token, Instant validUntil) { + this.token = token; + this.validUntil = validUntil; + } + + @Override + public String token() { + return token; + } + + @Override + public boolean isExpired() { + return Instant.now().isAfter(validUntil); + } + } +} diff --git a/http-client/client/src/main/java/io/avaje/http/client/AuthTokenProvider.java b/http-client/client/src/main/java/io/avaje/http/client/AuthTokenProvider.java new file mode 100644 index 000000000..9dcc51181 --- /dev/null +++ b/http-client/client/src/main/java/io/avaje/http/client/AuthTokenProvider.java @@ -0,0 +1,40 @@ +package io.avaje.http.client; + +/** + * Use to obtain an Authorization bearer token that is expected to be used. + * + *

{@code
+ *
+ *   class MyAuthTokenProvider implements AuthTokenProducer {
+ *
+ *     @Override
+ *     public AuthToken obtainToken(HttpClientRequest tokenRequest) {
+ *
+ *       MyTokenResponse tokenResponse = tokenRequest
+ *         .url("https://foo/auth/token")
+ *         .header("content-type", "application/json")
+ *         .body(authRequestAsJson())
+ *         .post()
+ *         .bean(MyTokenResponse.class);
+ *
+ *       String token = tokenResponse.getToken();
+ *       long expiresSecs = tokenResponse.getExpiresInSecs();
+ *
+ *       Instant validUntil = Instant.now().plusSeconds(expiresSecs).minusSeconds(60);
+ *
+ *       return AuthToken.of(token, validUntil);
+ *     }
+ *   }
+ *
+ * }
+ */ +public interface AuthTokenProvider { + + /** + * Obtain a new Authorization token. + * + * @param tokenRequest A new request to obtain an Authorisation token + */ + AuthToken obtainToken(HttpClientRequest tokenRequest); + +} diff --git a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContext.java b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContext.java index 03c36251b..3b42df7dd 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContext.java +++ b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContext.java @@ -8,6 +8,7 @@ import java.time.Duration; import java.util.List; import java.util.Map; +import java.util.concurrent.atomic.AtomicReference; class DHttpClientContext implements HttpClientContext { @@ -16,13 +17,20 @@ class DHttpClientContext implements HttpClientContext { private final Duration requestTimeout; private final BodyAdapter bodyAdapter; private final RequestListener requestListener; + private final RequestIntercept requestIntercept; + private final boolean withAuthToken; + private final AuthTokenProvider authTokenProvider; + private final AtomicReference tokenRef = new AtomicReference<>(); - DHttpClientContext(HttpClient httpClient, String baseUrl, Duration requestTimeout, BodyAdapter bodyAdapter, RequestListener requestListener) { + DHttpClientContext(HttpClient httpClient, String baseUrl, Duration requestTimeout, BodyAdapter bodyAdapter, RequestListener requestListener, AuthTokenProvider authTokenProvider, RequestIntercept intercept) { this.httpClient = httpClient; this.baseUrl = baseUrl; this.requestTimeout = requestTimeout; this.bodyAdapter = bodyAdapter; this.requestListener = requestListener; + this.authTokenProvider = authTokenProvider; + this.withAuthToken = authTokenProvider != null; + this.requestIntercept = intercept; } @Override @@ -130,5 +138,27 @@ void afterResponse(DHttpClientRequest request) { if (requestListener != null) { requestListener.response(request.listenerEvent()); } + if (requestIntercept != null) { + requestIntercept.afterResponse(request.response(), request); + } + } + + void beforeRequest(DHttpClientRequest request) { + if (withAuthToken && !request.isSkipAuthToken()) { + request.header("Authorization", "Bearer " + authToken()); + } + if (requestIntercept != null) { + requestIntercept.beforeRequest(request); + } } + + private String authToken() { + AuthToken authToken = tokenRef.get(); + if (authToken == null || authToken.isExpired()) { + authToken = authTokenProvider.obtainToken(request().skipAuthToken()); + tokenRef.set(authToken); + } + return authToken.token(); + } + } diff --git a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContextBuilder.java b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContextBuilder.java index cb8227a95..295927fe9 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContextBuilder.java +++ b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContextBuilder.java @@ -4,6 +4,8 @@ import java.net.CookieManager; import java.net.http.HttpClient; import java.time.Duration; +import java.util.ArrayList; +import java.util.List; import java.util.concurrent.Executor; import static java.util.Objects.requireNonNull; @@ -27,6 +29,10 @@ class DHttpClientContextBuilder implements HttpClientContext.Builder { private HttpClient.Version version; private Executor executor; + private AuthTokenProvider authTokenProvider; + + private final List interceptors = new ArrayList<>(); + DHttpClientContextBuilder() { } @@ -60,6 +66,18 @@ public HttpClientContext.Builder withRequestListener(RequestListener requestList return this; } + @Override + public HttpClientContext.Builder withRequestIntercept(RequestIntercept requestIntercept) { + this.interceptors.add(requestIntercept); + return this; + } + + @Override + public HttpClientContext.Builder withAuthTokenProvider(AuthTokenProvider authTokenProvider) { + this.authTokenProvider = authTokenProvider; + return this; + } + @Override public HttpClientContext.Builder withCookieHandler(CookieHandler cookieHandler) { this.cookieHandler = cookieHandler; @@ -71,11 +89,13 @@ public HttpClientContext.Builder withRedirect(HttpClient.Redirect redirect) { this.redirect = redirect; return this; } + @Override public HttpClientContext.Builder withVersion(HttpClient.Version version) { this.version = version; return this; } + @Override public HttpClientContext.Builder withExecutor(Executor executor) { this.executor = executor; @@ -89,7 +109,17 @@ public HttpClientContext build() { if (client == null) { client = defaultClient(); } - return new DHttpClientContext(client, baseUrl, requestTimeout, bodyAdapter, requestListener); + return new DHttpClientContext(client, baseUrl, requestTimeout, bodyAdapter, requestListener, authTokenProvider, buildIntercept()); + } + + private RequestIntercept buildIntercept() { + if (interceptors.isEmpty()) { + return null; + } else if (interceptors.size() == 1) { + return interceptors.get(0); + } else { + return new DRequestInterceptors(interceptors); + } } private HttpClient defaultClient() { diff --git a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java index 69b1482ce..70515f100 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java +++ b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java @@ -47,6 +47,7 @@ class DHttpClientRequest implements HttpClientRequest, HttpClientResponse { private HttpResponse httpResponse; private BodyContent encodedResponseBody; private boolean loggableResponseBody; + private boolean skipAuthToken; public DHttpClientRequest(DHttpClientContext context, Duration requestTimeout) { this.context = context; @@ -54,6 +55,12 @@ public DHttpClientRequest(DHttpClientContext context, Duration requestTimeout) { this.url = context.url(); } + @Override + public HttpClientRequest skipAuthToken() { + this.skipAuthToken = true; + return this; + } + @Override public HttpClientRequest requestTimeout(Duration requestTimeout) { this.requestTimeout = requestTimeout; @@ -220,28 +227,24 @@ private void addHeaders() { public HttpClientResponse get() { httpRequest = newGet(url.build()); - addHeaders(); return this; } @Override public HttpClientResponse delete() { httpRequest = newDelete(url.build()); - addHeaders(); return this; } @Override public HttpClientResponse post() { httpRequest = newPost(url.build(), body()); - addHeaders(); return this; } @Override public HttpClientResponse put() { httpRequest = newPut(url.build(), body()); - addHeaders(); return this; } @@ -278,6 +281,8 @@ public List list(Class cls) { @Override public HttpResponse withResponseHandler(HttpResponse.BodyHandler responseHandler) { + context.beforeRequest(this); + addHeaders(); final long startNanos = System.nanoTime(); final HttpResponse response = context.send(httpRequest, responseHandler); requestTimeNanos = System.nanoTime() - startNanos; @@ -357,6 +362,14 @@ RequestListener.Event listenerEvent() { return new ListenerEvent(); } + HttpResponse response() { + return httpResponse; + } + + boolean isSkipAuthToken() { + return skipAuthToken; + } + private class ListenerEvent implements RequestListener.Event { @Override diff --git a/http-client/client/src/main/java/io/avaje/http/client/DRequestInterceptors.java b/http-client/client/src/main/java/io/avaje/http/client/DRequestInterceptors.java new file mode 100644 index 000000000..3ae70aef5 --- /dev/null +++ b/http-client/client/src/main/java/io/avaje/http/client/DRequestInterceptors.java @@ -0,0 +1,37 @@ +package io.avaje.http.client; + +import java.net.http.HttpResponse; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * Processing of multiple RequestIntercept. + *

+ * Noting that afterResponse interceptors are processed in reverse order. + */ +class DRequestInterceptors implements RequestIntercept { + + private final List before; + private final List after; + + DRequestInterceptors(List interceptors) { + this.before = new ArrayList<>(interceptors); + Collections.reverse(interceptors); + this.after = new ArrayList<>(interceptors); + } + + @Override + public void beforeRequest(HttpClientRequest request) { + for (RequestIntercept interceptor : before) { + interceptor.beforeRequest(request); + } + } + + @Override + public void afterResponse(HttpResponse response, HttpClientRequest request) { + for (RequestIntercept interceptor : after) { + interceptor.afterResponse(response, request); + } + } +} diff --git a/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java b/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java index 3759ebf2d..2f21dd914 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java +++ b/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java @@ -157,6 +157,23 @@ interface Builder { */ Builder withRequestListener(RequestListener requestListener); + /** + * Add a request interceptor. + */ + Builder withRequestIntercept(RequestIntercept requestIntercept); + + /** + * Add a Authorization token provider. + *

+ * When set all requests are expected to use a Authorization Bearer token + * unless they are marked via {@link HttpClientRequest#skipAuthToken()}. + *

+ * The AuthTokenProvider obtains a new token typically with an expiry. This + * is automatically called as needed and the Authorization Bearer header set + * on all requests (not marked with skipAuthToken()). + */ + Builder withAuthTokenProvider(AuthTokenProvider authTokenProvider); + /** * Specify a cookie handler to use on the HttpClient. This would override the default cookie handler. * diff --git a/http-client/client/src/main/java/io/avaje/http/client/HttpClientRequest.java b/http-client/client/src/main/java/io/avaje/http/client/HttpClientRequest.java index 8e0820f2e..24f8bba69 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/HttpClientRequest.java +++ b/http-client/client/src/main/java/io/avaje/http/client/HttpClientRequest.java @@ -26,6 +26,14 @@ */ public interface HttpClientRequest { + /** + * For this request skip using an Authorization token. + *

+ * This is automatically set on the request passed to + * {@link AuthTokenProvider#obtainToken(HttpClientRequest)}. + */ + HttpClientRequest skipAuthToken(); + /** * Set the request timeout to use for this request. When not set the default * request timeout will be used. diff --git a/http-client/client/src/main/java/io/avaje/http/client/RequestIntercept.java b/http-client/client/src/main/java/io/avaje/http/client/RequestIntercept.java new file mode 100644 index 000000000..ed487730a --- /dev/null +++ b/http-client/client/src/main/java/io/avaje/http/client/RequestIntercept.java @@ -0,0 +1,22 @@ +package io.avaje.http.client; + +import java.net.http.HttpResponse; + +/** + * Interceptor for before the request is made and after the response is obtained. + */ +public interface RequestIntercept { + + /** + * Before the request has been made. + *

+ * Typically we can add headers or modify the request prior to it being sent. + */ + void beforeRequest(HttpClientRequest request); + + /** + * After the response has been received. + */ + void afterResponse(HttpResponse response, HttpClientRequest request); + +} diff --git a/http-client/client/src/test/java/io/avaje/http/client/AuthTokenTest.java b/http-client/client/src/test/java/io/avaje/http/client/AuthTokenTest.java new file mode 100644 index 000000000..7a5f09925 --- /dev/null +++ b/http-client/client/src/test/java/io/avaje/http/client/AuthTokenTest.java @@ -0,0 +1,82 @@ +package io.avaje.http.client; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; + +import java.net.http.HttpResponse; +import java.time.Instant; + +public class AuthTokenTest { + + private static final ObjectMapper objectMapper = init(); + + private static ObjectMapper init() { + return new ObjectMapper() + //.registerModule(new JavaTimeModule()) + .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) + .configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false) + .configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false) + .configure(SerializationFeature.INDENT_OUTPUT, true) + .setSerializationInclusion(JsonInclude.Include.NON_NULL); + } + + static class MyAuthTokenProvider implements AuthTokenProvider { + + @Override + public AuthToken obtainToken(HttpClientRequest tokenRequest) { + AuthTokenResponse res = tokenRequest + .url("https://foo/v2/token") + .header("content-type", "application/json") + .body(authRequestAsJson()) + .post() + .bean(AuthTokenResponse.class); + + Instant validUntil = Instant.now().plusSeconds(res.expires_in).minusSeconds(60); + + return AuthToken.of(res.access_token, validUntil); + } + } + + @Disabled + @Test + void sendEmail() { + + HttpClientContext ctx = HttpClientContext.newBuilder() + .withBaseUrl("https://foo") + .withBodyAdapter(new JacksonBodyAdapter(objectMapper)) + .withRequestListener(new RequestLogger()) + .withAuthTokenProvider(new MyAuthTokenProvider()) + .build(); + + String path = "bar"; + + HttpResponse res = ctx.request() + .path(path) + .header("Content-Type", "application/json") + //.body(payload) + .post() + .asString(); + + HttpResponse res2 = ctx.request() + .path(path) + .header("Content-Type", "application/json") + //.body(payload) + .post() + .asString(); + + } + + private static String authRequestAsJson() { + return null; + } + + static public class AuthTokenResponse { + public String access_token; + public Long expires_in; + // ... + } +} diff --git a/http-client/client/src/test/java/io/avaje/http/client/DHttpClientContextTest.java b/http-client/client/src/test/java/io/avaje/http/client/DHttpClientContextTest.java index 5405dd270..bfa0f08a5 100644 --- a/http-client/client/src/test/java/io/avaje/http/client/DHttpClientContextTest.java +++ b/http-client/client/src/test/java/io/avaje/http/client/DHttpClientContextTest.java @@ -9,7 +9,7 @@ class DHttpClientContextTest { - private final DHttpClientContext context = new DHttpClientContext(null, null, null, null, null); + private final DHttpClientContext context = new DHttpClientContext(null, null, null, null, null, null, null); @Test void gzip_gzipDecode() { diff --git a/http-client/client/src/test/java/io/avaje/http/client/DRequestInterceptorsTest.java b/http-client/client/src/test/java/io/avaje/http/client/DRequestInterceptorsTest.java new file mode 100644 index 000000000..06b60c9f8 --- /dev/null +++ b/http-client/client/src/test/java/io/avaje/http/client/DRequestInterceptorsTest.java @@ -0,0 +1,51 @@ +package io.avaje.http.client; + +import org.junit.jupiter.api.Test; + +import java.net.http.HttpResponse; + +import static java.util.Arrays.asList; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; + +class DRequestInterceptorsTest { + + private StringBuilder buffer = new StringBuilder(); + + @Test + void intercept_reverse_after() { + + DRequestInterceptors interceptors = new DRequestInterceptors(asList(new One(), new Two())); + + interceptors.beforeRequest(mock(HttpClientRequest.class)); + interceptors.afterResponse(mock(HttpResponse.class), mock(HttpClientRequest.class)); + + assertThat(buffer.toString()).isEqualTo("oneBefore|twoBefore|twoAfter|oneAfter|"); + } + + private class One implements RequestIntercept { + + @Override + public void beforeRequest(HttpClientRequest request) { + buffer.append("oneBefore|"); + } + + @Override + public void afterResponse(HttpResponse response, HttpClientRequest request) { + buffer.append("oneAfter|"); + } + } + + private class Two implements RequestIntercept { + + @Override + public void beforeRequest(HttpClientRequest request) { + buffer.append("twoBefore|"); + } + + @Override + public void afterResponse(HttpResponse response, HttpClientRequest request) { + buffer.append("twoAfter|"); + } + } +} From 2cb62fe7661c8dd378eb09cd12a1afd66219d2f0 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Fri, 23 Apr 2021 08:53:48 +1200 Subject: [PATCH 0067/1323] Prepare client release version --- http-client/client/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/http-client/client/pom.xml b/http-client/client/pom.xml index 518da1375..6e948d249 100644 --- a/http-client/client/pom.xml +++ b/http-client/client/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-client - 1.1 + 1.2-SNAPSHOT scm:git:git@github.com:avaje/avaje-http-client.git From 4f37c395ea51cc6135efcf29168102fccd9acbd6 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Fri, 23 Apr 2021 08:54:39 +1200 Subject: [PATCH 0068/1323] [maven-release-plugin] prepare release avaje-http-client-1.2 --- http-client/client/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/http-client/client/pom.xml b/http-client/client/pom.xml index 6e948d249..617c43c56 100644 --- a/http-client/client/pom.xml +++ b/http-client/client/pom.xml @@ -9,11 +9,11 @@ io.avaje avaje-http-client - 1.2-SNAPSHOT + 1.2 scm:git:git@github.com:avaje/avaje-http-client.git - HEAD + avaje-http-client-1.2 From 92fec61e3312890161f5fbc238195316e22f845c Mon Sep 17 00:00:00 2001 From: rbygrave Date: Fri, 23 Apr 2021 08:54:47 +1200 Subject: [PATCH 0069/1323] [maven-release-plugin] prepare for next development iteration --- http-client/client/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/http-client/client/pom.xml b/http-client/client/pom.xml index 617c43c56..1fc519ee8 100644 --- a/http-client/client/pom.xml +++ b/http-client/client/pom.xml @@ -9,11 +9,11 @@ io.avaje avaje-http-client - 1.2 + 1.3-SNAPSHOT scm:git:git@github.com:avaje/avaje-http-client.git - avaje-http-client-1.2 + HEAD From 1808f615ec6b80eb0a14625cad16ed10a4795fcc Mon Sep 17 00:00:00 2001 From: rbygrave Date: Fri, 23 Apr 2021 08:58:12 +1200 Subject: [PATCH 0070/1323] Bump release version to 1.2 --- http-client/gson-adapter/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/http-client/gson-adapter/pom.xml b/http-client/gson-adapter/pom.xml index f7a0d6a1d..d564c905f 100644 --- a/http-client/gson-adapter/pom.xml +++ b/http-client/gson-adapter/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-client-gson - 1.1 + 1.2 scm:git:git@github.com:avaje/avaje-http-client.git @@ -27,7 +27,7 @@ io.avaje avaje-http-client - 1.0 + 1.2 provided From 0759ce3735c7774e55af2bc01bd1ba06da144c51 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Fri, 23 Apr 2021 09:07:09 +1200 Subject: [PATCH 0071/1323] Update docs and test module dependencies --- http-client/README.md | 47 ++++++++++++++++++- http-client/test/pom.xml | 4 +- .../test/java/example/github/GithubTest.java | 2 +- 3 files changed, 48 insertions(+), 5 deletions(-) diff --git a/http-client/README.md b/http-client/README.md index 26fd10e58..984d5a6f8 100644 --- a/http-client/README.md +++ b/http-client/README.md @@ -14,7 +14,7 @@ A light weight wrapper to the JDK 11+ Java Http Client io.avaje avaje-http-client - 1.0 + 1.2 ``` @@ -27,7 +27,7 @@ Create a HttpClientContext with a baseUrl, Jackson or Gson based JSON public HttpClientContext client() { return HttpClientContext.newBuilder() .withBaseUrl(baseUrl) - .withResponseListener(new RequestLogger()) + .withRequestListener(new RequestLogger()) .withBodyAdapter(new JacksonBodyAdapter(new ObjectMapper())) // .withBodyAdapter(new GsonBodyAdapter(new Gson())) .build(); @@ -132,3 +132,46 @@ assertThat(res.statusCode()).isEqualTo(201); ``` ## Currently NO support for POSTing multipart-form + +## Auth token + +Built in support for obtaining and setting an Authorization token. + +### 1. Implement AuthTokenProvider + +```java + + class MyAuthTokenProvider implements AuthTokenProvider { + + @Override + public AuthToken obtainToken(HttpClientRequest tokenRequest) { + AuthTokenResponse res = tokenRequest + .url("https://foo/v2/token") + .header("content-type", "application/json") + .body(authRequestAsJson()) + .post() + .bean(AuthTokenResponse.class); + + Instant validUntil = Instant.now().plusSeconds(res.expires_in).minusSeconds(60); + + return AuthToken.of(res.access_token, validUntil); + } + } +``` + +### 2. Register with HttpClientContext + +```java + HttpClientContext ctx = HttpClientContext.newBuilder() + .withBaseUrl("https://foo") + .withBodyAdapter(new JacksonBodyAdapter(objectMapper)) + .withRequestListener(new RequestLogger()) + .withAuthTokenProvider(new MyAuthTokenProvider()) + tests diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index 551c9f007..42834e0d4 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -19,7 +19,7 @@ - + @@ -32,7 +32,7 @@ io.avaje avaje-http-client - 1.4-SNAPSHOT + 1.4 @@ -44,7 +44,7 @@ io.avaje avaje-http-api - 1.4-SNAPSHOT + 1.5-SNAPSHOT @@ -100,7 +100,7 @@ io.avaje avaje-http-generator-client - 1.4-SNAPSHOT + 1.5-SNAPSHOT diff --git a/tests/test-helidon/pom.xml b/tests/test-helidon/pom.xml index 944ac7333..2d9364763 100644 --- a/tests/test-helidon/pom.xml +++ b/tests/test-helidon/pom.xml @@ -17,7 +17,7 @@ org.example.Main 2.2.2 - 1.4-SNAPSHOT + 1.5-SNAPSHOT @@ -36,17 +36,17 @@ io.avaje avaje-http-api - 1.2 + 1.4 io.avaje avaje-inject - 4.1 + 6.0.RC4 io.avaje avaje-inject-generator - 4.1 + 6.0.RC4 provided @@ -115,7 +115,7 @@ io.avaje avaje-http-client - 1.0 + 1.4 test diff --git a/tests/test-helidon/src/test/java/org/example/BaseWebTest.java b/tests/test-helidon/src/test/java/org/example/BaseWebTest.java index 8821963be..3a62075c9 100644 --- a/tests/test-helidon/src/test/java/org/example/BaseWebTest.java +++ b/tests/test-helidon/src/test/java/org/example/BaseWebTest.java @@ -28,7 +28,7 @@ public static void shutdown() { public static HttpClientContext client() { return HttpClientContext.newBuilder() .withBaseUrl(baseUrl) - .withResponseListener(new RequestLogger()) + .withRequestListener(new RequestLogger()) .withBodyAdapter(new JacksonBodyAdapter(new ObjectMapper())) //.with(httpClient) .build(); diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 634cd6942..fe65f57ec 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -20,7 +20,7 @@ 2.0.8 1.3.71 2.12.3 - 1.4-SNAPSHOT + 1.5-SNAPSHOT @@ -52,19 +52,19 @@ io.avaje avaje-inject - 4.1 + 6.0.RC4 io.avaje avaje-http-api - 1.2 + 1.4 io.avaje avaje-http-hibernate-validator - 2.0 + 2.5 @@ -78,7 +78,7 @@ io.avaje avaje-inject-generator - 4.1 + 6.0.RC4 provided @@ -108,7 +108,7 @@ io.avaje avaje-http-client - 1.0 + 1.4 test diff --git a/tests/test-javalin/src/test/java/org/example/myapp/BaseWebTest.java b/tests/test-javalin/src/test/java/org/example/myapp/BaseWebTest.java index 477401832..020a5e4a6 100644 --- a/tests/test-javalin/src/test/java/org/example/myapp/BaseWebTest.java +++ b/tests/test-javalin/src/test/java/org/example/myapp/BaseWebTest.java @@ -28,7 +28,7 @@ public static void shutdown() { public static HttpClientContext client() { return HttpClientContext.newBuilder() .withBaseUrl(baseUrl) - .withResponseListener(new RequestLogger()) + .withRequestListener(new RequestLogger()) .withBodyAdapter(new JacksonBodyAdapter(new ObjectMapper())) //.with(httpClient) .build(); diff --git a/tests/test-javalin/src/test/java/org/example/myapp/HelloControllerTest.java b/tests/test-javalin/src/test/java/org/example/myapp/HelloControllerTest.java index 352353805..9395f7f39 100644 --- a/tests/test-javalin/src/test/java/org/example/myapp/HelloControllerTest.java +++ b/tests/test-javalin/src/test/java/org/example/myapp/HelloControllerTest.java @@ -36,7 +36,7 @@ class HelloControllerTest extends BaseWebTest { this.clientContext = HttpClientContext.newBuilder() .withBaseUrl(baseUrl) - .withResponseListener(new RequestLogger()) + .withRequestListener(new RequestLogger()) .withBodyAdapter(new JacksonBodyAdapter(new ObjectMapper())) .with(httpClient) .build(); diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 2f14760c3..d4df6e02e 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -19,8 +19,8 @@ 1.3 2.0.8 2.12.3 - 6.0.RC3 - 1.4-SNAPSHOT + 6.0.RC4 + 1.5-SNAPSHOT @@ -95,7 +95,7 @@ io.avaje avaje-http-client - 1.1 + 1.4 test diff --git a/tests/test-spark/pom.xml b/tests/test-spark/pom.xml index 70a1680c7..b07e8bfb3 100644 --- a/tests/test-spark/pom.xml +++ b/tests/test-spark/pom.xml @@ -17,7 +17,7 @@ org.example.myapp.Main 2.0.8 - 1.4-SNAPSHOT + 1.5-SNAPSHOT @@ -43,19 +43,19 @@ io.avaje avaje-inject - 4.1 + 6.0.RC4 io.avaje avaje-http-api - 1.2 + 1.4 io.avaje avaje-http-hibernate-validator - 2.0 + 2.5 @@ -69,14 +69,14 @@ io.avaje avaje-inject-generator - 4.1 + 6.0.RC4 provided io.avaje avaje-http-spark-generator - 1.4-SNAPSHOT + 1.5-SNAPSHOT provided @@ -93,7 +93,7 @@ io.avaje avaje-http-client - 1.0 + 1.4 test From 35cedfef52dea50b2a5db29e24ec049e723fdea8 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Tue, 1 Jun 2021 16:30:31 +1200 Subject: [PATCH 0091/1323] #15 - Add PATCH, HEAD, TRACE verbs, bump to upper case VERB methods and deprecate the existing lower case one --- .../avaje/http/client/DHttpClientRequest.java | 71 ++++++++--- .../avaje/http/client/HttpClientRequest.java | 63 +++++++++- .../java/io/avaje/http/client/VerbTest.java | 115 ++++++++++++++++++ .../test/java/org/example/webserver/App.java | 11 +- 4 files changed, 233 insertions(+), 27 deletions(-) create mode 100644 http-client/client/src/test/java/io/avaje/http/client/VerbTest.java diff --git a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java index a1fa3bb78..7e52a5f66 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java +++ b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java @@ -22,6 +22,10 @@ class DHttpClientRequest implements HttpClientRequest, HttpClientResponse { private static final String CONTENT_TYPE = "Content-Type"; private static final String CONTENT_ENCODING = "Content-Encoding"; + private static final String VERB_DELETE = "DELETE"; + private static final String VERB_HEAD = "HEAD"; + private static final String VERB_PATCH = "PATCH"; + private static final String VERB_TRACE = "TRACE"; private final DHttpClientContext context; private final UrlBuilder url; @@ -211,7 +215,7 @@ private HttpRequest.BodyPublisher body() { } else if (formParams != null) { return bodyFromForm(); } else { - return null; + return HttpRequest.BodyPublishers.noBody(); } } @@ -264,29 +268,47 @@ private void addHeaders() { } } - public HttpClientResponse get() { + @Override + public HttpClientResponse HEAD() { + httpRequest = newHead(url.build()); + return this; + } + + public HttpClientResponse GET() { httpRequest = newGet(url.build()); return this; } @Override - public HttpClientResponse delete() { - httpRequest = newDelete(url.build()); + public HttpClientResponse DELETE() { + httpRequest = newDelete(url.build(), body()); return this; } @Override - public HttpClientResponse post() { + public HttpClientResponse POST() { httpRequest = newPost(url.build(), body()); return this; } @Override - public HttpClientResponse put() { + public HttpClientResponse PUT() { httpRequest = newPut(url.build(), body()); return this; } + @Override + public HttpClientResponse PATCH() { + httpRequest = newPatch(url.build(), body()); + return this; + } + + @Override + public HttpClientResponse TRACE() { + httpRequest = newTrace(url.build(), body()); + return this; + } + private void readResponseContent() { final HttpResponse response = asByteArray(); this.httpResponse = response; @@ -368,30 +390,39 @@ public HttpResponse> asLines() { return withResponseHandler(HttpResponse.BodyHandlers.ofLines()); } - protected HttpRequest.Builder newGet(String url) { + private HttpRequest.Builder newReq(String url) { return HttpRequest.newBuilder() .uri(URI.create(url)) - .timeout(requestTimeout) - .GET(); + .timeout(requestTimeout); } - protected HttpRequest.Builder newDelete(String url) { - return HttpRequest.newBuilder() - .uri(URI.create(url)) - .timeout(requestTimeout) - .DELETE(); + private HttpRequest.Builder newHead(String url) { + return newRequest(VERB_HEAD, url, HttpRequest.BodyPublishers.noBody()); + } + + private HttpRequest.Builder newGet(String url) { + return newReq(url).GET(); + } + + private HttpRequest.Builder newPost(String url, HttpRequest.BodyPublisher body) { + return newReq(url).POST(body); + } + + private HttpRequest.Builder newPut(String url, HttpRequest.BodyPublisher body) { + return newReq(url).PUT(body); } - public HttpRequest.Builder newPost(String url, HttpRequest.BodyPublisher body) { - return newRequest("POST", url, body); + private HttpRequest.Builder newPatch(String url, HttpRequest.BodyPublisher body) { + return newRequest(VERB_PATCH, url, body); } - public HttpRequest.Builder newPut(String url, HttpRequest.BodyPublisher body) { - return newRequest("PUT", url, body); + private HttpRequest.Builder newDelete(String url, HttpRequest.BodyPublisher body) { + // allow DELETE to have a body + return newRequest(VERB_DELETE, url, body); } - public HttpRequest.Builder newPatch(String url, HttpRequest.BodyPublisher body) { - return newRequest("PATCH", url, body); + private HttpRequest.Builder newTrace(String url, HttpRequest.BodyPublisher body) { + return newRequest(VERB_TRACE, url, body); } protected HttpRequest.Builder newRequest(String method, String url, HttpRequest.BodyPublisher body) { diff --git a/http-client/client/src/main/java/io/avaje/http/client/HttpClientRequest.java b/http-client/client/src/main/java/io/avaje/http/client/HttpClientRequest.java index 8140258c7..157eb0370 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/HttpClientRequest.java +++ b/http-client/client/src/main/java/io/avaje/http/client/HttpClientRequest.java @@ -228,24 +228,79 @@ public interface HttpClientRequest { */ HttpClientRequest body(HttpRequest.BodyPublisher body); + /** + * Deprecated migrate to GET(). + */ + @Deprecated + default HttpClientResponse get() { + return GET(); + } + + /** + * Deprecated migrate to POST(). + */ + @Deprecated + default HttpClientResponse post() { + return POST(); + } + + /** + * Deprecated migrate to PUT(). + */ + @Deprecated + default HttpClientResponse put() { + return PUT(); + } + + /** + * Deprecated migrate to PATCH(). + */ + @Deprecated + default HttpClientResponse patch() { + return PATCH(); + } + + /** + * Deprecated migrate to DELETE(). + */ + @Deprecated + default HttpClientResponse delete() { + return DELETE(); + } + /** * Execute the request as a GET. */ - HttpClientResponse get(); + HttpClientResponse GET(); /** * Execute the request as a POST. */ - HttpClientResponse post(); + HttpClientResponse POST(); /** * Execute the request as a PUT. */ - HttpClientResponse put(); + HttpClientResponse PUT(); + + /** + * Execute the request as a PATCH. + */ + HttpClientResponse PATCH(); /** * Execute the request as a DELETE. */ - HttpClientResponse delete(); + HttpClientResponse DELETE(); + + /** + * Execute the request as a TRACE. + */ + HttpClientResponse TRACE(); + + /** + * Execute the request as a HEAD. + */ + HttpClientResponse HEAD(); } diff --git a/http-client/client/src/test/java/io/avaje/http/client/VerbTest.java b/http-client/client/src/test/java/io/avaje/http/client/VerbTest.java new file mode 100644 index 000000000..0d9775026 --- /dev/null +++ b/http-client/client/src/test/java/io/avaje/http/client/VerbTest.java @@ -0,0 +1,115 @@ +package io.avaje.http.client; + +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; + +import java.net.http.HttpResponse; + +import static org.assertj.core.api.Assertions.assertThat; + +public class VerbTest extends BaseWebTest { + + private final HttpClientContext clientContext = client(); + + @Test + void post() { + + HttpResponse res = clientContext.request() + .path("post") + .POST() + .asString(); + + assertThat(res.body()).isEqualTo("post"); + + HttpResponse res2 = clientContext.request() + .path("post") + .post() + .asString(); + + assertThat(res2.body()).isEqualTo("post"); + } + + @Test + void put() { + + HttpResponse res = clientContext.request() + .path("put") + .PUT() + .asString(); + + assertThat(res.body()).isEqualTo("put"); + + HttpResponse res2 = clientContext.request() + .path("put") + .put() + .asString(); + + assertThat(res2.body()).isEqualTo("put"); + } + + @Test + void patch() { + + HttpResponse res = clientContext.request() + .path("patch") + .PATCH().asString(); + + assertThat(res.body()).isEqualTo("patch"); + } + + @Disabled + @Test() + void trace() { + + HttpResponse res = clientContext.request() + .path("patch") + .TRACE().asString(); + + assertThat(res.body()).isEqualTo("patch"); + } + + @Test + void delete() { + + HttpResponse res = clientContext.request() + .path("delete") + .DELETE().asString(); + + assertThat(res.body()).isEqualTo("delete body[]"); + } + + @Test + void delete_with_body() { + + HttpResponse res = clientContext.request() + .path("delete") + .body("dummy") + .DELETE().asString(); + + assertThat(res.body()).isEqualTo("delete body[dummy]"); + } + + @Test + void head() { + + HttpResponse res = clientContext.request() + .path("head") + .body("dummy") + .HEAD().asString(); + + assertThat(res.statusCode()).isEqualTo(200); + assertThat(res.body()).isEqualTo(""); + } + + @Test + void get() { + + HttpResponse res = clientContext.request() + .path("get") + .body("dummy") + .GET().asString(); + + assertThat(res.body()).isEqualTo("get"); + } + +} diff --git a/http-client/client/src/test/java/org/example/webserver/App.java b/http-client/client/src/test/java/org/example/webserver/App.java index 7df4e2119..e7d2baad6 100644 --- a/http-client/client/src/test/java/org/example/webserver/App.java +++ b/http-client/client/src/test/java/org/example/webserver/App.java @@ -56,9 +56,14 @@ public static Javalin start(int port) { ctx.json(map); }); - app.get("/", ctx -> { - ctx.result("Hello World"); - }); + app.get("/", ctx -> ctx.result("Hello World")); + app.head("/head", ctx -> ctx.result("head")); + app.get("/get", ctx -> ctx.result("get")); + app.post("/post", ctx -> ctx.result("post")); + app.put("/put", ctx -> ctx.result("put")); + app.patch("/patch", ctx -> ctx.result("patch")); + //app.tra("/patch", ctx -> ctx.result("patch")); + app.delete("/delete", ctx -> ctx.result("delete body[" + ctx.body() + "]")); // // All WebRoutes / Controllers ... from DI Context // List webRoutes = context.getBeans(WebRoutes.class); From d38d55b0230fec49a61e63a9ec0f476b3761aec9 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Tue, 1 Jun 2021 16:31:18 +1200 Subject: [PATCH 0092/1323] [maven-release-plugin] prepare release avaje-http-client-1.5 --- http-client/client/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/http-client/client/pom.xml b/http-client/client/pom.xml index 65f821d07..820ded611 100644 --- a/http-client/client/pom.xml +++ b/http-client/client/pom.xml @@ -9,11 +9,11 @@ io.avaje avaje-http-client - 1.5-SNAPSHOT + 1.5 scm:git:git@github.com:avaje/avaje-http-client.git - HEAD + avaje-http-client-1.5 From 017cb461a9aab8b49c095164a76978e3f4a38bb3 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Tue, 1 Jun 2021 16:31:26 +1200 Subject: [PATCH 0093/1323] [maven-release-plugin] prepare for next development iteration --- http-client/client/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/http-client/client/pom.xml b/http-client/client/pom.xml index 820ded611..76191066c 100644 --- a/http-client/client/pom.xml +++ b/http-client/client/pom.xml @@ -9,11 +9,11 @@ io.avaje avaje-http-client - 1.5 + 1.6-SNAPSHOT scm:git:git@github.com:avaje/avaje-http-client.git - avaje-http-client-1.5 + HEAD From 615d7048b6cbcb7c38f4c9af69479d7f539f21a8 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Tue, 1 Jun 2021 16:32:31 +1200 Subject: [PATCH 0094/1323] Bump release version to 1.5 --- http-client/gson-adapter/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/http-client/gson-adapter/pom.xml b/http-client/gson-adapter/pom.xml index b64d1730d..e3365d554 100644 --- a/http-client/gson-adapter/pom.xml +++ b/http-client/gson-adapter/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-client-gson - 1.4 + 1.5 scm:git:git@github.com:avaje/avaje-http-client.git From d134ef540018a07ea755c81df7522d8f8ec4c7d9 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Tue, 1 Jun 2021 21:45:44 +1200 Subject: [PATCH 0095/1323] Update README for 1.5 with upper case verbs --- http-client/README.md | 38 +++++++++++++++++++++----------------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/http-client/README.md b/http-client/README.md index 984d5a6f8..1f82aa29a 100644 --- a/http-client/README.md +++ b/http-client/README.md @@ -14,7 +14,7 @@ A light weight wrapper to the JDK 11+ Java Http Client io.avaje avaje-http-client - 1.2 + 1.5 ``` @@ -42,24 +42,25 @@ From HttpClientContext: - Build the url via path(), matrixParam(), queryParam() - Optionally set headers(), cookies() etc - Optionally specify a request body (JSON, form, or raw BodyPublisher) - - Http verbs - get(), post(), put(), delete() + - Http verbs - GET(), POST(), PUT(), PATCH(), DELETE(), HEAD(), TRACE() - Optionally return response body as a bean, list of beans, or raw ## Examples GET as String ```java - final HttpResponse hres = clientContext.request() - .path("hello") - .get().asString(); - +final HttpResponse hres = clientContext.request() + .path("hello") + .GET() + .asString(); ``` GET as json to single bean ```java final HelloDto bean = clientContext.request() .path("hello/there") - .get().bean(HelloDto.class); + .GET() + .bean(HelloDto.class); ``` POST a bean as json request body @@ -68,18 +69,19 @@ HelloDto bean = new HelloDto(12, "rob", "other"); final HttpResponse res = clientContext.request() .path("hello/savebean") - .body(bean).post() + .body(bean) + .POST() .asDiscarding(); assertThat(res.statusCode()).isEqualTo(201); - ``` GET as json to list of beans ```java final List beans = clientContext.request() .path("hello") - .get().list(HelloDto.class); + .GET() + .list(HelloDto.class); ``` Path @@ -88,13 +90,15 @@ final HttpResponse res = clientContext.request() .path("hello") .path("withMatrix") .path("2011") - .get().asString(); + .GET() + .asString(); // is the same as ... final HttpResponse res = clientContext.request() .path("hello/withMatrix/2011") - .get().asString(); + .GET() + .asString(); ``` MatrixParam @@ -105,7 +109,7 @@ final HttpResponse httpRes = clientContext.request() .matrixParam("country", "nz") .path("foo") .matrixParam("extra", "banana") - .get().asString(); + .GET().asString(); ``` QueryParam @@ -114,7 +118,7 @@ final List beans = clientContext.request() .path("hello") .queryParam("sortBy", "name") .queryParam("maxCount", "100") - .get().list(HelloDto.class); + .GET().list(HelloDto.class); ``` FormParam @@ -125,13 +129,13 @@ final HttpResponse res = clientContext.request() .formParam("email", "user@foo.com") .formParam("url", "http://foo.com") .formParam("startDate", "2020-12-03") - .post() + .POST() .asDiscarding(); assertThat(res.statusCode()).isEqualTo(201); ``` -## Currently NO support for POSTing multipart-form +## Currently, NO support for POSTing multipart-form ## Auth token @@ -149,7 +153,7 @@ Built in support for obtaining and setting an Authorization token. .url("https://foo/v2/token") .header("content-type", "application/json") .body(authRequestAsJson()) - .post() + .POST() .bean(AuthTokenResponse.class); Instant validUntil = Instant.now().plusSeconds(res.expires_in).minusSeconds(60); From d1792397317100e1b04d4cf5d91d702df4a5a717 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Wed, 2 Jun 2021 12:56:57 +1200 Subject: [PATCH 0096/1323] [maven-release-plugin] prepare for next development iteration --- http-api/pom.xml | 4 ++-- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 4 ++-- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- pom.xml | 4 ++-- 7 files changed, 10 insertions(+), 10 deletions(-) diff --git a/http-api/pom.xml b/http-api/pom.xml index c70ff6972..0df01a5c5 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-generator-parent - 1.5 + 1.6-SNAPSHOT .. @@ -20,7 +20,7 @@ scm:git:git@github.com:avaje/avaje-http.git - avaje-http-generator-parent-1.5 + HEAD diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index 65824aeb4..bb2c40e66 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -5,7 +5,7 @@ io.avaje avaje-http-generator-parent - 1.5 + 1.6-SNAPSHOT .. diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index aaca13aa6..645f4f21b 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-generator-parent - 1.5 + 1.6-SNAPSHOT .. @@ -33,7 +33,7 @@ io.avaje avaje-http-api - 1.5 + 1.6-SNAPSHOT diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index 94b87e4b7..10aa1c233 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-generator-parent - 1.5 + 1.6-SNAPSHOT .. diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index e3c56fbec..b682ad036 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-generator-parent - 1.5 + 1.6-SNAPSHOT .. diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index f3ea56389..6c074bfde 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-generator-parent - 1.5 + 1.6-SNAPSHOT .. diff --git a/pom.xml b/pom.xml index b27177b05..44ad14504 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-generator-parent - 1.5 + 1.6-SNAPSHOT pom @@ -15,7 +15,7 @@ scm:git:git@github.com:avaje/avaje-http.git - avaje-http-generator-parent-1.5 + HEAD From 7a1abde6eb4b866411d96b4a12cfec418c34afda Mon Sep 17 00:00:00 2001 From: rbygrave Date: Wed, 2 Jun 2021 15:01:05 +1200 Subject: [PATCH 0097/1323] Merge 2.x branch with bump to avaje inject --- tests/test-client/pom.xml | 4 ++-- tests/test-helidon/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-spark/pom.xml | 4 ++-- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index 79cbcdfef..ef2964dbf 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -37,7 +37,7 @@ io.avaje avaje-http-api - 1.5-SNAPSHOT + 1.6-SNAPSHOT @@ -93,7 +93,7 @@ io.avaje avaje-http-generator-client - 1.5-SNAPSHOT + 1.6-SNAPSHOT diff --git a/tests/test-helidon/pom.xml b/tests/test-helidon/pom.xml index 41d3ba711..9da871c88 100644 --- a/tests/test-helidon/pom.xml +++ b/tests/test-helidon/pom.xml @@ -17,7 +17,7 @@ org.example.Main 2.2.2 - 1.5-SNAPSHOT + 1.6-SNAPSHOT diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index b57e10ace..9e2199746 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -20,7 +20,7 @@ 2.0.8 1.3.71 2.12.3 - 1.5-SNAPSHOT + 1.6-SNAPSHOT diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index b84ed1908..aec028a28 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -20,7 +20,7 @@ 2.0.8 2.12.3 6.0.RC4 - 1.5-SNAPSHOT + 1.6-SNAPSHOT diff --git a/tests/test-spark/pom.xml b/tests/test-spark/pom.xml index ff53a9f5c..05e4998c6 100644 --- a/tests/test-spark/pom.xml +++ b/tests/test-spark/pom.xml @@ -17,7 +17,7 @@ org.example.myapp.Main 2.0.8 - 1.5-SNAPSHOT + 1.6-SNAPSHOT @@ -76,7 +76,7 @@ io.avaje avaje-http-spark-generator - 1.5-SNAPSHOT + 1.6-SNAPSHOT provided From dde05d5ec3a9946eba5c4d1d3cd7f158d1198753 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Wed, 2 Jun 2021 15:12:54 +1200 Subject: [PATCH 0098/1323] Bump version to 2.0.RC1-SNAPSHOT --- http-api/pom.xml | 2 +- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 4 ++-- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- pom.xml | 2 +- tests/test-client/pom.xml | 4 ++-- tests/test-helidon/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-spark/pom.xml | 4 ++-- 12 files changed, 15 insertions(+), 15 deletions(-) diff --git a/http-api/pom.xml b/http-api/pom.xml index 0df01a5c5..2592a37d6 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-generator-parent - 1.6-SNAPSHOT + 2.0.RC1-SNAPSHOT .. diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index bb2c40e66..f8ec513dc 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -5,7 +5,7 @@ io.avaje avaje-http-generator-parent - 1.6-SNAPSHOT + 2.0.RC1-SNAPSHOT .. diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 645f4f21b..f954fe1e6 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-generator-parent - 1.6-SNAPSHOT + 2.0.RC1-SNAPSHOT .. @@ -33,7 +33,7 @@ io.avaje avaje-http-api - 1.6-SNAPSHOT + 2.0.RC1-SNAPSHOT diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index 10aa1c233..7276d2267 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-generator-parent - 1.6-SNAPSHOT + 2.0.RC1-SNAPSHOT .. diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index b682ad036..bd78a73bc 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-generator-parent - 1.6-SNAPSHOT + 2.0.RC1-SNAPSHOT .. diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index 6c074bfde..55f394873 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-generator-parent - 1.6-SNAPSHOT + 2.0.RC1-SNAPSHOT .. diff --git a/pom.xml b/pom.xml index b9b30c205..054a171db 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-generator-parent - 1.6-SNAPSHOT + 2.0.RC1-SNAPSHOT pom diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index ef2964dbf..76f793a61 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -37,7 +37,7 @@ io.avaje avaje-http-api - 1.6-SNAPSHOT + 2.0.RC1-SNAPSHOT @@ -93,7 +93,7 @@ io.avaje avaje-http-generator-client - 1.6-SNAPSHOT + 2.0.RC1-SNAPSHOT diff --git a/tests/test-helidon/pom.xml b/tests/test-helidon/pom.xml index 9da871c88..bd6f733e3 100644 --- a/tests/test-helidon/pom.xml +++ b/tests/test-helidon/pom.xml @@ -17,7 +17,7 @@ org.example.Main 2.2.2 - 1.6-SNAPSHOT + 2.0.RC1-SNAPSHOT diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 9e2199746..6c218ff5e 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -20,7 +20,7 @@ 2.0.8 1.3.71 2.12.3 - 1.6-SNAPSHOT + 2.0.RC1-SNAPSHOT diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index aec028a28..49433caac 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -20,7 +20,7 @@ 2.0.8 2.12.3 6.0.RC4 - 1.6-SNAPSHOT + 2.0.RC1-SNAPSHOT diff --git a/tests/test-spark/pom.xml b/tests/test-spark/pom.xml index 05e4998c6..740981b6e 100644 --- a/tests/test-spark/pom.xml +++ b/tests/test-spark/pom.xml @@ -17,7 +17,7 @@ org.example.myapp.Main 2.0.8 - 1.6-SNAPSHOT + 2.0.RC1-SNAPSHOT @@ -76,7 +76,7 @@ io.avaje avaje-http-spark-generator - 1.6-SNAPSHOT + 2.0.RC1-SNAPSHOT provided From 29f9979902f93303d4cdd51e75329ca35492ce6d Mon Sep 17 00:00:00 2001 From: rbygrave Date: Wed, 2 Jun 2021 15:29:57 +1200 Subject: [PATCH 0099/1323] Bump in tests helidon and javalin versions --- tests/test-helidon/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test-helidon/pom.xml b/tests/test-helidon/pom.xml index bd6f733e3..9033e3293 100644 --- a/tests/test-helidon/pom.xml +++ b/tests/test-helidon/pom.xml @@ -16,7 +16,7 @@ org.example.Main - 2.2.2 + 2.3.0 2.0.RC1-SNAPSHOT diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 6c218ff5e..20d497e27 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -16,7 +16,7 @@ org.example.myapp.Main - 3.10.1 + 3.13.7 2.0.8 1.3.71 2.12.3 From 00e5e52fb0589f8fa52b50ff43bc4a0455748a89 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Wed, 16 Jun 2021 14:58:21 +1200 Subject: [PATCH 0100/1323] Bump avaje-inject to 6.0 --- http-hibernate-validator/pom.xml | 4 ++-- tests/test-helidon/pom.xml | 4 ++-- tests/test-javalin/pom.xml | 4 ++-- tests/test-jex/pom.xml | 2 +- tests/test-spark/pom.xml | 4 ++-- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/http-hibernate-validator/pom.xml b/http-hibernate-validator/pom.xml index c7aa2a186..64e801fda 100644 --- a/http-hibernate-validator/pom.xml +++ b/http-hibernate-validator/pom.xml @@ -41,7 +41,7 @@ io.avaje avaje-inject - 6.0.RC4 + 6.0 provided @@ -50,7 +50,7 @@ io.avaje avaje-inject-generator - 6.0.RC4 + 6.0 provided diff --git a/tests/test-helidon/pom.xml b/tests/test-helidon/pom.xml index 9033e3293..897e9a5af 100644 --- a/tests/test-helidon/pom.xml +++ b/tests/test-helidon/pom.xml @@ -41,12 +41,12 @@ io.avaje avaje-inject - 6.0.RC4 + 6.0 io.avaje avaje-inject-generator - 6.0.RC4 + 6.0 provided diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 20d497e27..322ffa54e 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -52,7 +52,7 @@ io.avaje avaje-inject - 6.0.RC4 + 6.0 @@ -78,7 +78,7 @@ io.avaje avaje-inject-generator - 6.0.RC4 + 6.0 provided diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 49433caac..049169f80 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -19,7 +19,7 @@ 1.5 2.0.8 2.12.3 - 6.0.RC4 + 6.0 2.0.RC1-SNAPSHOT diff --git a/tests/test-spark/pom.xml b/tests/test-spark/pom.xml index 740981b6e..0c92e05c9 100644 --- a/tests/test-spark/pom.xml +++ b/tests/test-spark/pom.xml @@ -43,7 +43,7 @@ io.avaje avaje-inject - 6.0.RC4 + 6.0 @@ -69,7 +69,7 @@ io.avaje avaje-inject-generator - 6.0.RC4 + 6.0 provided From bc2a7c4cf689a94c871e45743aaba01205ece98e Mon Sep 17 00:00:00 2001 From: rbygrave Date: Wed, 16 Jun 2021 15:01:31 +1200 Subject: [PATCH 0101/1323] Update tests to use inject ApplicationScope from SystemContext --- README.md | 2 +- tests/test-helidon/src/main/java/org/example/Main.java | 4 ++-- tests/test-javalin/src/main/java/org/example/myapp/Main.java | 4 ++-- tests/test-spark/src/main/java/org/example/web/App.java | 3 +-- 4 files changed, 6 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 8e3d072ca..84359f626 100644 --- a/README.md +++ b/README.md @@ -55,7 +55,7 @@ get all the WebRoutes and register them with Javalin using. fun main(args: Array) { // get all the webRoutes - val webRoutes = SystemContext.getBeans(WebRoutes::class.java) + val webRoutes = ApplicationScope.list(WebRoutes::class.java) val javalin = Javalin.create() diff --git a/tests/test-helidon/src/main/java/org/example/Main.java b/tests/test-helidon/src/main/java/org/example/Main.java index 4fb311a84..18a392b87 100644 --- a/tests/test-helidon/src/main/java/org/example/Main.java +++ b/tests/test-helidon/src/main/java/org/example/Main.java @@ -1,6 +1,6 @@ package org.example; -import io.avaje.inject.SystemContext; +import io.avaje.inject.ApplicationScope; import io.helidon.health.HealthSupport; import io.helidon.media.jackson.JacksonSupport; import io.helidon.metrics.MetricsSupport; @@ -58,7 +58,7 @@ private static Routing createRouting() { .register(MetricsSupport.create()) .register("/greet", new GreetService()); - SystemContext.getBeans(Service.class).forEach(builder::register); + ApplicationScope.list(Service.class).forEach(builder::register); return builder.build(); } diff --git a/tests/test-javalin/src/main/java/org/example/myapp/Main.java b/tests/test-javalin/src/main/java/org/example/myapp/Main.java index d53a573b9..830a2ca6a 100644 --- a/tests/test-javalin/src/main/java/org/example/myapp/Main.java +++ b/tests/test-javalin/src/main/java/org/example/myapp/Main.java @@ -4,7 +4,7 @@ import io.avaje.http.api.InvalidTypeArgumentException; import io.avaje.http.api.ValidationException; import io.avaje.http.api.WebRoutes; -import io.avaje.inject.SystemContext; +import io.avaje.inject.ApplicationScope; import io.javalin.Javalin; import io.javalin.http.staticfiles.Location; import io.swagger.v3.oas.annotations.OpenAPIDefinition; @@ -71,7 +71,7 @@ public static Javalin start(int port) { }); // All WebRoutes / Controllers ... from DI Context - List webRoutes = SystemContext.getBeans(WebRoutes.class); + List webRoutes = ApplicationScope.list(WebRoutes.class); app.routes(() -> webRoutes.forEach(WebRoutes::registerRoutes)); app.start(port); diff --git a/tests/test-spark/src/main/java/org/example/web/App.java b/tests/test-spark/src/main/java/org/example/web/App.java index da7cca8a6..ed0c8a9ba 100644 --- a/tests/test-spark/src/main/java/org/example/web/App.java +++ b/tests/test-spark/src/main/java/org/example/web/App.java @@ -1,7 +1,6 @@ package org.example.web; import io.avaje.http.api.WebRoutes; -import io.avaje.inject.SystemContext; import spark.Spark; public class App { @@ -17,7 +16,7 @@ public static void main(String[] args) { return "hello"; }); - SystemContext.getBeans(WebRoutes.class) + ApplicationScope.list(WebRoutes.class) .forEach(WebRoutes::registerRoutes); } } From dc0fb219bfedc2f5631cdfaca1b4514843d705c0 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Wed, 16 Jun 2021 15:21:23 +1200 Subject: [PATCH 0102/1323] Update tests with upper case verbs --- .../io/avaje/http/client/AuthTokenTest.java | 6 +-- .../http/client/HelloControllerTest.java | 38 ++++++++++--------- .../java/io/avaje/http/client/RetryTest.java | 2 +- .../io/avaje/http/client/UrlBuilderTest.java | 4 +- .../java/io/avaje/http/client/VerbTest.java | 4 +- .../org/example/github/SimpleHttpClient.java | 8 ++-- 6 files changed, 32 insertions(+), 30 deletions(-) diff --git a/http-client/client/src/test/java/io/avaje/http/client/AuthTokenTest.java b/http-client/client/src/test/java/io/avaje/http/client/AuthTokenTest.java index 7a5f09925..de59da4b9 100644 --- a/http-client/client/src/test/java/io/avaje/http/client/AuthTokenTest.java +++ b/http-client/client/src/test/java/io/avaje/http/client/AuthTokenTest.java @@ -32,7 +32,7 @@ public AuthToken obtainToken(HttpClientRequest tokenRequest) { .url("https://foo/v2/token") .header("content-type", "application/json") .body(authRequestAsJson()) - .post() + .POST() .bean(AuthTokenResponse.class); Instant validUntil = Instant.now().plusSeconds(res.expires_in).minusSeconds(60); @@ -58,14 +58,14 @@ void sendEmail() { .path(path) .header("Content-Type", "application/json") //.body(payload) - .post() + .POST() .asString(); HttpResponse res2 = ctx.request() .path(path) .header("Content-Type", "application/json") //.body(payload) - .post() + .POST() .asString(); } diff --git a/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java b/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java index 88d20eccb..74c425393 100644 --- a/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java +++ b/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java @@ -9,9 +9,7 @@ import java.util.Map; import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.fail; +import static org.junit.jupiter.api.Assertions.*; class HelloControllerTest extends BaseWebTest { @@ -22,7 +20,7 @@ void get_helloMessage() { final HttpResponse hres = clientContext.request() .path("hello").path("message") - .get().asString(); + .GET().asString(); assertThat(hres.body()).contains("hello world"); assertThat(hres.statusCode()).isEqualTo(200); @@ -34,7 +32,7 @@ void get_helloMessage_via_url() { final HttpResponse hres = clientContext.request() .url("http://127.0.0.1:8887") .path("hello").path("message") - .get().asString(); + .GET().asString(); assertThat(hres.body()).contains("hello world"); assertThat(hres.statusCode()).isEqualTo(200); @@ -45,7 +43,7 @@ void get_hello_returningListOfBeans() { final List helloDtos = clientContext.request() .path("hello") - .get().list(HelloDto.class); + .GET().list(HelloDto.class); assertThat(helloDtos).hasSize(2); } @@ -54,8 +52,9 @@ void get_hello_returningListOfBeans() { void get_withPathParamAndQueryParam_returningBean() { final HelloDto dto = clientContext.request() - .path("hello/43/2020-03-05").queryParam("otherParam", "other").queryParam("foo", (String) null) - .get().bean(HelloDto.class); + .path("hello/43/2020-03-05").queryParam("otherParam", "other").queryParam("foo", null) + .GET() + .bean(HelloDto.class); assertThat(dto.id).isEqualTo(43L); assertThat(dto.name).isEqualTo("2020-03-05"); @@ -73,7 +72,7 @@ void post_bean_returningBean_usingExplicitConverters() { final HelloDto bean = clientContext.request() .path("hello") .body(from.write(dto)) - .post() + .POST() .read(toDto); assertEquals("posted", bean.name); @@ -87,7 +86,8 @@ void post_bean_returningVoid() { final HttpResponse res = clientContext.request() .path("hello/savebean/foo") - .body(dto).post() + .body(dto) + .POST() .asDiscarding(); assertThat(res.statusCode()).isEqualTo(201); @@ -102,7 +102,7 @@ void postForm() { .formParam("email", "user@foo.com") .formParam("url", "http://foo.com") .formParam("startDate", "2030-12-03") - .post() + .POST() .asDiscarding(); assertThat(res.statusCode()).isEqualTo(201); @@ -117,7 +117,7 @@ void postForm_returningBean() { .formParam("email", "user@foo.com") .formParam("url", "http://foo.com") .formParam("startDate", "2030-12-03") - .post() + .POST() .asDiscarding(); assertThat(res.statusCode()).isEqualTo(201); @@ -128,7 +128,7 @@ void postForm_returningBean() { .formParam("email", "Bax@foo.com") .formParam("url", "http://foo.com") .formParam("startDate", "2030-12-03") - .post() + .POST() .bean(HelloDto.class); assertThat(bean.name).isEqualTo("Bax"); @@ -143,7 +143,7 @@ void postForm_asVoid_validResponse() { .formParam("name", "baz") .formParam("email", "user@foo.com") .formParam("url", "http://foo") - .post() + .POST() .asVoid(); assertEquals(201, res.statusCode()); @@ -156,7 +156,7 @@ void postForm_asVoid_invokesValidation_expect_badRequest_extractError() { .path("hello/saveform") .formParam("email", "user@foo.com") .formParam("url", "notAValidUrl") - .post() + .POST() .asVoid(); fail(); @@ -183,7 +183,7 @@ void postForm_asBytes_validation_expect_badRequest_extractError() { .path("hello/saveform") .formParam("email", "user@foo.com") .formParam("url", "notAValidUrl") - .post().asVoid(); + .POST().asVoid(); fail(); @@ -212,7 +212,8 @@ void delete() { final HttpResponse res = clientContext.request() .path("hello/52") - .delete().asDiscarding(); + .DELETE() + .asDiscarding(); assertThat(res.statusCode()).isEqualTo(204); } @@ -226,7 +227,8 @@ void get_withMatrixParam() { .matrixParam("country", "nz") .path("foo") .queryParam("extra", "banana") - .get().asString(); + .GET() + .asString(); assertEquals(200, httpRes.statusCode()); assertEquals("yr:2011 au:rob co:nz other:foo extra:banana", httpRes.body()); diff --git a/http-client/client/src/test/java/io/avaje/http/client/RetryTest.java b/http-client/client/src/test/java/io/avaje/http/client/RetryTest.java index 5daf0b48d..f828182b9 100644 --- a/http-client/client/src/test/java/io/avaje/http/client/RetryTest.java +++ b/http-client/client/src/test/java/io/avaje/http/client/RetryTest.java @@ -25,7 +25,7 @@ void retryTest() { HttpResponse res = clientContext.request() .path("hello/retry") - .get() + .GET() .asString(); assertThat(res.body()).isEqualTo("All good at 3rd attempt"); diff --git a/http-client/client/src/test/java/io/avaje/http/client/UrlBuilderTest.java b/http-client/client/src/test/java/io/avaje/http/client/UrlBuilderTest.java index 625d0f690..623a8917b 100644 --- a/http-client/client/src/test/java/io/avaje/http/client/UrlBuilderTest.java +++ b/http-client/client/src/test/java/io/avaje/http/client/UrlBuilderTest.java @@ -63,7 +63,7 @@ void matrixParam_path() { @Test void param() { - assertThat(foo().queryParam("bar", (String) null).build()).isEqualTo("https://foo"); + assertThat(foo().queryParam("bar", null).build()).isEqualTo("https://foo"); assertThat(foo().queryParam("bar", "a").build()).isEqualTo("https://foo?bar=a"); assertThat(foo().queryParam("bar", "a").queryParam("baz", "b").build()).isEqualTo("https://foo?bar=a&baz=b"); } @@ -75,7 +75,7 @@ void param_encode() { @Test void queryParam_when_null() { - assertThat(foo().queryParam("bar", (String) null).build()).isEqualTo("https://foo"); + assertThat(foo().queryParam("bar", null).build()).isEqualTo("https://foo"); assertThat(foo().queryParam("bar", (Boolean) null).build()).isEqualTo("https://foo"); assertThat(foo().queryParam("bar", (Integer) null).build()).isEqualTo("https://foo"); assertThat(foo().queryParam("bar", (Long) null).build()).isEqualTo("https://foo"); diff --git a/http-client/client/src/test/java/io/avaje/http/client/VerbTest.java b/http-client/client/src/test/java/io/avaje/http/client/VerbTest.java index 0d9775026..c1ef6ba41 100644 --- a/http-client/client/src/test/java/io/avaje/http/client/VerbTest.java +++ b/http-client/client/src/test/java/io/avaje/http/client/VerbTest.java @@ -23,7 +23,7 @@ void post() { HttpResponse res2 = clientContext.request() .path("post") - .post() + .POST() .asString(); assertThat(res2.body()).isEqualTo("post"); @@ -41,7 +41,7 @@ void put() { HttpResponse res2 = clientContext.request() .path("put") - .put() + .PUT() .asString(); assertThat(res2.body()).isEqualTo("put"); diff --git a/http-client/client/src/test/java/org/example/github/SimpleHttpClient.java b/http-client/client/src/test/java/org/example/github/SimpleHttpClient.java index 970a430b7..9e6d4812e 100644 --- a/http-client/client/src/test/java/org/example/github/SimpleHttpClient.java +++ b/http-client/client/src/test/java/org/example/github/SimpleHttpClient.java @@ -29,7 +29,7 @@ public List listRepos(String user, String other) throws HttpException { return context.request() .path("users").path(user).path("repos") .queryParam("other", other) - .get().list(Repo.class); + .GET().list(Repo.class); } @Post("users") @@ -38,7 +38,7 @@ public Repo post(Repo repo) throws HttpException { return context.request() .path("foo/users") .body(writeRepo.write(repo)) - .post().read(readRepo); + .POST().read(readRepo); } @Get("users/{id}") @@ -46,7 +46,7 @@ public Repo post(Repo repo) throws HttpException { public Repo getById(String id) { return context.request() .path("users").path(id) - .get().bean(Repo.class); + .GET().bean(Repo.class); } public InputStream getById2(String id, InputStream is) { @@ -54,7 +54,7 @@ public InputStream getById2(String id, InputStream is) { context.request() .path("users").path(id).path("stream") .body(() -> is) - .get().withResponseHandler(HttpResponse.BodyHandlers.ofInputStream()); + .GET().withResponseHandler(HttpResponse.BodyHandlers.ofInputStream()); context.checkResponse(response); return response.body(); From 6b84b8c61e7206b3d8dca8df41f4658fcf39bd03 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Wed, 16 Jun 2021 17:20:53 +1200 Subject: [PATCH 0103/1323] #16 - Obfuscate Authorization header and suppress logging payloads for AuthToken request and via request.suppressLogging() --- .../avaje/http/client/DHttpClientContext.java | 8 ++++- .../avaje/http/client/DHttpClientRequest.java | 14 ++++++++ .../avaje/http/client/HttpClientRequest.java | 8 +++++ .../io/avaje/http/client/RequestListener.java | 1 - .../io/avaje/http/client/RequestLogger.java | 11 +++++- .../http/client/DHttpClientRequestTest.java | 35 +++++++++++++++++++ .../avaje/http/client/RequestLoggerTest.java | 16 +++++++++ 7 files changed, 90 insertions(+), 3 deletions(-) create mode 100644 http-client/client/src/test/java/io/avaje/http/client/DHttpClientRequestTest.java create mode 100644 http-client/client/src/test/java/io/avaje/http/client/RequestLoggerTest.java diff --git a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContext.java b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContext.java index 5358b2454..1ac3f0ec7 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContext.java +++ b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContext.java @@ -13,6 +13,12 @@ class DHttpClientContext implements HttpClientContext { + /** + * HTTP Authorization header. + */ + static final String AUTHORIZATION = "Authorization"; + private static final String BEARER = "Bearer "; + private final HttpClient httpClient; private final String baseUrl; private final Duration requestTimeout; @@ -172,7 +178,7 @@ void afterResponse(DHttpClientRequest request) { void beforeRequest(DHttpClientRequest request) { if (withAuthToken && !request.isSkipAuthToken()) { - request.header("Authorization", "Bearer " + authToken()); + request.header(AUTHORIZATION, BEARER + authToken()); } if (requestIntercept != null) { requestIntercept.beforeRequest(request); diff --git a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java index 7e52a5f66..648c382a7 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java +++ b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java @@ -48,6 +48,7 @@ class DHttpClientRequest implements HttpClientRequest, HttpClientResponse { private BodyContent encodedResponseBody; private boolean loggableResponseBody; private boolean skipAuthToken; + private boolean suppressLogging; DHttpClientRequest(DHttpClientContext context, Duration requestTimeout) { this.context = context; @@ -58,6 +59,13 @@ class DHttpClientRequest implements HttpClientRequest, HttpClientResponse { @Override public HttpClientRequest skipAuthToken() { this.skipAuthToken = true; + this.suppressLogging = true; + return this; + } + + @Override + public HttpClientRequest suppressLogging() { + this.suppressLogging = true; return this; } @@ -471,6 +479,9 @@ public HttpRequest request() { @Override public String requestBody() { + if (suppressLogging) { + return ""; + } if (encodedRequestBody != null) { return new String(encodedRequestBody.content(), StandardCharsets.UTF_8); } else if (bodyFormEncoded) { @@ -485,6 +496,9 @@ public String requestBody() { @Override public String responseBody() { + if (suppressLogging) { + return ""; + } if (encodedResponseBody != null) { return new String(encodedResponseBody.content(), StandardCharsets.UTF_8); } else if (httpResponse != null && loggableResponseBody) { diff --git a/http-client/client/src/main/java/io/avaje/http/client/HttpClientRequest.java b/http-client/client/src/main/java/io/avaje/http/client/HttpClientRequest.java index 157eb0370..2409d1f89 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/HttpClientRequest.java +++ b/http-client/client/src/main/java/io/avaje/http/client/HttpClientRequest.java @@ -34,6 +34,14 @@ public interface HttpClientRequest { */ HttpClientRequest skipAuthToken(); + /** + * For this request suppress payload logging. + *

+ * The payload contains sensitive content and the request and response content + * should be suppressed and not included in request logging. + */ + HttpClientRequest suppressLogging(); + /** * Set the request timeout to use for this request. When not set the default * request timeout will be used. diff --git a/http-client/client/src/main/java/io/avaje/http/client/RequestListener.java b/http-client/client/src/main/java/io/avaje/http/client/RequestListener.java index 2cdfde1d9..9ee496b02 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/RequestListener.java +++ b/http-client/client/src/main/java/io/avaje/http/client/RequestListener.java @@ -50,7 +50,6 @@ interface Event { * This will return null if the response is not String or byte array * encoded string content. For example, when requests use response * handlers for InputStream, Path, Stream etc this will return null. - *

*/ String responseBody(); diff --git a/http-client/client/src/main/java/io/avaje/http/client/RequestLogger.java b/http-client/client/src/main/java/io/avaje/http/client/RequestLogger.java index c989c9e42..cc2a50b9b 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/RequestLogger.java +++ b/http-client/client/src/main/java/io/avaje/http/client/RequestLogger.java @@ -61,8 +61,17 @@ private void headers(StringBuilder sb, String label, HttpHeaders headers) { if (!entries.isEmpty()) { sb.append(delimiter).append(label); for (Map.Entry> entry : entries) { - sb.append(entry.getKey()).append("=").append(entry.getValue()).append(", "); + final String key = entry.getKey(); + if (obfuscate(key)) { + sb.append(key).append("=, "); + } else { + sb.append(key).append("=").append(entry.getValue()).append(", "); + } } } } + + boolean obfuscate(String key) { + return DHttpClientContext.AUTHORIZATION.equals(key); + } } diff --git a/http-client/client/src/test/java/io/avaje/http/client/DHttpClientRequestTest.java b/http-client/client/src/test/java/io/avaje/http/client/DHttpClientRequestTest.java new file mode 100644 index 000000000..d83a779ac --- /dev/null +++ b/http-client/client/src/test/java/io/avaje/http/client/DHttpClientRequestTest.java @@ -0,0 +1,35 @@ +package io.avaje.http.client; + +import org.junit.jupiter.api.Test; + +import java.time.Duration; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; + +class DHttpClientRequestTest { + + @Test + void suppressLogging_listenerEvent_expect_suppressedPayloadContent() { + + final DHttpClientRequest request = new DHttpClientRequest(mock(DHttpClientContext.class), Duration.ZERO); + + request.suppressLogging(); + final RequestListener.Event event = request.listenerEvent(); + + assertThat(event.requestBody()).isEqualTo(""); + assertThat(event.responseBody()).isEqualTo(""); + } + + @Test + void skipAuthToken_listenerEvent_expect_suppressedPayloadContent() { + + final DHttpClientRequest request = new DHttpClientRequest(mock(DHttpClientContext.class), Duration.ZERO); + + request.skipAuthToken(); + final RequestListener.Event event = request.listenerEvent(); + + assertThat(event.requestBody()).isEqualTo(""); + assertThat(event.responseBody()).isEqualTo(""); + } +} diff --git a/http-client/client/src/test/java/io/avaje/http/client/RequestLoggerTest.java b/http-client/client/src/test/java/io/avaje/http/client/RequestLoggerTest.java new file mode 100644 index 000000000..44ec0b69c --- /dev/null +++ b/http-client/client/src/test/java/io/avaje/http/client/RequestLoggerTest.java @@ -0,0 +1,16 @@ +package io.avaje.http.client; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +class RequestLoggerTest { + + private final RequestLogger requestLogger = new RequestLogger(); + + @Test + void obfuscate() { + assertTrue(requestLogger.obfuscate("Authorization")); + assertFalse(requestLogger.obfuscate("Foo")); + } +} From f41585ad6bea9d930c9ee6c7a7034a9a4a09eaa2 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Wed, 16 Jun 2021 21:38:28 +1200 Subject: [PATCH 0104/1323] #17 - Add stream() ... for streaming beans from x-json-stream response --- .../java/io/avaje/http/client/BodyReader.java | 4 ++++ .../avaje/http/client/DHttpClientContext.java | 4 ++++ .../avaje/http/client/DHttpClientRequest.java | 11 +++++++++ .../avaje/http/client/HttpClientResponse.java | 13 +++++++++++ .../avaje/http/client/JacksonBodyAdapter.java | 9 ++++++++ .../http/client/HelloControllerTest.java | 23 +++++++++++++++++++ .../webserver/HelloController$Route.java | 5 ++++ .../example/webserver/HelloController.java | 12 ++++++++++ http-client/gson-adapter/pom.xml | 2 +- .../http/client/gson/GsonBodyAdapter.java | 12 ++++++++++ 10 files changed, 94 insertions(+), 1 deletion(-) diff --git a/http-client/client/src/main/java/io/avaje/http/client/BodyReader.java b/http-client/client/src/main/java/io/avaje/http/client/BodyReader.java index 2bfe4a210..24417ab02 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/BodyReader.java +++ b/http-client/client/src/main/java/io/avaje/http/client/BodyReader.java @@ -10,4 +10,8 @@ public interface BodyReader { */ T read(BodyContent content); + /** + * Read the String content returning it as a java type. + */ + T readBody(String content); } diff --git a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContext.java b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContext.java index 1ac3f0ec7..bf6468186 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContext.java +++ b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContext.java @@ -159,6 +159,10 @@ BodyContent write(Object bean, String contentType) { return bodyAdapter.beanWriter(bean.getClass()).write(bean, contentType); } + BodyReader beanReader(Class cls) { + return bodyAdapter.beanReader(cls); + } + T readBean(Class cls, BodyContent content) { return bodyAdapter.beanReader(cls).read(content); } diff --git a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java index 648c382a7..95f907d7f 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java +++ b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java @@ -348,6 +348,17 @@ public List list(Class cls) { return context.readList(cls, encodedResponseBody); } + @Override + public Stream stream(Class cls) { + final HttpResponse> res = withResponseHandler(HttpResponse.BodyHandlers.ofLines()); + this.httpResponse = res; + if (res.statusCode() >= 300) { + throw new HttpException(res, context); + } + final BodyReader bodyReader = context.beanReader(cls); + return res.body().map(bodyReader::readBody); + } + @Override public HttpResponse withResponseHandler(HttpResponse.BodyHandler responseHandler) { context.beforeRequest(this); diff --git a/http-client/client/src/main/java/io/avaje/http/client/HttpClientResponse.java b/http-client/client/src/main/java/io/avaje/http/client/HttpClientResponse.java index 13a9e38df..8d1082091 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/HttpClientResponse.java +++ b/http-client/client/src/main/java/io/avaje/http/client/HttpClientResponse.java @@ -42,6 +42,19 @@ public interface HttpClientResponse { */ List list(Class type); + /** + * Return the response as a stream of beans. + *

+ * Typically the response is expected to be {@literal applciation/x-json-stream} + * newline delimited json payload. + * + * @param type The type of the bean to convert the response content into. + * @param The type that the content is converted to. + * @return The stream of beans from the response + * @throws HttpException when the response has error status codes + */ + Stream stream(Class type); + /** * Return the response with check for 200 range status code. *

diff --git a/http-client/client/src/main/java/io/avaje/http/client/JacksonBodyAdapter.java b/http-client/client/src/main/java/io/avaje/http/client/JacksonBodyAdapter.java index c6f50a69f..702ee480c 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/JacksonBodyAdapter.java +++ b/http-client/client/src/main/java/io/avaje/http/client/JacksonBodyAdapter.java @@ -83,6 +83,15 @@ private static class JReader implements BodyReader { this.reader = reader; } + @Override + public T readBody(String content) { + try { + return reader.readValue(content); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + @Override public T read(BodyContent s) { try { diff --git a/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java b/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java index 74c425393..82180d4c6 100644 --- a/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java +++ b/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java @@ -7,6 +7,8 @@ import java.net.http.HttpResponse; import java.util.List; import java.util.Map; +import java.util.stream.Collectors; +import java.util.stream.Stream; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.*; @@ -15,6 +17,22 @@ class HelloControllerTest extends BaseWebTest { final HttpClientContext clientContext = client(); + @Test + void get_stream() { + + final Stream stream = clientContext.request() + .path("hello").path("stream") + .GET() + .stream(SimpleData.class); + + final List data = stream.collect(Collectors.toList()); + + assertThat(data).hasSize(4); + final SimpleData first = data.get(0); + assertThat(first.id).isEqualTo(1); + assertThat(first.name).isEqualTo("one"); + } + @Test void get_helloMessage() { @@ -233,4 +251,9 @@ void get_withMatrixParam() { assertEquals(200, httpRes.statusCode()); assertEquals("yr:2011 au:rob co:nz other:foo extra:banana", httpRes.body()); } + + public static class SimpleData { + public long id; + public String name; + } } diff --git a/http-client/client/src/test/java/org/example/webserver/HelloController$Route.java b/http-client/client/src/test/java/org/example/webserver/HelloController$Route.java index b90372c6c..423ab4a4f 100644 --- a/http-client/client/src/test/java/org/example/webserver/HelloController$Route.java +++ b/http-client/client/src/test/java/org/example/webserver/HelloController$Route.java @@ -36,6 +36,11 @@ public void registerRoutes() { ctx.contentType("text/plain").result(controller.retry()); }); + ApiBuilder.get("/hello/stream", ctx -> { + ctx.status(200); + controller.stream(ctx); + }); + ApiBuilder.get("/hello/:id/:date", ctx -> { ctx.status(200); int id = asInt(ctx.pathParam("id")); diff --git a/http-client/client/src/test/java/org/example/webserver/HelloController.java b/http-client/client/src/test/java/org/example/webserver/HelloController.java index 53b947c48..2339b6ab6 100644 --- a/http-client/client/src/test/java/org/example/webserver/HelloController.java +++ b/http-client/client/src/test/java/org/example/webserver/HelloController.java @@ -47,6 +47,18 @@ String retry() { } } + @Get("stream") + void stream(Context context) { + // simulate x-json-stream response + context.header("content-type", "application/x-json-stream"); + String content = + "{\"id\":1, \"name\":\"one\"}\n" + + "{\"id\":2, \"name\":\"two\"}\n" + + "{\"id\":3, \"name\":\"three\"}\n" + + "{\"id\":4, \"name\":\"four\"}\n"; + context.result(content); + } + /** * Return the Hello DTO. * diff --git a/http-client/gson-adapter/pom.xml b/http-client/gson-adapter/pom.xml index e3365d554..0fa6dc466 100644 --- a/http-client/gson-adapter/pom.xml +++ b/http-client/gson-adapter/pom.xml @@ -27,7 +27,7 @@ io.avaje avaje-http-client - 1.3 + 1.6-SNAPSHOT provided diff --git a/http-client/gson-adapter/src/main/java/io/avaje/http/client/gson/GsonBodyAdapter.java b/http-client/gson-adapter/src/main/java/io/avaje/http/client/gson/GsonBodyAdapter.java index c5798fca6..238dc3756 100644 --- a/http-client/gson-adapter/src/main/java/io/avaje/http/client/gson/GsonBodyAdapter.java +++ b/http-client/gson-adapter/src/main/java/io/avaje/http/client/gson/GsonBodyAdapter.java @@ -100,6 +100,18 @@ private static class Reader implements BodyReader { this.adapter = adapter; } + /** + * Read the content returning it as a java type. + */ + @Override + public T readBody(String content) { + try { + return adapter.fromJson(content); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + @Override public T read(BodyContent body) { try { From 75e09576262ec4eef467772fa6322083c0c8e759 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Wed, 16 Jun 2021 21:39:20 +1200 Subject: [PATCH 0105/1323] [maven-release-plugin] prepare release avaje-http-client-1.6 --- http-client/client/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/http-client/client/pom.xml b/http-client/client/pom.xml index 76191066c..921c61924 100644 --- a/http-client/client/pom.xml +++ b/http-client/client/pom.xml @@ -9,11 +9,11 @@ io.avaje avaje-http-client - 1.6-SNAPSHOT + 1.6 scm:git:git@github.com:avaje/avaje-http-client.git - HEAD + avaje-http-client-1.6 From 5240ef824d9076844541d64586aad98418660b95 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Wed, 16 Jun 2021 21:39:29 +1200 Subject: [PATCH 0106/1323] [maven-release-plugin] prepare for next development iteration --- http-client/client/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/http-client/client/pom.xml b/http-client/client/pom.xml index 921c61924..8de2e7070 100644 --- a/http-client/client/pom.xml +++ b/http-client/client/pom.xml @@ -9,11 +9,11 @@ io.avaje avaje-http-client - 1.6 + 1.7-SNAPSHOT scm:git:git@github.com:avaje/avaje-http-client.git - avaje-http-client-1.6 + HEAD From cccff8f6f0f135ef76253759c0d77129360bcfe3 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Wed, 16 Jun 2021 21:43:45 +1200 Subject: [PATCH 0107/1323] Bump to 1.6 to release --- http-client/gson-adapter/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/http-client/gson-adapter/pom.xml b/http-client/gson-adapter/pom.xml index 0fa6dc466..49a33026d 100644 --- a/http-client/gson-adapter/pom.xml +++ b/http-client/gson-adapter/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-client-gson - 1.5 + 1.6 scm:git:git@github.com:avaje/avaje-http-client.git @@ -27,7 +27,7 @@ io.avaje avaje-http-client - 1.6-SNAPSHOT + 1.6 provided From 79b16c14da29dbf1ffe315117a9b3670b9ee514f Mon Sep 17 00:00:00 2001 From: rbygrave Date: Wed, 16 Jun 2021 22:13:29 +1200 Subject: [PATCH 0108/1323] Update README --- http-client/README.md | 62 +++++++++++++++++++++++++------------------ 1 file changed, 36 insertions(+), 26 deletions(-) diff --git a/http-client/README.md b/http-client/README.md index 1f82aa29a..8248a1a8e 100644 --- a/http-client/README.md +++ b/http-client/README.md @@ -14,7 +14,7 @@ A light weight wrapper to the JDK 11+ Java Http Client io.avaje avaje-http-client - 1.5 + 1.6 ``` @@ -49,7 +49,7 @@ From HttpClientContext: GET as String ```java -final HttpResponse hres = clientContext.request() +HttpResponse hres = clientContext.request() .path("hello") .GET() .asString(); @@ -57,17 +57,34 @@ final HttpResponse hres = clientContext.request() GET as json to single bean ```java -final HelloDto bean = clientContext.request() - .path("hello/there") +Customer customer = clientContext.request() + .path("customers").path(42) .GET() - .bean(HelloDto.class); + .bean(Customer.class); ``` +GET as json to a list of beans +```java +List list = clientContext.request() + .path("customers") + .GET() + .list(Customer.class); +``` + +GET as `application/x-json-stream` as a stream of beans +```java +Stream stream = clientContext.request() + .path("customers/all") + .GET() + .stream(Customer.class); +``` + + POST a bean as json request body ```java HelloDto bean = new HelloDto(12, "rob", "other"); -final HttpResponse res = clientContext.request() +HttpResponse res = clientContext.request() .path("hello/savebean") .body(bean) .POST() @@ -76,35 +93,28 @@ final HttpResponse res = clientContext.request() assertThat(res.statusCode()).isEqualTo(201); ``` -GET as json to list of beans -```java -final List beans = clientContext.request() - .path("hello") - .GET() - .list(HelloDto.class); -``` Path ```java -final HttpResponse res = clientContext.request() - .path("hello") - .path("withMatrix") - .path("2011") +HttpResponse res = clientContext.request() + .path("customers") + .path("42") + .path("contacts") .GET() .asString(); // is the same as ... -final HttpResponse res = clientContext.request() - .path("hello/withMatrix/2011") +HttpResponse res = clientContext.request() + .path("customers/42/contacts") .GET() .asString(); ``` MatrixParam ```java -final HttpResponse httpRes = clientContext.request() - .path("hello") +HttpResponse httpRes = clientContext.request() + .path("books") .matrixParam("author", "rob") .matrixParam("country", "nz") .path("foo") @@ -114,17 +124,17 @@ final HttpResponse httpRes = clientContext.request() QueryParam ```java -final List beans = clientContext.request() - .path("hello") +List beans = clientContext.request() + .path("products") .queryParam("sortBy", "name") .queryParam("maxCount", "100") - .GET().list(HelloDto.class); + .GET().list(Product.class); ``` FormParam ```java -final HttpResponse res = clientContext.request() - .path("hello/saveform") +HttpResponse res = clientContext.request() + .path("register/user") .formParam("name", "Bazz") .formParam("email", "user@foo.com") .formParam("url", "http://foo.com") From aebaca391c54be9c07f87fc9c311b87d70ac4ef1 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Wed, 16 Jun 2021 22:21:30 +1200 Subject: [PATCH 0109/1323] Bump to avaje-http-client and jex to version 1.6 --- tests/test-client/pom.xml | 2 +- tests/test-helidon/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 4 ++-- tests/test-spark/pom.xml | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index 76f793a61..e06a8a8ce 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -25,7 +25,7 @@ io.avaje avaje-http-client - 1.5 + 1.6 diff --git a/tests/test-helidon/pom.xml b/tests/test-helidon/pom.xml index 897e9a5af..94ec05b12 100644 --- a/tests/test-helidon/pom.xml +++ b/tests/test-helidon/pom.xml @@ -115,7 +115,7 @@ io.avaje avaje-http-client - 1.5 + 1.6 test diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 322ffa54e..52ea659d5 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -108,7 +108,7 @@ io.avaje avaje-http-client - 1.5 + 1.6 test diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 049169f80..998f2d5f2 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -16,7 +16,7 @@ org.example.myapp.Main - 1.5 + 1.6 2.0.8 2.12.3 6.0 @@ -95,7 +95,7 @@ io.avaje avaje-http-client - 1.5 + 1.6 test diff --git a/tests/test-spark/pom.xml b/tests/test-spark/pom.xml index 0c92e05c9..3939f78eb 100644 --- a/tests/test-spark/pom.xml +++ b/tests/test-spark/pom.xml @@ -93,7 +93,7 @@ io.avaje avaje-http-client - 1.5 + 1.6 test From 6c7bb3a41b8e8dc798086cd667b2748d06093221 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Wed, 16 Jun 2021 22:35:25 +1200 Subject: [PATCH 0110/1323] Bump version to 1.6-SNAPSHOT --- http-api/pom.xml | 2 +- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 4 ++-- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- pom.xml | 4 ++-- tests/test-client/pom.xml | 4 ++-- tests/test-helidon/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-spark/pom.xml | 4 ++-- 12 files changed, 16 insertions(+), 16 deletions(-) diff --git a/http-api/pom.xml b/http-api/pom.xml index 2592a37d6..0df01a5c5 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-generator-parent - 2.0.RC1-SNAPSHOT + 1.6-SNAPSHOT .. diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index f8ec513dc..bb2c40e66 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -5,7 +5,7 @@ io.avaje avaje-http-generator-parent - 2.0.RC1-SNAPSHOT + 1.6-SNAPSHOT .. diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index f954fe1e6..645f4f21b 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-generator-parent - 2.0.RC1-SNAPSHOT + 1.6-SNAPSHOT .. @@ -33,7 +33,7 @@ io.avaje avaje-http-api - 2.0.RC1-SNAPSHOT + 1.6-SNAPSHOT diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index 7276d2267..10aa1c233 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-generator-parent - 2.0.RC1-SNAPSHOT + 1.6-SNAPSHOT .. diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index bd78a73bc..b682ad036 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-generator-parent - 2.0.RC1-SNAPSHOT + 1.6-SNAPSHOT .. diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index 55f394873..6c074bfde 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-generator-parent - 2.0.RC1-SNAPSHOT + 1.6-SNAPSHOT .. diff --git a/pom.xml b/pom.xml index 054a171db..44ad14504 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-generator-parent - 2.0.RC1-SNAPSHOT + 1.6-SNAPSHOT pom @@ -39,7 +39,7 @@ http-generator-jex http-generator-helidon http-generator-client - tests + diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index e06a8a8ce..2e43332c7 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -37,7 +37,7 @@ io.avaje avaje-http-api - 2.0.RC1-SNAPSHOT + 1.6-SNAPSHOT @@ -93,7 +93,7 @@ io.avaje avaje-http-generator-client - 2.0.RC1-SNAPSHOT + 1.6-SNAPSHOT diff --git a/tests/test-helidon/pom.xml b/tests/test-helidon/pom.xml index 94ec05b12..b88733e23 100644 --- a/tests/test-helidon/pom.xml +++ b/tests/test-helidon/pom.xml @@ -17,7 +17,7 @@ org.example.Main 2.3.0 - 2.0.RC1-SNAPSHOT + 1.6-SNAPSHOT diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 52ea659d5..fb5c70135 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -20,7 +20,7 @@ 2.0.8 1.3.71 2.12.3 - 2.0.RC1-SNAPSHOT + 1.6-SNAPSHOT diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 998f2d5f2..24d5b3820 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -20,7 +20,7 @@ 2.0.8 2.12.3 6.0 - 2.0.RC1-SNAPSHOT + 1.6-SNAPSHOT diff --git a/tests/test-spark/pom.xml b/tests/test-spark/pom.xml index 3939f78eb..e3c7d527b 100644 --- a/tests/test-spark/pom.xml +++ b/tests/test-spark/pom.xml @@ -17,7 +17,7 @@ org.example.myapp.Main 2.0.8 - 2.0.RC1-SNAPSHOT + 1.6-SNAPSHOT @@ -76,7 +76,7 @@ io.avaje avaje-http-spark-generator - 2.0.RC1-SNAPSHOT + 1.6-SNAPSHOT provided From e80e5a48ee18b6a8a9c7f445c9225a7b847a6bf9 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Wed, 16 Jun 2021 22:36:11 +1200 Subject: [PATCH 0111/1323] [maven-release-plugin] prepare release avaje-http-generator-parent-1.6 --- http-api/pom.xml | 4 ++-- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 4 ++-- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- pom.xml | 4 ++-- 7 files changed, 10 insertions(+), 10 deletions(-) diff --git a/http-api/pom.xml b/http-api/pom.xml index 0df01a5c5..f7c6aaddb 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-generator-parent - 1.6-SNAPSHOT + 1.6 .. @@ -20,7 +20,7 @@ scm:git:git@github.com:avaje/avaje-http.git - HEAD + avaje-http-generator-parent-1.6 diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index bb2c40e66..efa8c1e14 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -5,7 +5,7 @@ io.avaje avaje-http-generator-parent - 1.6-SNAPSHOT + 1.6 .. diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 645f4f21b..5d93099a2 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-generator-parent - 1.6-SNAPSHOT + 1.6 .. @@ -33,7 +33,7 @@ io.avaje avaje-http-api - 1.6-SNAPSHOT + 1.6 diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index 10aa1c233..4ab41de72 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-generator-parent - 1.6-SNAPSHOT + 1.6 .. diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index b682ad036..1f0f61ba3 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-generator-parent - 1.6-SNAPSHOT + 1.6 .. diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index 6c074bfde..4a5e856b2 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-generator-parent - 1.6-SNAPSHOT + 1.6 .. diff --git a/pom.xml b/pom.xml index 44ad14504..c501820e1 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-generator-parent - 1.6-SNAPSHOT + 1.6 pom @@ -15,7 +15,7 @@ scm:git:git@github.com:avaje/avaje-http.git - HEAD + avaje-http-generator-parent-1.6 From 42ebfdd3f50444399e91b97e19886286e84f20d6 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Wed, 16 Jun 2021 22:36:20 +1200 Subject: [PATCH 0112/1323] [maven-release-plugin] prepare for next development iteration --- http-api/pom.xml | 4 ++-- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 4 ++-- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- pom.xml | 4 ++-- 7 files changed, 10 insertions(+), 10 deletions(-) diff --git a/http-api/pom.xml b/http-api/pom.xml index f7c6aaddb..296233edd 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-generator-parent - 1.6 + 1.7-SNAPSHOT .. @@ -20,7 +20,7 @@ scm:git:git@github.com:avaje/avaje-http.git - avaje-http-generator-parent-1.6 + HEAD diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index efa8c1e14..a8cd8abe1 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -5,7 +5,7 @@ io.avaje avaje-http-generator-parent - 1.6 + 1.7-SNAPSHOT .. diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 5d93099a2..a3c01a0ae 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-generator-parent - 1.6 + 1.7-SNAPSHOT .. @@ -33,7 +33,7 @@ io.avaje avaje-http-api - 1.6 + 1.7-SNAPSHOT diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index 4ab41de72..00f79d176 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-generator-parent - 1.6 + 1.7-SNAPSHOT .. diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index 1f0f61ba3..419756c14 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-generator-parent - 1.6 + 1.7-SNAPSHOT .. diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index 4a5e856b2..77e87476d 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-generator-parent - 1.6 + 1.7-SNAPSHOT .. diff --git a/pom.xml b/pom.xml index c501820e1..90c0554b4 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-generator-parent - 1.6 + 1.7-SNAPSHOT pom @@ -15,7 +15,7 @@ scm:git:git@github.com:avaje/avaje-http.git - avaje-http-generator-parent-1.6 + HEAD From c0a736a4b2b98dab6de65567f182bdb350317110 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Fri, 18 Jun 2021 16:23:30 +1200 Subject: [PATCH 0113/1323] Improve javadoc for HttpException --- .../io/avaje/http/client/HttpException.java | 32 ++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/http-client/client/src/main/java/io/avaje/http/client/HttpException.java b/http-client/client/src/main/java/io/avaje/http/client/HttpException.java index 21b183f1a..8d5a82ff6 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/HttpException.java +++ b/http-client/client/src/main/java/io/avaje/http/client/HttpException.java @@ -8,7 +8,37 @@ *

* Wraps an underlying HttpResponse with helper methods to get the response body * as string or as a bean. - *

+ * + *

Example catching HttpException

+ *
{@code
+ *
+ *   try {
+ *       clientContext.request()
+ *         .path("hello/saveForm")
+ *         .formParam("email", "user@foo.com")
+ *         .formParam("url", "notAValidUrl")
+ *         .POST()
+ *         .asVoid();
+ *
+ *     } catch (HttpException e) {
+ *
+ *       // obtain the statusCode from the exception ...
+ *       int statusCode = e.getStatusCode());
+ *
+ *       HttpResponse httpResponse = e.getHttpResponse();
+ *
+ *       // obtain the statusCode from httpResponse ...
+ *       int statusCode = httpResponse.statusCode();
+ *
+ *       // convert error response body into a bean (typically Jackson/Gson)
+ *       final MyErrorBean errorResponse = e.bean(MyErrorBean.class);
+ *
+ *       final Map errorMap = errorResponse.getErrors();
+ *       assertThat(errorMap.get("url")).isEqualTo("must be a valid URL");
+ *       assertThat(errorMap.get("name")).isEqualTo("must not be null");
+ *     }
+ *
+ * }
*/ public class HttpException extends RuntimeException { From ff0f6e4e826c12b8a5fd8f1d8f1575c64a34ed47 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Fri, 18 Jun 2021 16:51:26 +1200 Subject: [PATCH 0114/1323] Add async() execution for Void and String --- .../java/io/avaje/http/client/DHttpAsync.java | 28 +++++++++++++++++ .../avaje/http/client/DHttpClientContext.java | 9 ++++++ .../avaje/http/client/DHttpClientRequest.java | 30 +++++++++++++++---- .../avaje/http/client/HttpAsyncResponse.java | 21 +++++++++++++ .../avaje/http/client/HttpClientResponse.java | 5 ++++ .../http/client/HelloControllerTest.java | 27 +++++++++++++++++ .../java/org/example/github/GithubTest.java | 18 ++++++++++- 7 files changed, 131 insertions(+), 7 deletions(-) create mode 100644 http-client/client/src/main/java/io/avaje/http/client/DHttpAsync.java create mode 100644 http-client/client/src/main/java/io/avaje/http/client/HttpAsyncResponse.java diff --git a/http-client/client/src/main/java/io/avaje/http/client/DHttpAsync.java b/http-client/client/src/main/java/io/avaje/http/client/DHttpAsync.java new file mode 100644 index 000000000..1042bdf69 --- /dev/null +++ b/http-client/client/src/main/java/io/avaje/http/client/DHttpAsync.java @@ -0,0 +1,28 @@ +package io.avaje.http.client; + +import java.net.http.HttpResponse; +import java.util.concurrent.CompletableFuture; + +class DHttpAsync implements HttpAsyncResponse { + + private final DHttpClientRequest request; + + DHttpAsync(DHttpClientRequest request) { + this.request = request; + } + + @Override + public CompletableFuture> asDiscarding() { + return request + .performSendAsync(false, HttpResponse.BodyHandlers.discarding()) + .thenApply(request::afterAsync); + } + + @Override + public CompletableFuture> asString() { + return request + .performSendAsync(true, HttpResponse.BodyHandlers.ofString()) + .thenApply(request::afterAsync); + } + +} diff --git a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContext.java b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContext.java index bf6468186..ff3003d1c 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContext.java +++ b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContext.java @@ -9,6 +9,7 @@ import java.time.Duration; import java.util.List; import java.util.Map; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.atomic.AtomicReference; class DHttpClientContext implements HttpClientContext { @@ -29,6 +30,7 @@ class DHttpClientContext implements HttpClientContext { private final boolean withAuthToken; private final AuthTokenProvider authTokenProvider; private final AtomicReference tokenRef = new AtomicReference<>(); + private int loggingMaxBody = 1_000; DHttpClientContext(HttpClient httpClient, String baseUrl, Duration requestTimeout, BodyAdapter bodyAdapter, RetryHandler retryHandler, RequestListener requestListener, AuthTokenProvider authTokenProvider, RequestIntercept intercept) { this.httpClient = httpClient; @@ -155,6 +157,10 @@ HttpResponse send(HttpRequest.Builder requestBuilder, HttpResponse.BodyHa } } + CompletableFuture> sendAsync(HttpRequest.Builder requestBuilder, HttpResponse.BodyHandler bodyHandler) { + return httpClient.sendAsync(requestBuilder.build(), bodyHandler); + } + BodyContent write(Object bean, String contentType) { return bodyAdapter.beanWriter(bean.getClass()).write(bean, contentType); } @@ -198,4 +204,7 @@ private String authToken() { return authToken.token(); } + String maxResponseBody(String body) { + return body.length() > loggingMaxBody ? body.substring(0, loggingMaxBody) + " ..." : body; + } } diff --git a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java index 95f907d7f..27bac1079 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java +++ b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java @@ -13,6 +13,7 @@ import java.nio.file.Path; import java.time.*; import java.util.*; +import java.util.concurrent.CompletableFuture; import java.util.function.Supplier; import java.util.stream.Stream; @@ -49,6 +50,7 @@ class DHttpClientRequest implements HttpClientRequest, HttpClientResponse { private boolean loggableResponseBody; private boolean skipAuthToken; private boolean suppressLogging; + private long startAsyncNanos; DHttpClientRequest(DHttpClientContext context, Duration requestTimeout) { this.context = context; @@ -276,6 +278,11 @@ private void addHeaders() { } } + @Override + public HttpAsyncResponse async() { + return new DHttpAsync(this); + } + @Override public HttpClientResponse HEAD() { httpRequest = newHead(url.build()); @@ -378,6 +385,21 @@ protected HttpResponse performSend(HttpResponse.BodyHandler responseHa } } + protected CompletableFuture> performSendAsync(boolean loggable, HttpResponse.BodyHandler responseHandler) { + loggableResponseBody = loggable; + context.beforeRequest(this); + addHeaders(); + startAsyncNanos = System.nanoTime(); + return context.sendAsync(httpRequest, responseHandler); + } + + public HttpResponse afterAsync(HttpResponse response) { + requestTimeNanos = System.nanoTime() - startAsyncNanos; + httpResponse = response; + context.afterResponse(this); + return response; + } + @Override public HttpResponse asByteArray() { return withResponseHandler(HttpResponse.BodyHandlers.ofByteArray()); @@ -511,13 +533,9 @@ public String responseBody() { return ""; } if (encodedResponseBody != null) { - return new String(encodedResponseBody.content(), StandardCharsets.UTF_8); + return context.maxResponseBody(new String(encodedResponseBody.content(), StandardCharsets.UTF_8)); } else if (httpResponse != null && loggableResponseBody) { - String strBody = httpResponse.body().toString(); - if (strBody.length() > 1_000) { - return strBody.substring(0, 1_000) + "..."; - } - return strBody; + return context.maxResponseBody(httpResponse.body().toString()); } return null; } diff --git a/http-client/client/src/main/java/io/avaje/http/client/HttpAsyncResponse.java b/http-client/client/src/main/java/io/avaje/http/client/HttpAsyncResponse.java new file mode 100644 index 000000000..bad4d0d5b --- /dev/null +++ b/http-client/client/src/main/java/io/avaje/http/client/HttpAsyncResponse.java @@ -0,0 +1,21 @@ +package io.avaje.http.client; + +import java.net.http.HttpResponse; +import java.util.concurrent.CompletableFuture; + +/** + * Async responses as CompletableFuture. + */ +public interface HttpAsyncResponse { + + /** + * Process discarding response body as {@literal HttpResponse}. + */ + CompletableFuture> asDiscarding(); + + /** + * Process as String response body {@literal HttpResponse}. + */ + CompletableFuture> asString(); + +} diff --git a/http-client/client/src/main/java/io/avaje/http/client/HttpClientResponse.java b/http-client/client/src/main/java/io/avaje/http/client/HttpClientResponse.java index 8d1082091..186d23d8c 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/HttpClientResponse.java +++ b/http-client/client/src/main/java/io/avaje/http/client/HttpClientResponse.java @@ -12,6 +12,11 @@ */ public interface HttpClientResponse { + /** + * Send the request async using CompletableFuture. + */ + HttpAsyncResponse async(); + /** * Returning the response using the given response reader. * diff --git a/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java b/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java index 82180d4c6..ce85c0313 100644 --- a/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java +++ b/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java @@ -7,6 +7,8 @@ import java.net.http.HttpResponse; import java.util.List; import java.util.Map; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -44,6 +46,31 @@ void get_helloMessage() { assertThat(hres.statusCode()).isEqualTo(200); } + @Test + void async_get_asString() throws ExecutionException, InterruptedException { + + final CompletableFuture> future = clientContext.request() + .path("hello").path("message") + .GET() + .async().asString(); + + final HttpResponse hres = future.get(); + assertThat(hres.body()).contains("hello world"); + assertThat(hres.statusCode()).isEqualTo(200); + } + + @Test + void async_get_asDiscarding() throws ExecutionException, InterruptedException { + + final CompletableFuture> future = clientContext.request() + .path("hello").path("message") + .GET() + .async().asDiscarding(); + + final HttpResponse hres = future.get(); + assertThat(hres.statusCode()).isEqualTo(200); + } + @Test void get_helloMessage_via_url() { diff --git a/http-client/client/src/test/java/org/example/github/GithubTest.java b/http-client/client/src/test/java/org/example/github/GithubTest.java index 4709ba2e7..238fb28fa 100644 --- a/http-client/client/src/test/java/org/example/github/GithubTest.java +++ b/http-client/client/src/test/java/org/example/github/GithubTest.java @@ -4,6 +4,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import io.avaje.http.client.HttpClientContext; import io.avaje.http.client.JacksonBodyAdapter; +import io.avaje.http.client.RequestLogger; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; @@ -18,12 +19,27 @@ public class GithubTest { @Test @Disabled - void test() { + void test() throws InterruptedException { + final HttpClientContext clientContext = HttpClientContext.newBuilder() .withBaseUrl("https://api.github.com") .withBodyAdapter(bodyAdapter) + .withRequestListener(new RequestLogger()) .build(); + clientContext.request() + .path("users").path("rbygrave").path("repos") + .GET() + .async() + .asString() + .thenAccept(res -> { + + System.out.println("RES: "+res.statusCode()); + System.out.println("BODY: "+res.body()); + }); + + Thread.sleep(1_000); + // will not work under module classpath without registering the HttpApiProvider final Simple simple = clientContext.create(Simple.class); From 491e50d7cf773b981f9741b2654db4ed29b0ede1 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Fri, 18 Jun 2021 20:59:22 +1200 Subject: [PATCH 0115/1323] Tidy HttpException and JacksonBodyAdapter --- .../src/main/java/io/avaje/http/client/HttpException.java | 8 ++++---- .../java/io/avaje/http/client/JacksonBodyAdapter.java | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/http-client/client/src/main/java/io/avaje/http/client/HttpException.java b/http-client/client/src/main/java/io/avaje/http/client/HttpException.java index 8d5a82ff6..576062ffc 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/HttpException.java +++ b/http-client/client/src/main/java/io/avaje/http/client/HttpException.java @@ -43,7 +43,7 @@ public class HttpException extends RuntimeException { private final int statusCode; - private HttpClientContext context; + private DHttpClientContext context; private HttpResponse httpResponse; /** @@ -70,14 +70,14 @@ public HttpException(int statusCode, Throwable cause) { this.statusCode = statusCode; } - HttpException(HttpResponse httpResponse, HttpClientContext context) { + HttpException(HttpResponse httpResponse, DHttpClientContext context) { super(); this.httpResponse = httpResponse; this.statusCode = httpResponse.statusCode(); this.context = context; } - HttpException(HttpClientContext context, HttpResponse httpResponse) { + HttpException(DHttpClientContext context, HttpResponse httpResponse) { super(); this.httpResponse = httpResponse; this.statusCode = httpResponse.statusCode(); @@ -93,7 +93,7 @@ public HttpException(int statusCode, Throwable cause) { @SuppressWarnings("unchecked") public T bean(Class cls) { final BodyContent body = context.readContent((HttpResponse) httpResponse); - return context.converters().beanReader(cls).read(body); + return context.readBean(cls, body); } /** diff --git a/http-client/client/src/main/java/io/avaje/http/client/JacksonBodyAdapter.java b/http-client/client/src/main/java/io/avaje/http/client/JacksonBodyAdapter.java index 702ee480c..049aee16d 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/JacksonBodyAdapter.java +++ b/http-client/client/src/main/java/io/avaje/http/client/JacksonBodyAdapter.java @@ -93,9 +93,9 @@ public T readBody(String content) { } @Override - public T read(BodyContent s) { + public T read(BodyContent bodyContent) { try { - return reader.readValue(s.content()); + return reader.readValue(bodyContent.content()); } catch (IOException e) { throw new RuntimeException(e); } From 7a25baaae46cacf889a46321c1b4a9eb0e41e0f3 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Fri, 18 Jun 2021 21:17:41 +1200 Subject: [PATCH 0116/1323] Add Async bean() support --- .../java/io/avaje/http/client/DHttpAsync.java | 6 + .../avaje/http/client/DHttpClientContext.java | 2 +- .../avaje/http/client/DHttpClientRequest.java | 11 +- .../avaje/http/client/HttpAsyncResponse.java | 33 ++++++ .../http/client/HelloControllerTest.java | 105 ++++++++++++++++++ 5 files changed, 155 insertions(+), 2 deletions(-) diff --git a/http-client/client/src/main/java/io/avaje/http/client/DHttpAsync.java b/http-client/client/src/main/java/io/avaje/http/client/DHttpAsync.java index 1042bdf69..7fb6da80e 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/DHttpAsync.java +++ b/http-client/client/src/main/java/io/avaje/http/client/DHttpAsync.java @@ -25,4 +25,10 @@ public CompletableFuture> asString() { .thenApply(request::afterAsync); } + @Override + public CompletableFuture bean(Class type) { + return request + .performSendAsync(true, HttpResponse.BodyHandlers.ofByteArray()) + .thenApply(httpResponse -> request.asyncBean(type, httpResponse)); + } } diff --git a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContext.java b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContext.java index ff3003d1c..496a482c7 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContext.java +++ b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContext.java @@ -100,7 +100,7 @@ public void checkResponse(HttpResponse response) { } } - void check(HttpResponse response) { + void checkMaybeThrow(HttpResponse response) { if (response.statusCode() >= 300) { throw new HttpException(this, response); } diff --git a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java index 27bac1079..0fe002227 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java +++ b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java @@ -327,7 +327,7 @@ public HttpClientResponse TRACE() { private void readResponseContent() { final HttpResponse response = asByteArray(); this.httpResponse = response; - context.check(response); + context.checkMaybeThrow(response); encodedResponseBody = context.readContent(response); } @@ -393,6 +393,15 @@ protected CompletableFuture> performSendAsync(boolean loggab return context.sendAsync(httpRequest, responseHandler); } + protected E asyncBean(Class type, HttpResponse response) { + requestTimeNanos = System.nanoTime() - startAsyncNanos; + httpResponse = response; + encodedResponseBody = context.readContent(response); + context.afterResponse(this); + context.checkMaybeThrow(response); + return context.readBean(type, encodedResponseBody); + } + public HttpResponse afterAsync(HttpResponse response) { requestTimeNanos = System.nanoTime() - startAsyncNanos; httpResponse = response; diff --git a/http-client/client/src/main/java/io/avaje/http/client/HttpAsyncResponse.java b/http-client/client/src/main/java/io/avaje/http/client/HttpAsyncResponse.java index bad4d0d5b..c9e583e9c 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/HttpAsyncResponse.java +++ b/http-client/client/src/main/java/io/avaje/http/client/HttpAsyncResponse.java @@ -18,4 +18,37 @@ public interface HttpAsyncResponse { */ CompletableFuture> asString(); + /** + * Process expecting a (json) bean response body. + *

+ * If the HTTP statusCode is 300 or above a HttpException is throw which + * contains the HttpResponse. + * + *

{@code
+   *
+   *    clientContext.request()
+   *       ...
+   *       .POST().async()
+   *       .bean(HelloDto.class)
+   *       .whenComplete((helloDto, throwable) -> {
+   *
+   *         if (throwable != null) {
+   *           HttpException httpException = (HttpException) throwable.getCause();
+   *           int statusCode = httpException.getStatusCode();
+   *
+   *           // maybe convert json error response body to a bean (using Jackson/Gson)
+   *           MyErrorBean errorResponse = httpException.bean(MyErrorBean.class);
+   *           ..
+   *
+   *         } else {
+   *           // use helloDto
+   *           ...
+   *         }
+   *
+   *       });
+   *
+   *
+   * }
+ */ + CompletableFuture bean(Class type); } diff --git a/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java b/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java index ce85c0313..5c8e8fd99 100644 --- a/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java +++ b/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java @@ -8,7 +8,10 @@ import java.util.List; import java.util.Map; import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionException; import java.util.concurrent.ExecutionException; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -106,6 +109,108 @@ void get_withPathParamAndQueryParam_returningBean() { assertThat(dto.otherParam).isEqualTo("other"); } + @Test + void async_whenComplete_returningBean() throws ExecutionException, InterruptedException { + + final AtomicInteger counter = new AtomicInteger(); + final AtomicReference ref = new AtomicReference<>(); + + final CompletableFuture future = clientContext.request() + .path("hello/43/2020-03-05").queryParam("otherParam", "other").queryParam("foo", null) + .GET() + .async().bean(HelloDto.class); + + future.whenComplete((dto, throwable) -> { + counter.incrementAndGet(); + ref.set(dto); + + assertThat(throwable).isNull(); + assertThat(dto.id).isEqualTo(43L); + assertThat(dto.name).isEqualTo("2020-03-05"); + assertThat(dto.otherParam).isEqualTo("other"); + }); + + // wait ... + final HelloDto dto = future.get(); + assertThat(counter.incrementAndGet()).isEqualTo(2); + assertThat(dto).isSameAs(ref.get()); + + assertThat(dto.id).isEqualTo(43L); + assertThat(dto.name).isEqualTo("2020-03-05"); + assertThat(dto.otherParam).isEqualTo("other"); + } + + @Test + void async_whenComplete_throwingHttpException() { + + AtomicReference causeRef = new AtomicReference<>(); + + final CompletableFuture future = clientContext.request() + .path("hello/saveform3") + .formParam("name", "Bax") + .formParam("email", "notValidEmail") + .formParam("url", "notValidUrl") + .formParam("startDate", "2030-12-03") + .POST() + .async() + .bean(HelloDto.class) + .whenComplete((helloDto, throwable) -> { + // we get a throwable + assertThat(throwable.getCause()).isInstanceOf(HttpException.class); + assertThat(helloDto).isNull(); + + final HttpException httpException = (HttpException) throwable.getCause(); + causeRef.set(httpException); + assertThat(httpException.getStatusCode()).isEqualTo(422); + + // convert json error response body to a bean + final ErrorResponse errorResponse = httpException.bean(ErrorResponse.class); + + final Map errorMap = errorResponse.getErrors(); + assertThat(errorMap.get("url")).isEqualTo("must be a valid URL"); + assertThat(errorMap.get("email")).isEqualTo("must be a well-formed email address"); + }); + + try { + future.join(); + } catch (CompletionException e) { + assertThat(e.getCause()).isSameAs(causeRef.get()); + } + } + + @Test + void async_exceptionally_style() { + + AtomicReference causeRef = new AtomicReference<>(); + + final CompletableFuture future = clientContext.request() + .path("hello/saveform3") + .formParam("name", "Bax") + .formParam("email", "notValidEmail") + .formParam("url", "notValidUrl") + .formParam("startDate", "2030-12-03") + .POST() + .async() + .bean(HelloDto.class); + + future.exceptionally(throwable -> { + final HttpException httpException = (HttpException) throwable.getCause(); + causeRef.set(httpException); + assertThat(httpException.getStatusCode()).isEqualTo(422); + + return new HelloDto(0, "ErrorResponse", ""); + + }).thenAccept(helloDto -> { + assertThat(helloDto.name).isEqualTo("ErrorResponse"); + }); + + try { + future.join(); + } catch (CompletionException e) { + assertThat(e.getCause()).isSameAs(causeRef.get()); + } + } + @Test void post_bean_returningBean_usingExplicitConverters() { From c6a613cf1e9b9c1ebca604ff28097f04933fe24a Mon Sep 17 00:00:00 2001 From: rbygrave Date: Fri, 18 Jun 2021 21:25:20 +1200 Subject: [PATCH 0117/1323] Improve javadoc for HttpAsyncResponse --- .../avaje/http/client/HttpAsyncResponse.java | 39 ++++++++++++++++++- .../http/client/HelloControllerTest.java | 10 ++++- 2 files changed, 47 insertions(+), 2 deletions(-) diff --git a/http-client/client/src/main/java/io/avaje/http/client/HttpAsyncResponse.java b/http-client/client/src/main/java/io/avaje/http/client/HttpAsyncResponse.java index c9e583e9c..6eaccc295 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/HttpAsyncResponse.java +++ b/http-client/client/src/main/java/io/avaje/http/client/HttpAsyncResponse.java @@ -10,16 +10,53 @@ public interface HttpAsyncResponse { /** * Process discarding response body as {@literal HttpResponse}. + * + *
{@code
+   *
+   *   clientContext.request()
+   *       .path("hello/world")
+   *       .GET()
+   *       .async().asDiscarding()
+   *       .whenComplete((hres, throwable) -> {
+   *
+   *         if (throwable != null) {
+   *           ...
+   *         } else {
+   *           int statusCode = hres.statusCode();
+   *           ...
+   *         }
+   *       });
+   *
+   * }
*/ CompletableFuture> asDiscarding(); /** * Process as String response body {@literal HttpResponse}. + * + *
{@code
+   *
+   *   clientContext.request()
+   *       .path("hello/world")
+   *       .GET()
+   *       .async().asString()
+   *       .whenComplete((hres, throwable) -> {
+   *
+   *         if (throwable != null) {
+   *           ...
+   *         } else {
+   *           int statusCode = hres.statusCode();
+   *           String body = hres.body();
+   *           ...
+   *         }
+   *       });
+   *
+   * }
*/ CompletableFuture> asString(); /** - * Process expecting a (json) bean response body. + * Process expecting a bean response body (typically from json content). *

* If the HTTP statusCode is 300 or above a HttpException is throw which * contains the HttpResponse. diff --git a/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java b/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java index 5c8e8fd99..9974d447e 100644 --- a/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java +++ b/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java @@ -52,12 +52,20 @@ void get_helloMessage() { @Test void async_get_asString() throws ExecutionException, InterruptedException { + AtomicReference> ref = new AtomicReference<>(); + final CompletableFuture> future = clientContext.request() .path("hello").path("message") .GET() - .async().asString(); + .async().asString() + .whenComplete((hres, throwable) -> { + ref.set(hres); + assertThat(hres.statusCode()).isEqualTo(200); + assertThat(hres.body()).contains("hello world"); + }); final HttpResponse hres = future.get(); + assertThat(hres).isSameAs(ref.get()); assertThat(hres.body()).contains("hello world"); assertThat(hres.statusCode()).isEqualTo(200); } From 3df2ad6d51cd0306386e6a30903aa5a229ff72c2 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Fri, 18 Jun 2021 21:37:46 +1200 Subject: [PATCH 0118/1323] Add Async list() of beans support --- .../java/io/avaje/http/client/DHttpAsync.java | 8 +++++ .../avaje/http/client/DHttpClientRequest.java | 13 ++++++-- .../avaje/http/client/HttpAsyncResponse.java | 31 +++++++++++++++++-- .../http/client/HelloControllerTest.java | 21 +++++++++++++ 4 files changed, 69 insertions(+), 4 deletions(-) diff --git a/http-client/client/src/main/java/io/avaje/http/client/DHttpAsync.java b/http-client/client/src/main/java/io/avaje/http/client/DHttpAsync.java index 7fb6da80e..733c00d2c 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/DHttpAsync.java +++ b/http-client/client/src/main/java/io/avaje/http/client/DHttpAsync.java @@ -1,6 +1,7 @@ package io.avaje.http.client; import java.net.http.HttpResponse; +import java.util.List; import java.util.concurrent.CompletableFuture; class DHttpAsync implements HttpAsyncResponse { @@ -31,4 +32,11 @@ public CompletableFuture bean(Class type) { .performSendAsync(true, HttpResponse.BodyHandlers.ofByteArray()) .thenApply(httpResponse -> request.asyncBean(type, httpResponse)); } + + @Override + public CompletableFuture> list(Class type) { + return request + .performSendAsync(true, HttpResponse.BodyHandlers.ofByteArray()) + .thenApply(httpResponse -> request.asyncList(type, httpResponse)); + } } diff --git a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java index 0fe002227..ada58ec6a 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java +++ b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java @@ -394,15 +394,24 @@ protected CompletableFuture> performSendAsync(boolean loggab } protected E asyncBean(Class type, HttpResponse response) { + afterAsyncEncoded(response); + return context.readBean(type, encodedResponseBody); + } + + protected List asyncList(Class type, HttpResponse response) { + afterAsyncEncoded(response); + return context.readList(type, encodedResponseBody); + } + + private void afterAsyncEncoded(HttpResponse response) { requestTimeNanos = System.nanoTime() - startAsyncNanos; httpResponse = response; encodedResponseBody = context.readContent(response); context.afterResponse(this); context.checkMaybeThrow(response); - return context.readBean(type, encodedResponseBody); } - public HttpResponse afterAsync(HttpResponse response) { + protected HttpResponse afterAsync(HttpResponse response) { requestTimeNanos = System.nanoTime() - startAsyncNanos; httpResponse = response; context.afterResponse(this); diff --git a/http-client/client/src/main/java/io/avaje/http/client/HttpAsyncResponse.java b/http-client/client/src/main/java/io/avaje/http/client/HttpAsyncResponse.java index 6eaccc295..6b6442df3 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/HttpAsyncResponse.java +++ b/http-client/client/src/main/java/io/avaje/http/client/HttpAsyncResponse.java @@ -1,6 +1,7 @@ package io.avaje.http.client; import java.net.http.HttpResponse; +import java.util.List; import java.util.concurrent.CompletableFuture; /** @@ -81,11 +82,37 @@ public interface HttpAsyncResponse { * // use helloDto * ... * } - * * }); + * } + */ + CompletableFuture bean(Class type); + + /** + * Process expecting a list of beans response body (typically from json content). + *

+ * If the HTTP statusCode is 300 or above a HttpException is throw which + * contains the HttpResponse. + * + *

{@code
+   *
+   *    clientContext.request()
+   *       ...
+   *       .GET().async()
+   *       .list(HelloDto.class)
+   *       .whenComplete((helloDtos, throwable) -> {
    *
+   *         if (throwable != null) {
+   *           HttpException httpException = (HttpException) throwable.getCause();
+   *           int statusCode = httpException.getStatusCode();
+   *           ...
    *
+   *         } else {
+   *           // use list of helloDto
+   *           ...
+   *         }
+   *       });
    * }
*/ - CompletableFuture bean(Class type); + CompletableFuture> list(Class type); + } diff --git a/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java b/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java index 9974d447e..fc6ea8d67 100644 --- a/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java +++ b/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java @@ -104,6 +104,27 @@ void get_hello_returningListOfBeans() { assertThat(helloDtos).hasSize(2); } + @Test + void async_list() throws ExecutionException, InterruptedException { + + AtomicReference> ref = new AtomicReference<>(); + + final CompletableFuture> future = clientContext.request() + .path("hello") + .GET().async() + .list(HelloDto.class); + + future.whenComplete((helloDtos, throwable) -> { + assertThat(throwable).isNull(); + assertThat(helloDtos).hasSize(2); + ref.set(helloDtos); + }); + + final List helloDtos = future.get(); + assertThat(helloDtos).hasSize(2); + assertThat(helloDtos).isSameAs(ref.get()); + } + @Test void get_withPathParamAndQueryParam_returningBean() { From 681e7bab6ac9da4f8d64b3ebf3f368752fdb7af1 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Fri, 18 Jun 2021 22:31:16 +1200 Subject: [PATCH 0119/1323] Add Async withHandler() support for any response body handler --- .../java/io/avaje/http/client/DHttpAsync.java | 9 +++- .../avaje/http/client/DHttpClientRequest.java | 3 +- .../avaje/http/client/HttpAsyncResponse.java | 54 ++++++++++++++++++- .../http/client/HelloControllerTest.java | 51 ++++++++++++++++++ 4 files changed, 113 insertions(+), 4 deletions(-) diff --git a/http-client/client/src/main/java/io/avaje/http/client/DHttpAsync.java b/http-client/client/src/main/java/io/avaje/http/client/DHttpAsync.java index 733c00d2c..e7fb69e79 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/DHttpAsync.java +++ b/http-client/client/src/main/java/io/avaje/http/client/DHttpAsync.java @@ -13,12 +13,17 @@ class DHttpAsync implements HttpAsyncResponse { } @Override - public CompletableFuture> asDiscarding() { + public CompletableFuture> withHandler(HttpResponse.BodyHandler handler) { return request - .performSendAsync(false, HttpResponse.BodyHandlers.discarding()) + .performSendAsync(false, handler) .thenApply(request::afterAsync); } + @Override + public CompletableFuture> asDiscarding() { + return withHandler(HttpResponse.BodyHandlers.discarding()); + } + @Override public CompletableFuture> asString() { return request diff --git a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java index ada58ec6a..aa7a26204 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java +++ b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java @@ -553,7 +553,8 @@ public String responseBody() { if (encodedResponseBody != null) { return context.maxResponseBody(new String(encodedResponseBody.content(), StandardCharsets.UTF_8)); } else if (httpResponse != null && loggableResponseBody) { - return context.maxResponseBody(httpResponse.body().toString()); + final Object body = httpResponse.body(); + return (body == null) ? null : context.maxResponseBody(body.toString()); } return null; } diff --git a/http-client/client/src/main/java/io/avaje/http/client/HttpAsyncResponse.java b/http-client/client/src/main/java/io/avaje/http/client/HttpAsyncResponse.java index 6b6442df3..527ca91fe 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/HttpAsyncResponse.java +++ b/http-client/client/src/main/java/io/avaje/http/client/HttpAsyncResponse.java @@ -5,7 +5,7 @@ import java.util.concurrent.CompletableFuture; /** - * Async responses as CompletableFuture. + * Async processing of the request with responses as CompletableFuture. */ public interface HttpAsyncResponse { @@ -29,6 +29,8 @@ public interface HttpAsyncResponse { * }); * * } + * + * @return The CompletableFuture of the response */ CompletableFuture> asDiscarding(); @@ -53,9 +55,53 @@ public interface HttpAsyncResponse { * }); * * } + * + * @return The CompletableFuture of the response */ CompletableFuture> asString(); + /** + * Process with any given {@code HttpResponse.BodyHandler}. + * + *

Example: line subscriber

+ *

+ * Subscribe line by line to the response. + *

+ *
{@code
+   *
+   *    CompletableFuture> future = clientContext.request()
+   *       .path("hello/lineStream")
+   *       .GET().async()
+   *       .withHandler(HttpResponse.BodyHandlers.fromLineSubscriber(new Flow.Subscriber<>() {
+   *
+   *         @Override
+   *         public void onSubscribe(Flow.Subscription subscription) {
+   *           subscription.request(Long.MAX_VALUE);
+   *         }
+   *         @Override
+   *         public void onNext(String item) {
+   *           ...
+   *         }
+   *         @Override
+   *         public void onError(Throwable throwable) {
+   *           ...
+   *         }
+   *         @Override
+   *         public void onComplete() {
+   *           ...
+   *         }
+   *       }))
+   *       .whenComplete((hres, throwable) -> {
+   *         int statusCode = hres.statusCode();
+   *         ...
+   *       });
+   * }
+ * + * @param bodyHandlers The body handler to use to process the response + * @return The CompletableFuture of the response + */ + CompletableFuture> withHandler(HttpResponse.BodyHandler bodyHandlers); + /** * Process expecting a bean response body (typically from json content). *

@@ -84,6 +130,9 @@ public interface HttpAsyncResponse { * } * }); * } + * + * @param type The bean type to convert the content to + * @return The CompletableFuture of the response */ CompletableFuture bean(Class type); @@ -112,6 +161,9 @@ public interface HttpAsyncResponse { * } * }); * } + * + * @param type The bean type to convert the content to + * @return The CompletableFuture of the response */ CompletableFuture> list(Class type); diff --git a/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java b/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java index fc6ea8d67..bebc6813a 100644 --- a/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java +++ b/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java @@ -5,11 +5,13 @@ import org.junit.jupiter.api.Test; import java.net.http.HttpResponse; +import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionException; import java.util.concurrent.ExecutionException; +import java.util.concurrent.Flow; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicReference; import java.util.stream.Collectors; @@ -38,6 +40,55 @@ void get_stream() { assertThat(first.name).isEqualTo("one"); } + @Test + void async_stream() throws ExecutionException, InterruptedException { + + AtomicReference> hresRef = new AtomicReference<>(); + AtomicReference errRef = new AtomicReference<>(); + AtomicReference completeRef = new AtomicReference<>(); + AtomicReference onSubscribeRef = new AtomicReference<>(); + + final List lines = new ArrayList<>(); + + final CompletableFuture> future = clientContext.request() + .path("hello/stream") + .GET() + .async().withHandler(HttpResponse.BodyHandlers.fromLineSubscriber(new Flow.Subscriber<>() { + @Override + public void onSubscribe(Flow.Subscription subscription) { + subscription.request(Long.MAX_VALUE); + onSubscribeRef.set(true); + } + @Override + public void onNext(String item) { + lines.add(item); + } + @Override + public void onError(Throwable throwable) { + errRef.set(throwable); + } + @Override + public void onComplete() { + completeRef.set(true); + } + })).whenComplete((hres, throwable) -> { + hresRef.set(hres); + assertThat(hres.statusCode()).isEqualTo(200); + assertThat(throwable).isNull(); + }); + + // just wait + assertThat(future.get()).isSameAs(hresRef.get()); + + assertThat(onSubscribeRef.get()).isTrue(); + assertThat(completeRef.get()).isTrue(); + assertThat(errRef.get()).isNull(); + assertThat(lines).hasSize(4); + + final String first = lines.get(0); + assertThat(first).isEqualTo("{\"id\":1, \"name\":\"one\"}"); + } + @Test void get_helloMessage() { From c58a03c53d3b3166be7112f6bf62c73b8b96f94b Mon Sep 17 00:00:00 2001 From: rbygrave Date: Fri, 18 Jun 2021 22:35:53 +1200 Subject: [PATCH 0120/1323] Refactor rename method withResponseHandler() to withHandler() with deprecation --- .../avaje/http/client/DHttpClientRequest.java | 18 +++++++++--------- .../avaje/http/client/HttpClientResponse.java | 10 +++++++++- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java index aa7a26204..8340cbea3 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java +++ b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java @@ -357,7 +357,7 @@ public List list(Class cls) { @Override public Stream stream(Class cls) { - final HttpResponse> res = withResponseHandler(HttpResponse.BodyHandlers.ofLines()); + final HttpResponse> res = withHandler(HttpResponse.BodyHandlers.ofLines()); this.httpResponse = res; if (res.statusCode() >= 300) { throw new HttpException(res, context); @@ -367,7 +367,7 @@ public Stream stream(Class cls) { } @Override - public HttpResponse withResponseHandler(HttpResponse.BodyHandler responseHandler) { + public HttpResponse withHandler(HttpResponse.BodyHandler responseHandler) { context.beforeRequest(this); addHeaders(); HttpResponse response = performSend(responseHandler); @@ -420,33 +420,33 @@ protected HttpResponse afterAsync(HttpResponse response) { @Override public HttpResponse asByteArray() { - return withResponseHandler(HttpResponse.BodyHandlers.ofByteArray()); + return withHandler(HttpResponse.BodyHandlers.ofByteArray()); } @Override public HttpResponse asString() { loggableResponseBody = true; - return withResponseHandler(HttpResponse.BodyHandlers.ofString()); + return withHandler(HttpResponse.BodyHandlers.ofString()); } @Override public HttpResponse asDiscarding() { - return withResponseHandler(discarding()); + return withHandler(discarding()); } @Override public HttpResponse asInputStream() { - return withResponseHandler(HttpResponse.BodyHandlers.ofInputStream()); + return withHandler(HttpResponse.BodyHandlers.ofInputStream()); } @Override public HttpResponse asFile(Path file) { - return withResponseHandler(HttpResponse.BodyHandlers.ofFile(file)); + return withHandler(HttpResponse.BodyHandlers.ofFile(file)); } @Override public HttpResponse> asLines() { - return withResponseHandler(HttpResponse.BodyHandlers.ofLines()); + return withHandler(HttpResponse.BodyHandlers.ofLines()); } private HttpRequest.Builder newReq(String url) { @@ -564,7 +564,7 @@ static class HttpVoidResponse implements HttpResponse { private final HttpResponse orig; - @SuppressWarnings({"unchecked", "raw"}) + @SuppressWarnings({"raw"}) HttpVoidResponse(HttpResponse orig) { this.orig = orig; } diff --git a/http-client/client/src/main/java/io/avaje/http/client/HttpClientResponse.java b/http-client/client/src/main/java/io/avaje/http/client/HttpClientResponse.java index 186d23d8c..90a75e354 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/HttpClientResponse.java +++ b/http-client/client/src/main/java/io/avaje/http/client/HttpClientResponse.java @@ -108,6 +108,14 @@ public interface HttpClientResponse { /** * Return the response using the given response body handler. */ - HttpResponse withResponseHandler(HttpResponse.BodyHandler responseHandler); + HttpResponse withHandler(HttpResponse.BodyHandler responseHandler); + + /** + * Deprecated migrate to {@link #withHandler(HttpResponse.BodyHandler)} + */ + @Deprecated + default HttpResponse withResponseHandler(HttpResponse.BodyHandler responseHandler) { + return withHandler(responseHandler); + } } From 0369e0699c668bf7f2cfaf2c32033b6ad099bfd0 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Fri, 18 Jun 2021 22:50:02 +1200 Subject: [PATCH 0121/1323] Update README --- http-client/README.md | 101 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) diff --git a/http-client/README.md b/http-client/README.md index 8248a1a8e..a751f3392 100644 --- a/http-client/README.md +++ b/http-client/README.md @@ -147,6 +147,107 @@ assertThat(res.statusCode()).isEqualTo(201); ## Currently, NO support for POSTing multipart-form +## Async processing + +### .async().asDiscarding() - HttpResponse + +```java + +clientContext.request() + .path("hello/world") + .GET() + .async().asDiscarding() + .whenComplete((hres, throwable) -> { + + if (throwable != null) { + ... + } else { + int statusCode = hres.statusCode(); + ... + } + }); + +``` + +### .async().asString() - HttpResponse + +```java +clientContext.request() + .path("hello/world") + .GET() + .async().asString() + .whenComplete((hres, throwable) -> { + + if (throwable != null) { + ... + } else { + int statusCode = hres.statusCode(); + String body = hres.body(); + ... + } + }); +``` + +### .async().bean(HelloDto.class) + +```java +clientContext.request() + ... + .POST().async() + .bean(HelloDto.class) + .whenComplete((helloDto, throwable) -> { + + if (throwable != null) { + HttpException httpException = (HttpException) throwable.getCause(); + int statusCode = httpException.getStatusCode(); + + // maybe convert json error response body to a bean (using Jackson/Gson) + MyErrorBean errorResponse = httpException.bean(MyErrorBean.class); + .. + + } else { + // use helloDto + ... + } + }); + +``` + +### .async().withHandler(...) - Any response body handler + +The example below is a line subscriber processing response content line by line. + +```java +CompletableFuture> future = clientContext.request() + .path("hello/lineStream") + .GET().async() + .withHandler(HttpResponse.BodyHandlers.fromLineSubscriber(new Flow.Subscriber<>() { + + @Override + public void onSubscribe(Flow.Subscription subscription) { + subscription.request(Long.MAX_VALUE); + } + @Override + public void onNext(String item) { + ... + } + @Override + public void onError(Throwable throwable) { + ... + } + @Override + public void onComplete() { + ... + } + })) + .whenComplete((hres, throwable) -> { + int statusCode = hres.statusCode(); + ... + }); + +``` + + ## Auth token Built in support for obtaining and setting an Authorization token. From db2987298c92f4b86490755a426d3c9420a96e04 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Fri, 18 Jun 2021 22:55:38 +1200 Subject: [PATCH 0122/1323] Update README --- http-client/README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/http-client/README.md b/http-client/README.md index a751f3392..4ae17039e 100644 --- a/http-client/README.md +++ b/http-client/README.md @@ -43,7 +43,8 @@ From HttpClientContext: - Optionally set headers(), cookies() etc - Optionally specify a request body (JSON, form, or raw BodyPublisher) - Http verbs - GET(), POST(), PUT(), PATCH(), DELETE(), HEAD(), TRACE() - - Optionally return response body as a bean, list of beans, or raw + - Optionally return response body as a bean, list of beans, stream of beans or various raw response types + - Optionally use Async processing of the request ## Examples @@ -149,7 +150,7 @@ assertThat(res.statusCode()).isEqualTo(201); ## Async processing -### .async().asDiscarding() - HttpResponse +### .async().asDiscarding() - HttpResponse<Void> ```java @@ -169,7 +170,7 @@ clientContext.request() ``` -### .async().asString() - HttpResponse +### .async().asString() - HttpResponse<String> ```java clientContext.request() From 1b2306ecf0261c5d4739d899bb2a4ae996f69689 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Sun, 20 Jun 2021 16:39:10 +1200 Subject: [PATCH 0123/1323] #19 - ENH: Add Basic Authentication support - BasicAuthIntercept --- .../avaje/http/client/BasicAuthIntercept.java | 38 +++++++++++++++++++ .../avaje/http/client/DHttpClientRequest.java | 6 +++ .../avaje/http/client/HttpClientRequest.java | 8 ++++ .../http/client/BasicAuthInterceptTest.java | 30 +++++++++++++++ .../avaje/http/client/HelloBasicAuthTest.java | 35 +++++++++++++++++ .../webserver/HelloController$Route.java | 6 +++ .../example/webserver/HelloController.java | 20 ++++++---- 7 files changed, 135 insertions(+), 8 deletions(-) create mode 100644 http-client/client/src/main/java/io/avaje/http/client/BasicAuthIntercept.java create mode 100644 http-client/client/src/test/java/io/avaje/http/client/BasicAuthInterceptTest.java create mode 100644 http-client/client/src/test/java/io/avaje/http/client/HelloBasicAuthTest.java diff --git a/http-client/client/src/main/java/io/avaje/http/client/BasicAuthIntercept.java b/http-client/client/src/main/java/io/avaje/http/client/BasicAuthIntercept.java new file mode 100644 index 000000000..4b02fdcca --- /dev/null +++ b/http-client/client/src/main/java/io/avaje/http/client/BasicAuthIntercept.java @@ -0,0 +1,38 @@ +package io.avaje.http.client; + +import java.net.http.HttpResponse; +import java.util.Base64; + +import static java.nio.charset.StandardCharsets.UTF_8; + +/** + * Adds Basic Authorization header to requests. + */ +public class BasicAuthIntercept implements RequestIntercept { + + private final String headerValue; + + /** + * Construct with the username and password. + */ + public BasicAuthIntercept(String username, String password) { + this.headerValue = "Basic "+encode(username, password); + } + + /** + * Return Base64 encoding of {@literal username:password} + */ + public static String encode(String username, String password) { + return Base64.getEncoder().encodeToString((username + ":" + password).getBytes(UTF_8)); + } + + @Override + public void beforeRequest(HttpClientRequest request) { + request.header("Authorization", headerValue); + } + + @Override + public void afterResponse(HttpResponse response, HttpClientRequest request) { + // do nothing + } +} diff --git a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java index 8340cbea3..e1f26ad5d 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java +++ b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java @@ -91,6 +91,12 @@ public HttpClientRequest header(String name, Object value) { return value != null ? header(name, value.toString()) : this; } + @Override + public List header(String name) { + final List values = headers.get(name); + return values == null ? Collections.emptyList() : values; + } + @Override public HttpClientRequest gzip(boolean gzip) { this.gzip = gzip; diff --git a/http-client/client/src/main/java/io/avaje/http/client/HttpClientRequest.java b/http-client/client/src/main/java/io/avaje/http/client/HttpClientRequest.java index 2409d1f89..8196435bf 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/HttpClientRequest.java +++ b/http-client/client/src/main/java/io/avaje/http/client/HttpClientRequest.java @@ -5,6 +5,7 @@ import java.net.http.HttpRequest; import java.nio.file.Path; import java.time.Duration; +import java.util.List; import java.util.function.Supplier; /** @@ -69,6 +70,13 @@ public interface HttpClientRequest { */ HttpClientRequest header(String name, Object value); + /** + * Return the header values that have been set for the given header name. + * + * @return The headers values or an empty collection if the header has not been specified yet. + */ + List header(String name); + /** * Set if body content should be gzip encoded. * diff --git a/http-client/client/src/test/java/io/avaje/http/client/BasicAuthInterceptTest.java b/http-client/client/src/test/java/io/avaje/http/client/BasicAuthInterceptTest.java new file mode 100644 index 000000000..a2df5cd59 --- /dev/null +++ b/http-client/client/src/test/java/io/avaje/http/client/BasicAuthInterceptTest.java @@ -0,0 +1,30 @@ +package io.avaje.http.client; + +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +class BasicAuthInterceptTest { + + @Test + void encode() { + final String encode = BasicAuthIntercept.encode("Aladdin", "open sesame"); + assertThat(encode).isEqualTo("QWxhZGRpbjpvcGVuIHNlc2FtZQ=="); + } + + @Test + void beforeRequest() { + // setup + final BasicAuthIntercept intercept = new BasicAuthIntercept("Aladdin", "open sesame"); + final HttpClientContext ctx = HttpClientContext.newBuilder().withBaseUrl("junk").build(); + + // act + final HttpClientRequest request = ctx.request(); + intercept.beforeRequest(request); + + final List values = request.header("Authorization"); + assertThat(values).containsExactly("Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ=="); + } +} diff --git a/http-client/client/src/test/java/io/avaje/http/client/HelloBasicAuthTest.java b/http-client/client/src/test/java/io/avaje/http/client/HelloBasicAuthTest.java new file mode 100644 index 000000000..edfe57d92 --- /dev/null +++ b/http-client/client/src/test/java/io/avaje/http/client/HelloBasicAuthTest.java @@ -0,0 +1,35 @@ +package io.avaje.http.client; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.jupiter.api.Test; + +import java.net.http.HttpResponse; + +import static org.assertj.core.api.Assertions.assertThat; + +class HelloBasicAuthTest extends BaseWebTest { + + final HttpClientContext clientContext = client(); + + public static HttpClientContext client() { + return HttpClientContext.newBuilder() + .withBaseUrl(baseUrl) + .withRequestListener(new RequestLogger()) + .withBodyAdapter(new JacksonBodyAdapter(new ObjectMapper())) + .withRequestIntercept(new BasicAuthIntercept("rob", "bot")) + .build(); + } + + @Test + void basicAuth() { + + final HttpResponse hres = clientContext.request() + .path("hello/basicAuth") + .GET() + .asString(); + + assertThat(hres.statusCode()).isEqualTo(200); + assertThat(hres.body()).isEqualTo("decoded: rob:bot"); + } + +} diff --git a/http-client/client/src/test/java/org/example/webserver/HelloController$Route.java b/http-client/client/src/test/java/org/example/webserver/HelloController$Route.java index 423ab4a4f..5632587ec 100644 --- a/http-client/client/src/test/java/org/example/webserver/HelloController$Route.java +++ b/http-client/client/src/test/java/org/example/webserver/HelloController$Route.java @@ -36,6 +36,12 @@ public void registerRoutes() { ctx.contentType("text/plain").result(controller.retry()); }); + ApiBuilder.get("/hello/basicAuth", ctx -> { + ctx.status(200); + final String authorization = ctx.header("Authorization"); + ctx.result(controller.basicAuth(authorization)); + }); + ApiBuilder.get("/hello/stream", ctx -> { ctx.status(200); controller.stream(ctx); diff --git a/http-client/client/src/test/java/org/example/webserver/HelloController.java b/http-client/client/src/test/java/org/example/webserver/HelloController.java index 2339b6ab6..8b1de4c7a 100644 --- a/http-client/client/src/test/java/org/example/webserver/HelloController.java +++ b/http-client/client/src/test/java/org/example/webserver/HelloController.java @@ -1,20 +1,15 @@ package org.example.webserver; -import io.avaje.http.api.Controller; -import io.avaje.http.api.Delete; -import io.avaje.http.api.Form; -import io.avaje.http.api.Get; -import io.avaje.http.api.MediaType; -import io.avaje.http.api.Path; -import io.avaje.http.api.Post; -import io.avaje.http.api.Produces; +import io.avaje.http.api.*; import io.javalin.http.Context; import javax.validation.Valid; import java.time.LocalDate; import java.util.ArrayList; +import java.util.Base64; import java.util.List; +import static java.nio.charset.StandardCharsets.UTF_8; import static java.util.Objects.requireNonNull; /** @@ -47,6 +42,15 @@ String retry() { } } + @Get + String basicAuth(@Header String authorization) { + final String[] split = authorization.split(" "); + if (split[0].equals("Basic")) { + return "decoded: " + new String(Base64.getDecoder().decode(split[1]), UTF_8); + } + return "NotExpected: " + authorization; + } + @Get("stream") void stream(Context context) { // simulate x-json-stream response From 836f74103207aa82158d914bc3b6e57ad4be3eee Mon Sep 17 00:00:00 2001 From: rbygrave Date: Sun, 20 Jun 2021 17:56:46 +1200 Subject: [PATCH 0124/1323] #20 - ENH: Add async().stream(...) for streaming results to beans (typically x-json-stream response) --- .../java/io/avaje/http/client/DHttpAsync.java | 8 ++++ .../avaje/http/client/DHttpClientRequest.java | 11 +++++ .../avaje/http/client/HttpAsyncResponse.java | 46 ++++++++++++++++--- .../http/client/HelloControllerTest.java | 43 +++++++++++++++-- 4 files changed, 97 insertions(+), 11 deletions(-) diff --git a/http-client/client/src/main/java/io/avaje/http/client/DHttpAsync.java b/http-client/client/src/main/java/io/avaje/http/client/DHttpAsync.java index e7fb69e79..97ebe1ed8 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/DHttpAsync.java +++ b/http-client/client/src/main/java/io/avaje/http/client/DHttpAsync.java @@ -3,6 +3,7 @@ import java.net.http.HttpResponse; import java.util.List; import java.util.concurrent.CompletableFuture; +import java.util.stream.Stream; class DHttpAsync implements HttpAsyncResponse { @@ -44,4 +45,11 @@ public CompletableFuture> list(Class type) { .performSendAsync(true, HttpResponse.BodyHandlers.ofByteArray()) .thenApply(httpResponse -> request.asyncList(type, httpResponse)); } + + @Override + public CompletableFuture> stream(Class type) { + return request + .performSendAsync(false, HttpResponse.BodyHandlers.ofLines()) + .thenApply(httpResponse -> request.asyncStream(type, httpResponse)); + } } diff --git a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java index e1f26ad5d..416e2112d 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java +++ b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java @@ -409,6 +409,17 @@ protected List asyncList(Class type, HttpResponse response) { return context.readList(type, encodedResponseBody); } + protected Stream asyncStream(Class type, HttpResponse> response) { + requestTimeNanos = System.nanoTime() - startAsyncNanos; + httpResponse = response; + context.afterResponse(this); + if (response.statusCode() >= 300) { + throw new HttpException(response, context); + } + final BodyReader bodyReader = context.beanReader(type); + return response.body().map(bodyReader::readBody); + } + private void afterAsyncEncoded(HttpResponse response) { requestTimeNanos = System.nanoTime() - startAsyncNanos; httpResponse = response; diff --git a/http-client/client/src/main/java/io/avaje/http/client/HttpAsyncResponse.java b/http-client/client/src/main/java/io/avaje/http/client/HttpAsyncResponse.java index 527ca91fe..cd8ae1307 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/HttpAsyncResponse.java +++ b/http-client/client/src/main/java/io/avaje/http/client/HttpAsyncResponse.java @@ -3,6 +3,7 @@ import java.net.http.HttpResponse; import java.util.List; import java.util.concurrent.CompletableFuture; +import java.util.stream.Stream; /** * Async processing of the request with responses as CompletableFuture. @@ -105,8 +106,9 @@ public interface HttpAsyncResponse { /** * Process expecting a bean response body (typically from json content). *

- * If the HTTP statusCode is 300 or above a HttpException is throw which - * contains the HttpResponse. + * If the HTTP statusCode is 300 or above a HttpException is throw + * which contains the HttpResponse. This is the cause in the + * CompletionException. * *

{@code
    *
@@ -125,7 +127,7 @@ public interface HttpAsyncResponse {
    *           ..
    *
    *         } else {
-   *           // use helloDto
+   *           // process helloDto
    *           ...
    *         }
    *       });
@@ -139,8 +141,9 @@ public interface HttpAsyncResponse {
   /**
    * Process expecting a list of beans response body (typically from json content).
    * 

- * If the HTTP statusCode is 300 or above a HttpException is throw which - * contains the HttpResponse. + * If the HTTP statusCode is 300 or above a HttpException is throw + * which contains the HttpResponse. This is the cause in the + * CompletionException. * *

{@code
    *
@@ -156,7 +159,7 @@ public interface HttpAsyncResponse {
    *           ...
    *
    *         } else {
-   *           // use list of helloDto
+   *           // process list of helloDto
    *           ...
    *         }
    *       });
@@ -167,4 +170,35 @@ public interface HttpAsyncResponse {
    */
    CompletableFuture> list(Class type);
 
+  /**
+   * Process response as a stream of beans (x-json-stream).
+   * 

+ * If the HTTP statusCode is 300 or above a HttpException is throw + * which contains the HttpResponse. This is the cause in the + * CompletionException. + * + *

{@code
+   *
+   *   CompletableFuture> future = clientContext.request()
+   *       .path("customers/stream")
+   *       .GET().async()
+   *       .stream(Customer.class);
+   *
+   *   future.whenComplete((stream, throwable) -> {
+   *       // if throwable != null ... handle error
+   *
+   *       // else process Stream ...
+   *       try (stream) {
+   *         stream.forEach(customer -> {
+   *           ...
+   *         });
+   *       }
+   *     });
+   *
+   * }
+ * + * @param type The bean type to convert the content to + * @return The CompletableFuture of the response + */ + CompletableFuture> stream(Class type); } diff --git a/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java b/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java index bebc6813a..4cb5a16a7 100644 --- a/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java +++ b/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java @@ -41,7 +41,37 @@ void get_stream() { } @Test - void async_stream() throws ExecutionException, InterruptedException { + void async_get_stream() throws ExecutionException, InterruptedException { + + final CompletableFuture> future = clientContext.request() + .path("hello").path("stream") + .GET().async() + .stream(SimpleData.class); + + future.whenComplete((stream, throwable) -> { + assertThat(throwable).isNull(); + + final List data = stream.collect(Collectors.toList()); + assertThat(data).hasSize(4); + final SimpleData first = data.get(0); + assertThat(first.id).isEqualTo(1); + assertThat(first.name).isEqualTo("one"); + + try (stream) { + // more typically process with forEach ... + stream.forEach(simpleData -> { + System.out.println("process " + simpleData.id + " " + simpleData.name); + }); + } + }); + + // wait ... + future.get(); + + } + + @Test + void async_stream_fromLineSubscriber() throws ExecutionException, InterruptedException { AtomicReference> hresRef = new AtomicReference<>(); AtomicReference errRef = new AtomicReference<>(); @@ -59,14 +89,17 @@ public void onSubscribe(Flow.Subscription subscription) { subscription.request(Long.MAX_VALUE); onSubscribeRef.set(true); } + @Override public void onNext(String item) { lines.add(item); } + @Override public void onError(Throwable throwable) { errRef.set(throwable); } + @Override public void onComplete() { completeRef.set(true); @@ -274,11 +307,11 @@ void async_exceptionally_style() { .bean(HelloDto.class); future.exceptionally(throwable -> { - final HttpException httpException = (HttpException) throwable.getCause(); - causeRef.set(httpException); - assertThat(httpException.getStatusCode()).isEqualTo(422); + final HttpException httpException = (HttpException) throwable.getCause(); + causeRef.set(httpException); + assertThat(httpException.getStatusCode()).isEqualTo(422); - return new HelloDto(0, "ErrorResponse", ""); + return new HelloDto(0, "ErrorResponse", ""); }).thenAccept(helloDto -> { assertThat(helloDto.name).isEqualTo("ErrorResponse"); From f6200a4fb023b6853fdc616c5416dea2e11cfb15 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Sun, 20 Jun 2021 19:49:00 +1200 Subject: [PATCH 0125/1323] Javadoc update --- .../java/io/avaje/http/client/HttpClientContext.java | 12 ++++++++---- .../java/io/avaje/http/client/HttpClientRequest.java | 6 ++++-- .../java/io/avaje/http/client/RequestLogger.java | 10 ++++++++++ .../io/avaje/http/client/SimpleRetryHandler.java | 6 ++++++ .../main/java/io/avaje/http/client/package-info.java | 2 +- 5 files changed, 29 insertions(+), 7 deletions(-) diff --git a/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java b/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java index 87f968834..0abd6e19b 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java +++ b/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java @@ -13,6 +13,7 @@ * * HttpClientContext ctx = HttpClientContext.newBuilder() * .withBaseUrl("http://localhost:8080") + * .withRequestListener(new RequestLogger()) * .withBodyAdapter(new JacksonBodyAdapter(new ObjectMapper())) * .build(); * @@ -20,7 +21,7 @@ * .path("hello") * .queryParam("name", "Rob") * .queryParam("say", "Ki ora") - * .get() + * .GET() * .bean(HelloDto.class); * * }
@@ -34,12 +35,13 @@ public interface HttpClientContext { * * HttpClientContext ctx = HttpClientContext.newBuilder() * .withBaseUrl("http://localhost:8080") + * .withRequestListener(new RequestLogger()) * .withBodyAdapter(new JacksonBodyAdapter(new ObjectMapper())) * .build(); * * HttpResponse res = ctx.request() * .path("hello") - * .get().asString(); + * .GET().asString(); * * }
*/ @@ -118,6 +120,7 @@ static HttpClientContext.Builder newBuilder() { * * HttpClientContext ctx = HttpClientContext.newBuilder() * .withBaseUrl("http://localhost:8080") + * .withRequestListener(new RequestLogger()) * .withBodyAdapter(new JacksonBodyAdapter(new ObjectMapper())) * .build(); * @@ -125,7 +128,7 @@ static HttpClientContext.Builder newBuilder() { * .path("hello") * .queryParam("name", "Rob") * .queryParam("say", "Ki ora") - * .get() + * .GET() * .bean(HelloDto.class); * * } @@ -227,13 +230,14 @@ interface Builder { * * HttpClientContext ctx = HttpClientContext.newBuilder() * .withBaseUrl("http://localhost:8080") + * .withRequestListener(new RequestLogger()) * .withBodyAdapter(new JacksonBodyAdapter(new ObjectMapper())) * .build(); * * HelloDto dto = ctx.request() * .path("hello") * .queryParam("say", "Ki ora") - * .get() + * .GET() * .bean(HelloDto.class); * * } diff --git a/http-client/client/src/main/java/io/avaje/http/client/HttpClientRequest.java b/http-client/client/src/main/java/io/avaje/http/client/HttpClientRequest.java index 8196435bf..8a83d152c 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/HttpClientRequest.java +++ b/http-client/client/src/main/java/io/avaje/http/client/HttpClientRequest.java @@ -19,7 +19,8 @@ * * HelloDto dto = clientContext.request() * .path("hello").queryParam("name", "Rob").queryParam("say", "Ki ora") - * .get().bean(HelloDto.class); + * .GET() + * .bean(HelloDto.class); * * } * @@ -92,7 +93,8 @@ public interface HttpClientRequest { * HttpResponse res = clientContext.request() * .url("http://127.0.0.1:8887") * .path("hello") - * .get().asString(); + * .GET() + * .asString(); * * } * diff --git a/http-client/client/src/main/java/io/avaje/http/client/RequestLogger.java b/http-client/client/src/main/java/io/avaje/http/client/RequestLogger.java index cc2a50b9b..e4d92991e 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/RequestLogger.java +++ b/http-client/client/src/main/java/io/avaje/http/client/RequestLogger.java @@ -12,6 +12,10 @@ /** * Logs request and response details for debug logging purposes. + *

+ * This implementation logs the request and response with the same + * single logging entry rather than separate logging of the request + * and response. */ public class RequestLogger implements RequestListener { @@ -19,10 +23,16 @@ public class RequestLogger implements RequestListener { private final String delimiter; + /** + * Create using the {@literal \n} new line character. + */ public RequestLogger() { this("\n"); } + /** + * Create with a given line delimiter. + */ public RequestLogger(String delimiter) { this.delimiter = delimiter; } diff --git a/http-client/client/src/main/java/io/avaje/http/client/SimpleRetryHandler.java b/http-client/client/src/main/java/io/avaje/http/client/SimpleRetryHandler.java index a376c4feb..3b0ea5534 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/SimpleRetryHandler.java +++ b/http-client/client/src/main/java/io/avaje/http/client/SimpleRetryHandler.java @@ -15,6 +15,12 @@ public class SimpleRetryHandler implements RetryHandler { private final int maxRetries; private final long backoffMillis; + /** + * Create with maximum number of retries and linear backoff time. + * + * @param maxRetries The maximum number of retry attempts + * @param backoffMillis The linear backoff between attempts in milliseconds + */ public SimpleRetryHandler(int maxRetries, long backoffMillis) { this.maxRetries = maxRetries; this.backoffMillis = backoffMillis; diff --git a/http-client/client/src/main/java/io/avaje/http/client/package-info.java b/http-client/client/src/main/java/io/avaje/http/client/package-info.java index 3ad25d449..02f86d631 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/package-info.java +++ b/http-client/client/src/main/java/io/avaje/http/client/package-info.java @@ -14,7 +14,7 @@ * HelloDto dto = ctx.request() * .path("hello") * .queryParam("say", "Ki ora") - * .get() + * .GET() * .bean(HelloDto.class); * * } From ecf5c981d9de3fba351afb0d9e0f7d6564c44d58 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Mon, 21 Jun 2021 12:32:53 +1200 Subject: [PATCH 0126/1323] Simplify PathConversion removing unnecessary methods --- .../io/avaje/http/client/PathConversion.java | 70 ++----------------- 1 file changed, 5 insertions(+), 65 deletions(-) diff --git a/http-client/client/src/main/java/io/avaje/http/client/PathConversion.java b/http-client/client/src/main/java/io/avaje/http/client/PathConversion.java index 06f1dd8aa..03b4fcd45 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/PathConversion.java +++ b/http-client/client/src/main/java/io/avaje/http/client/PathConversion.java @@ -1,9 +1,5 @@ package io.avaje.http.client; -import java.math.BigDecimal; -import java.time.*; -import java.util.UUID; - /** * Helper methods to convert common types to String path values. */ @@ -33,78 +29,22 @@ public static String toPath(boolean val) { /** * Convert to path. */ - public static String toPath(UUID val) { - return val.toString(); - } - - /** - * Convert to path. - */ - public static String toPath(LocalDate val) { - return val.toString(); - } - - /** - * Convert to path. - */ - public static String toPath(LocalTime val) { - return val.toString(); - } - - /** - * Convert to path. - */ - public static String toPath(LocalDateTime val) { - return val.toString(); - } - - /** - * Convert to path. - */ - public static String toPath(Instant val) { - return val.toString(); - } - - /** - * Convert to path. - */ - public static String toPath(OffsetDateTime val) { - return val.toString(); - } - - /** - * Convert to path. - */ - public static String toPath(ZonedDateTime val) { - return val.toString(); + public static String toPath(double val) { + return Double.toString(val); } /** * Convert to path. */ - public static String toPath(ZoneId val) { - return val.toString(); + public static String toPath(float val) { + return Float.toString(val); } /** * Convert to path. */ - public static String toPath(BigDecimal val) { + public static String toPath(Object val) { return val.toString(); } - /** - * Convert to path. - */ - public static String toPath(double val) { - return Double.toString(val); - } - - /** - * Convert to path. - */ - public static String toPath(float val) { - return Float.toString(val); - } - } From 03824e2165b846385da7c0c332f0f403c6bd2737 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Mon, 21 Jun 2021 14:19:25 +1200 Subject: [PATCH 0127/1323] Update README --- http-client/README.md | 176 +++++++++++++++++++++++++++++++++++------- 1 file changed, 150 insertions(+), 26 deletions(-) diff --git a/http-client/README.md b/http-client/README.md index 4ae17039e..af3e54d84 100644 --- a/http-client/README.md +++ b/http-client/README.md @@ -4,7 +4,11 @@ A light weight wrapper to the JDK 11+ Java Http Client - Adds a fluid API for request constructing URL and payload - Adds JSON marshalling/unmarshalling of request and response using Jackson or Gson -- Adds request/response logging +- Gzip encoding/decoding +- Logging of request/response logging +- Interception of request/response +- Built in support for authorization via Basic Auth and Bearer Token + @@ -35,20 +39,82 @@ Create a HttpClientContext with a baseUrl, Jackson or Gson based JSON ``` -### Requests +## Requests From HttpClientContext: - Create a request - Build the url via path(), matrixParam(), queryParam() - Optionally set headers(), cookies() etc - - Optionally specify a request body (JSON, form, or raw BodyPublisher) + - Optionally specify a request body (JSON, form, or any JDK BodyPublisher) - Http verbs - GET(), POST(), PUT(), PATCH(), DELETE(), HEAD(), TRACE() - - Optionally return response body as a bean, list of beans, stream of beans or various raw response types - - Optionally use Async processing of the request + + - Sync processing response body as: + - a bean, list of beans, stream of beans, String, Void or any JDK Response.BodyHandler + + - Async processing of the request using CompleteableFuture + - a bean, list of beans, stream of beans, String, Void or any JDK Response.BodyHandler + + + +## Limitations: +- NO support for POSTing multipart-form currently + + +#### Example GET as String +```java +HttpResponse hres = clientContext.request() + .path("hello") + .GET() + .asString(); +``` + + +## Overview of responses + +Overview of response types for sync calls. + + + + + + + + + + + + + + + + + +
sync processing 
asVoidHttpResponse<Void>
asStringHttpResponse<String>
bean<E>E
list<E>List<E>
stream<E>Stream<E>
withHandler(HttpResponse.BodyHandler<E>)E
  
async processing 
asVoidCompleteableFuture<Void>
asStringCompleteableFuture<String>
bean<E>CompleteableFuture<E>
list<E>CompleteableFuture<List<E>>
stream<E>CompleteableFuture<Stream<E>>
withHandler(HttpResponse.BodyHandler<E>)CompleteableFuture<E>
+ +### JDK BodyHandlers + +JDK HttpClient provides a number of BodyHandlers including reactive Flow based subscribers. +With the `withHandler()` methods we can use any of these or our own `HttpResponse.BodyHandler` +implementation. + +Reference https://docs.oracle.com/en/java/javase/11/docs/api/java.net.http/java/net/http/HttpResponse.BodyHandlers.html + + + + + + + + + + + + +
discarding()Discards the response body
ofByteArray()byte[]
ofString()String, additional charset option
ofLines()Stream<String>
ofInputStream()InputStream
ofFile(Path file)Path with various options
ofByteArrayConsumer(...) 
fromSubscribervarious options
fromLineSubscribervarious options
## Examples -GET as String +#### GET as String ```java HttpResponse hres = clientContext.request() .path("hello") @@ -56,7 +122,31 @@ HttpResponse hres = clientContext.request() .asString(); ``` -GET as json to single bean +#### Async GET as String + - All async requests use JDK httpClient.sendAsync(...) returning CompleteableFuture<T> + - throwable is a CompletionException + - In the example below hres is of type HttpResponse<String> + +```java +clientContext.request() + .path("hello") + .GET() + .async().asString() + .whenComplete((hres, throwable) -> { + + if (throwable != null) { + // CompletionException + ... + } else { + // HttpResponse<String> + int statusCode = hres.statusCode(); + String body = hres.body(); + ... + } + }); +``` + +#### GET as json to single bean ```java Customer customer = clientContext.request() .path("customers").path(42) @@ -64,7 +154,7 @@ Customer customer = clientContext.request() .bean(Customer.class); ``` -GET as json to a list of beans +#### GET as json to a list of beans ```java List list = clientContext.request() .path("customers") @@ -72,7 +162,7 @@ List list = clientContext.request() .list(Customer.class); ``` -GET as `application/x-json-stream` as a stream of beans +#### GET as `application/x-json-stream` as a stream of beans ```java Stream stream = clientContext.request() .path("customers/all") @@ -81,12 +171,12 @@ Stream stream = clientContext.request() ``` -POST a bean as json request body +#### POST a bean as json request body ```java -HelloDto bean = new HelloDto(12, "rob", "other"); +Hello bean = new Hello(42, "rob", "other"); HttpResponse res = clientContext.request() - .path("hello/savebean") + .path("hello") .body(bean) .POST() .asDiscarding(); @@ -95,7 +185,11 @@ assertThat(res.statusCode()).isEqualTo(201); ``` -Path +#### Path + +Multiple calls to `path()` append with a `/`. This is make it easier to build a path +programmatically and also build paths that include `matrixParam()` + ```java HttpResponse res = clientContext.request() .path("customers") @@ -112,7 +206,7 @@ HttpResponse res = clientContext.request() .asString(); ``` -MatrixParam +#### MatrixParam ```java HttpResponse httpRes = clientContext.request() .path("books") @@ -120,19 +214,21 @@ HttpResponse httpRes = clientContext.request() .matrixParam("country", "nz") .path("foo") .matrixParam("extra", "banana") - .GET().asString(); + .GET() + .asString(); ``` -QueryParam +#### QueryParam ```java List beans = clientContext.request() .path("products") .queryParam("sortBy", "name") .queryParam("maxCount", "100") - .GET().list(Product.class); + .GET() + .list(Product.class); ``` -FormParam +#### FormParam ```java HttpResponse res = clientContext.request() .path("register/user") @@ -146,10 +242,21 @@ HttpResponse res = clientContext.request() assertThat(res.statusCode()).isEqualTo(201); ``` -## Currently, NO support for POSTing multipart-form + ## Async processing +All async requests use JDK httpClient.sendAsync(...) returning CompleteableFuture<T> + + + + + + + + +
asVoidCompleteableFuture<Void>
asStringCompleteableFuture<String>
bean<E>CompleteableFuture<E>
list<E>CompleteableFuture<List<E>>
stream<E>CompleteableFuture<Stream<E>>
withHandler(HttpResponse.BodyHandler<E>)CompleteableFuture<E>
+ ### .async().asDiscarding() - HttpResponse<Void> ```java @@ -214,7 +321,7 @@ clientContext.request() ``` -### .async().withHandler(...) - Any response body handler +### .async().withHandler(...) - Any `Response.BodyHandler` implementation The example below is a line subscriber processing response content line by line. @@ -230,6 +337,7 @@ CompletableFuture> future = clientContext.request() } @Override public void onNext(String item) { + // process the line of response content ... } @Override @@ -248,10 +356,27 @@ CompletableFuture> future = clientContext.request() ``` +## BasicAuthIntercept - Authorization Basic / Basic Auth + +We can use `BasicAuthIntercept` to intercept all requests adding a `Authorization: Basic ...` +header ("Basic Auth"). + +##### Example + +```java +HttpClientContext clientContext = + HttpClientContext.newBuilder() + .withBaseUrl(baseUrl) + ... + .withRequestIntercept(new BasicAuthIntercept("myUsername", "myPassword")) + tests diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index 2e43332c7..9a41fe875 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -25,7 +25,7 @@ io.avaje avaje-http-client - 1.6 + 1.7 @@ -37,7 +37,7 @@ io.avaje avaje-http-api - 1.6-SNAPSHOT + 1.7-SNAPSHOT @@ -93,7 +93,7 @@ io.avaje avaje-http-generator-client - 1.6-SNAPSHOT + 1.7-SNAPSHOT diff --git a/tests/test-client/src/main/java/org/example/GitHubUsers.java b/tests/test-client/src/main/java/org/example/GitHubUsers.java index f87890dbd..85d41174c 100644 --- a/tests/test-client/src/main/java/org/example/GitHubUsers.java +++ b/tests/test-client/src/main/java/org/example/GitHubUsers.java @@ -3,17 +3,75 @@ import io.avaje.http.api.Client; import io.avaje.http.api.Get; import io.avaje.http.api.Path; +import io.avaje.http.client.HttpCall; +import java.net.http.HttpResponse; import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.stream.Stream; @Client @Path("users") public interface GitHubUsers { + @Get("{user}/repos") + void plainVoid(String user); + + @Get("{user}/repos") + HttpResponse asVoid(String user); + + @Get("{user}/repos") + HttpCall> callAsVoid(String user); + + @Get("{user}/repos") + String plainString(String user); + + @Get("{user}/repos") + HttpResponse asStr(String user); + + @Get("{user}/repos") + HttpCall> callAsStr(String user); + @Get("{user}/repos") List listRepos(String user); @Get("{user}/repos") - String list2(String user); + HttpCall> callListRepos(String user); + + @Get("{user}/repos/stream") + Stream streamRepos(String user); + + @Get("{user}/repos/stream") + HttpCall> callStreamRepos(String user); + + @Get("{user}/repos") + HttpResponse withHan(String user, HttpResponse.BodyHandler myHandler); + + @Get("{user}/repos") + HttpCall> callWithHan(String user, HttpResponse.BodyHandler myHandler); + + @Get("{user}/repos/stream") + Repo beanRepo(String user); + + @Get("{user}/repos/stream") + HttpCall callBeanRepo(String user); + +// @Get("{user}/repos/stream") +// CompletableFuture asyncVoid(String user); + + @Get("{user}/repos/stream") + CompletableFuture> asyncVoid(String user); + + @Get("{user}/repos/stream") + CompletableFuture> asyncString(String user); + + @Get("{user}/repos/stream") + CompletableFuture> asyncStreamRepo(String user); + + @Get("{user}/repos/stream") + CompletableFuture> asyncListRepo(String user); + + @Get("{user}/repos/stream") + CompletableFuture asyncBeanRepo(String user); } diff --git a/tests/test-helidon/pom.xml b/tests/test-helidon/pom.xml index b88733e23..339ce8b43 100644 --- a/tests/test-helidon/pom.xml +++ b/tests/test-helidon/pom.xml @@ -17,7 +17,7 @@ org.example.Main 2.3.0 - 1.6-SNAPSHOT + 1.7-SNAPSHOT @@ -115,7 +115,7 @@ io.avaje avaje-http-client - 1.6 + 1.7 test diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index fb5c70135..bf5a21cb0 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -20,7 +20,7 @@ 2.0.8 1.3.71 2.12.3 - 1.6-SNAPSHOT + 1.7-SNAPSHOT @@ -108,7 +108,7 @@ io.avaje avaje-http-client - 1.6 + 1.7 test diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 24d5b3820..8d31ca1f6 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -20,7 +20,7 @@ 2.0.8 2.12.3 6.0 - 1.6-SNAPSHOT + 1.7-SNAPSHOT @@ -95,7 +95,7 @@ io.avaje avaje-http-client - 1.6 + 1.7 test diff --git a/tests/test-spark/pom.xml b/tests/test-spark/pom.xml index e3c7d527b..8a8862f1c 100644 --- a/tests/test-spark/pom.xml +++ b/tests/test-spark/pom.xml @@ -17,7 +17,7 @@ org.example.myapp.Main 2.0.8 - 1.6-SNAPSHOT + 1.7-SNAPSHOT @@ -76,7 +76,7 @@ io.avaje avaje-http-spark-generator - 1.6-SNAPSHOT + 1.7-SNAPSHOT provided @@ -93,7 +93,7 @@ io.avaje avaje-http-client - 1.6 + 1.7 test From 534823274b8af1f14b1f70dc37ca8be4e21ebd52 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Wed, 23 Jun 2021 19:11:55 +1200 Subject: [PATCH 0145/1323] #22 - ENH: Add Map option for header() queryParam() and formParam() --- .../avaje/http/client/DHttpClientRequest.java | 27 +++++++- .../avaje/http/client/HttpClientRequest.java | 28 +++++++- .../java/io/avaje/http/client/UrlBuilder.java | 13 ++++ .../http/client/HelloControllerTest.java | 67 ++++++++++++++++--- .../io/avaje/http/client/UrlBuilderTest.java | 16 +++++ 5 files changed, 137 insertions(+), 14 deletions(-) diff --git a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java index 9b7f0f399..559a9a9ec 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java +++ b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java @@ -91,6 +91,16 @@ public HttpClientRequest header(String name, Object value) { return value != null ? header(name, value.toString()) : this; } + @Override + public HttpClientRequest header(Map headers) { + if (headers != null) { + for (Map.Entry entry : headers.entrySet()) { + header(entry.getKey(), entry.getValue()); + } + } + return this; + } + @Override public List header(String name) { final List values = headers.get(name); @@ -145,7 +155,6 @@ public HttpClientRequest matrixParam(String name, Object value) { return this; } - @Override public HttpClientRequest queryParam(String name, String value) { url.queryParam(name, value); @@ -158,6 +167,12 @@ public HttpClientRequest queryParam(String name, Object value) { return this; } + @Override + public HttpClientRequest queryParam(Map params) { + url.queryParam(params); + return this; + } + @Override public HttpClientRequest formParam(String name, String value) { if (value == null) { @@ -175,6 +190,16 @@ public HttpClientRequest formParam(String name, Object value) { return value != null ? formParam(name, value.toString()) : this; } + @Override + public HttpClientRequest formParam(Map params) { + if (params != null) { + for (Map.Entry entry : params.entrySet()) { + formParam(entry.getKey(), entry.getValue()); + } + } + return this; + } + @Override public HttpClientRequest body(BodyContent bodyContent) { encodedRequestBody = bodyContent; diff --git a/http-client/client/src/main/java/io/avaje/http/client/HttpClientRequest.java b/http-client/client/src/main/java/io/avaje/http/client/HttpClientRequest.java index 0f74ddbdf..153423fb1 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/HttpClientRequest.java +++ b/http-client/client/src/main/java/io/avaje/http/client/HttpClientRequest.java @@ -1,11 +1,11 @@ package io.avaje.http.client; -import java.io.FileNotFoundException; import java.io.InputStream; import java.net.http.HttpRequest; import java.nio.file.Path; import java.time.Duration; import java.util.List; +import java.util.Map; import java.util.function.Supplier; /** @@ -71,6 +71,14 @@ public interface HttpClientRequest { */ HttpClientRequest header(String name, Object value); + /** + * Add the headers to the request via map. + * + * @param headers The headers as name value map to add + * @return The request being built + */ + HttpClientRequest header(Map headers); + /** * Return the header values that have been set for the given header name. * @@ -164,7 +172,7 @@ public interface HttpClientRequest { HttpClientRequest queryParam(String name, String value); /** - * Add a Integer query parameter + * Add a query parameter * * @param name The name of the query parameter * @param value The value of the query parameter which can be null @@ -172,6 +180,14 @@ public interface HttpClientRequest { */ HttpClientRequest queryParam(String name, Object value); + /** + * Add a multiple query parameters as name value map. + * + * @param params The query parameters + * @return The request being built + */ + HttpClientRequest queryParam(Map params); + /** * Add a form parameter. * @@ -190,6 +206,14 @@ public interface HttpClientRequest { */ HttpClientRequest formParam(String name, Object value); + /** + * Add the form parameters via a map. + * + * @param params The form parameters as name value map + * @return The request being built + */ + HttpClientRequest formParam(Map params); + /** * Set encoded body content. */ diff --git a/http-client/client/src/main/java/io/avaje/http/client/UrlBuilder.java b/http-client/client/src/main/java/io/avaje/http/client/UrlBuilder.java index ed57f5c9b..55818ff92 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/UrlBuilder.java +++ b/http-client/client/src/main/java/io/avaje/http/client/UrlBuilder.java @@ -2,6 +2,7 @@ import java.net.URLEncoder; import java.nio.charset.StandardCharsets; +import java.util.Map; /** * Build a URL typically using a base url and adding path and query parameters. @@ -89,6 +90,18 @@ public UrlBuilder queryParam(String name, Object value) { return this; } + /** + * Append a query parameters. + */ + public UrlBuilder queryParam(Map params) { + if (params != null) { + for (Map.Entry entry : params.entrySet()) { + queryParam(entry.getKey(), entry.getValue()); + } + } + return this; + } + /** * Append a matrix parameter. *

diff --git a/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java b/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java index 0504ce0e6..f67e18a78 100644 --- a/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java +++ b/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java @@ -11,10 +11,7 @@ import java.time.Duration; import java.time.LocalDate; import java.time.ZoneId; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.UUID; +import java.util.*; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionException; import java.util.concurrent.ExecutionException; @@ -31,6 +28,21 @@ class HelloControllerTest extends BaseWebTest { final HttpClientContext clientContext = client(); + @Test + void queryParamMap() { + Map params = new LinkedHashMap<>(); + params.put("A", "a"); + params.put("B", "b"); + + final HttpResponse hres = clientContext.request() + .path("hello").path("message") + .queryParam(params) + .GET().asString(); + + assertThat(hres.statusCode()).isEqualTo(200); + assertThat(hres.uri().toString()).isEqualTo("http://localhost:8887/hello/message?A=a&B=b"); + } + @Test void asLines() { final HttpResponse> hres = @@ -246,6 +258,22 @@ void get_notFound() { assertThat(hres.body()).contains("Not found"); } + @Test + void headers() { + final HttpClientRequest request = clientContext.request(); + + Map headers = new LinkedHashMap<>(); + headers.put("A", "a"); + headers.put("B", "b"); + headers.put("C", "c"); + request.header(headers); + request.header("B", "b2"); + + assertThat(request.header("A")).containsExactly("a"); + assertThat(request.header("B")).containsExactly("b", "b2"); + assertThat(request.header("C")).containsExactly("c"); + } + @Test void callString() { final HttpResponse hres = clientContext.request() @@ -535,7 +563,7 @@ void async_exceptionally_style() { future.exceptionally(throwable -> { final HttpException httpException = (HttpException) throwable.getCause(); causeRef.set(httpException); - assertThat(httpException.getStatusCode()).isEqualTo(422); + assertThat(httpException.statusCode()).isEqualTo(422); return new HelloDto(0, "ErrorResponse", ""); @@ -601,6 +629,23 @@ void postForm() { assertThat(res.statusCode()).isEqualTo(201); } + @Test + void postForm_asMap() { + Map formParams = new LinkedHashMap<>(); + formParams.put("name", "Bazz"); + formParams.put("email", "user@foo.com"); + formParams.put("url", "http://foo.com"); + formParams.put("startDate", LocalDate.of(2030, 12, 03).toString()); + + final HttpResponse res = clientContext.request() + .path("hello/saveform") + .formParam(formParams) + .POST() + .asDiscarding(); + + assertThat(res.statusCode()).isEqualTo(201); + } + @Test void postForm_returningBean() { @@ -662,7 +707,7 @@ void postForm_asVoid_invokesValidation_expect_badRequest_extractError() { fail(); } catch (HttpException e) { - assertEquals(422, e.getStatusCode()); + assertEquals(422, e.statusCode()); final HttpResponse httpResponse = e.getHttpResponse(); assertNotNull(httpResponse); @@ -693,7 +738,7 @@ void asyncAsVoid_extractError() throws InterruptedException { final HttpException cause = (HttpException) throwable.getCause(); ref.set(cause); - final HttpResponse httpResponse = cause.getHttpResponse(); + final HttpResponse httpResponse = cause.httpResponse(); assertNotNull(httpResponse); assertEquals(422, httpResponse.statusCode()); @@ -728,7 +773,7 @@ void callAsVoid_async_extractError() throws InterruptedException { final HttpException cause = (HttpException) throwable.getCause(); ref.set(cause); - final HttpResponse httpResponse = cause.getHttpResponse(); + final HttpResponse httpResponse = cause.httpResponse(); assertNotNull(httpResponse); assertEquals(422, httpResponse.statusCode()); @@ -759,7 +804,7 @@ void callAsVoid_extractError() { fail(); } catch (HttpException e) { - final HttpResponse httpResponse = e.getHttpResponse(); + final HttpResponse httpResponse = e.httpResponse(); assertNotNull(httpResponse); assertEquals(422, httpResponse.statusCode()); @@ -782,9 +827,9 @@ void postForm_asBytes_validation_expect_badRequest_extractError() { fail(); } catch (HttpException e) { - assertEquals(422, e.getStatusCode()); + assertEquals(422, e.statusCode()); - final HttpResponse httpResponse = e.getHttpResponse(); + final HttpResponse httpResponse = e.httpResponse(); assertNotNull(httpResponse); assertEquals(422, httpResponse.statusCode()); diff --git a/http-client/client/src/test/java/io/avaje/http/client/UrlBuilderTest.java b/http-client/client/src/test/java/io/avaje/http/client/UrlBuilderTest.java index e41c4ff71..5d627e08e 100644 --- a/http-client/client/src/test/java/io/avaje/http/client/UrlBuilderTest.java +++ b/http-client/client/src/test/java/io/avaje/http/client/UrlBuilderTest.java @@ -7,6 +7,8 @@ import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; +import java.util.LinkedHashMap; +import java.util.Map; import java.util.UUID; import static org.assertj.core.api.Assertions.assertThat; @@ -111,6 +113,20 @@ void queryParam_when_many() { assertThat(url).isEqualTo("https://foo?a=a&b=true&c=false&d=1&e=2&f=13:42&g=2020-01-04&h=2020-01-04T13:44"); } + @Test + void queryParam_when_map() { + Map params = new LinkedHashMap<>(); + params.put("A", "a"); + params.put("B", "b"); + params.put("C", "c"); + + final UrlBuilder urlBuilder = foo() + .queryParam(params) + .queryParam("B", "b2"); + + assertThat(urlBuilder.build()).isEqualTo("https://foo?A=a&B=b&C=c&B=b2"); + } + @Test void queryParam_when_uuid() { UUID uuid = UUID.randomUUID(); From 8b2b3e061497fa21badc113d783bb3c98ab57e96 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Thu, 24 Jun 2021 10:18:58 +1200 Subject: [PATCH 0146/1323] Tidy tests using deprecated methods --- .../src/test/java/org/example/github/SimpleHttpClient.java | 2 +- .../src/test/java/org/example/webserver/HelloController.java | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/http-client/client/src/test/java/org/example/github/SimpleHttpClient.java b/http-client/client/src/test/java/org/example/github/SimpleHttpClient.java index 9e6d4812e..ec2f8bd14 100644 --- a/http-client/client/src/test/java/org/example/github/SimpleHttpClient.java +++ b/http-client/client/src/test/java/org/example/github/SimpleHttpClient.java @@ -54,7 +54,7 @@ public InputStream getById2(String id, InputStream is) { context.request() .path("users").path(id).path("stream") .body(() -> is) - .GET().withResponseHandler(HttpResponse.BodyHandlers.ofInputStream()); + .GET().withHandler(HttpResponse.BodyHandlers.ofInputStream()); context.checkResponse(response); return response.body(); diff --git a/http-client/client/src/test/java/org/example/webserver/HelloController.java b/http-client/client/src/test/java/org/example/webserver/HelloController.java index f01cdbcf1..45feb95e2 100644 --- a/http-client/client/src/test/java/org/example/webserver/HelloController.java +++ b/http-client/client/src/test/java/org/example/webserver/HelloController.java @@ -71,7 +71,6 @@ void stream(Context context) { * @param date The name of the hello * @param otherParam Optional other parameter * @return The Hello DTO given the id and name. - * @deprecated Please migrate away */ @Get("/{id}/{date}") HelloDto hello(int id, LocalDate date, String otherParam) { From 196e6812d5ffa13ea1f096e037c76c2751eb8d93 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Thu, 24 Jun 2021 10:20:04 +1200 Subject: [PATCH 0147/1323] [maven-release-plugin] prepare release avaje-http-client-1.8 --- http-client/client/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/http-client/client/pom.xml b/http-client/client/pom.xml index f7bf0c4c5..f972aee54 100644 --- a/http-client/client/pom.xml +++ b/http-client/client/pom.xml @@ -9,11 +9,11 @@ io.avaje avaje-http-client - 1.8-SNAPSHOT + 1.8 scm:git:git@github.com:avaje/avaje-http-client.git - HEAD + avaje-http-client-1.8 From 2aa220b53c2d33989571b93f41717e14ee0adbec Mon Sep 17 00:00:00 2001 From: rbygrave Date: Thu, 24 Jun 2021 10:20:13 +1200 Subject: [PATCH 0148/1323] [maven-release-plugin] prepare for next development iteration --- http-client/client/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/http-client/client/pom.xml b/http-client/client/pom.xml index f972aee54..8dd48daab 100644 --- a/http-client/client/pom.xml +++ b/http-client/client/pom.xml @@ -9,11 +9,11 @@ io.avaje avaje-http-client - 1.8 + 1.9-SNAPSHOT scm:git:git@github.com:avaje/avaje-http-client.git - avaje-http-client-1.8 + HEAD From 43764966f91126bff15ae345aa9efe90da584472 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Thu, 24 Jun 2021 12:00:33 +1200 Subject: [PATCH 0149/1323] Bump version to 1.9 and improve README around Loom vs Async --- http-client/README.md | 85 ++++++++++++++++++-------------- http-client/gson-adapter/pom.xml | 4 +- 2 files changed, 49 insertions(+), 40 deletions(-) diff --git a/http-client/README.md b/http-client/README.md index 758c2be87..e38859ed6 100644 --- a/http-client/README.md +++ b/http-client/README.md @@ -3,7 +3,7 @@ A lightweight wrapper to the [JDK 11+ Java Http Client](http://openjdk.java.net/groups/net/httpclient/intro.html) - Use Java 11.0.8 or higher (some SSL related bugs prior to 11.0.8 with JDK HttpClient) -- Adds a fluid API for request constructing URL and payload +- Adds a fluid API for building URL and payload - Adds JSON marshalling/unmarshalling of request and response using Jackson or Gson - Gzip encoding/decoding - Logging of request/response logging @@ -18,7 +18,7 @@ A lightweight wrapper to the [JDK 11+ Java Http Client](http://openjdk.java.net/ io.avaje avaje-http-client - 1.7 + 1.9 ``` @@ -495,8 +495,15 @@ obtained for initial request and then renewed when the token has expired. The following is a very quick and rough comparison of running 10,000 requests using `Async` vs `Loom`. -To run this test myself I use [Jex](https://github.com/avaje/avaje-jex) as the -server (Jetty based) and have it running using Loom. +The intention is to test the thought that in a "future Loom world" the +desire to use `async()` execution with HttpClient reduces. + +TLDR: Caveat, caveat, more caveats ... initial testing shows Loom to be just a +touch faster (~10%) than async. + +To run my tests I use [Jex](https://github.com/avaje/avaje-jex) as the server +(Jetty based) and have it running using Loom. For whatever testing you do +you will need a server that can handle a very large number of concurrent requests. The Loom blocking request (make 10K of these) @@ -527,41 +534,39 @@ HttpClient's reactive streams. The `whenComplete()` callback is invoked when the response is ready. Collect all the resulting CompletableFuture and wait for them all to complete. +Outline: + ```java // Collect all the CompletableFuture's -List>> all = new ArrayList<>(); +List>> futures = new ArrayList<>(); -long start = System.currentTimeMillis(); for (int i = 0; i < 10_000; i++) { - all.add(httpClient.request().path("s200") - .GET() - .async().asString() - .whenComplete((hres, throwable) -> { - output(hres); - })); + futures.add(httpClient.request().path("s200") + .GET() + .async().asString() + .whenComplete((hres, throwable) -> { + // confirm 200 response etc + ... + })); } -// wait for them all to complete .. -CompletableFuture.allOf(all.toArray(new CompletableFuture[0])) - .join(); +// wait for all requests to complete via join() ... +CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join(); -long exeMs = System.currentTimeMillis() - start; -System.out.println("Complete ... exeMillis:" + exeMs); ``` -Runs is approx 5 to 5.5 seconds on my environment (without sout). ### 10K requests using Loom With Loom Java 17 EA Release we can use `Executors.newVirtualThreadExecutor()` -to return an ExecutorService that uses Loom Virtual Threads. These -are backed by "Carrier threads" (via ForkedJoinPool). +to return an ExecutorService that uses Loom Virtual Threads. These are backed +by "Carrier threads" (via ForkedJoinPool). -```java +Outline: -long start = System.currentTimeMillis(); +```java -// Use Loom's Executors.newVirtualThreadExecutor() +// use Loom's Executors.newVirtualThreadExecutor() try (ExecutorService executorService = Executors.newVirtualThreadExecutor()) { for (int i = 0; i < 10_000; i++) { @@ -569,30 +574,34 @@ try (ExecutorService executorService = Executors.newVirtualThreadExecutor()) { } } -long exeMs = System.currentTimeMillis() - start; -System.out.println("Complete ... exeMillis:" + exeMs); ``` ```java private void task() { - HttpResponse hres = performGet(); - System.out.println(" status:" + hres.statusCode() + " length:" + hres.body().length()); -} + HttpResponse hres = + httpClient.request().path("s200") + .GET() + .asString(); -private HttpResponse performGet() { - return httpClient.request() - .path("s200") - .GET() - .asString(); + // confirm 200 response etc + ... } + ``` -Running in approx 4.5 to 5 seconds on my environment (without sout). +Caveat: Proper performance benchmarks are really hard and take a lot of +effort. + +Running some "rough/approx performance comparison tests" using `Loom` +build `17 EA 2021-09-14 / (build 17-loom+7-342)` vs `Async` for my environment +and 10K request scenarios has loom execution around 10% faster than async. + +It looks like Loom and Async run in pretty much the same time although it +currently looks that Loom is just a touch faster (perhaps due to how it does +park/unpark). More investigation required. -It looks like Loom and Async run in pretty much the same time although -it could be that Loom is just a slight touch faster. I need to do more -investigation. -Build used is: `17 EA 2021-09-14 / (build 17-loom+7-342)`. +Date: 2021-06 +Build: `17 EA 2021-09-14 / (build 17-loom+7-342)`. ``` openjdk version "17-loom" 2021-09-14 diff --git a/http-client/gson-adapter/pom.xml b/http-client/gson-adapter/pom.xml index 713c63869..a7ab873c6 100644 --- a/http-client/gson-adapter/pom.xml +++ b/http-client/gson-adapter/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-client-gson - 1.7 + 1.9 scm:git:git@github.com:avaje/avaje-http-client.git @@ -27,7 +27,7 @@ io.avaje avaje-http-client - 1.7 + 1.9 provided From 32a77cd7c69036abcdaa5da6c22d36a9506e51e9 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Thu, 24 Jun 2021 12:03:06 +1200 Subject: [PATCH 0150/1323] Bump version to 1.8, Gson to version 2.8.7 --- http-client/gson-adapter/pom.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/http-client/gson-adapter/pom.xml b/http-client/gson-adapter/pom.xml index a7ab873c6..ef02f24d4 100644 --- a/http-client/gson-adapter/pom.xml +++ b/http-client/gson-adapter/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-client-gson - 1.9 + 1.8 scm:git:git@github.com:avaje/avaje-http-client.git @@ -21,13 +21,13 @@ com.google.code.gson gson - 2.8.6 + 2.8.7 io.avaje avaje-http-client - 1.9 + 1.8 provided From 1d9f5ed539ddefd5474aed8f3169913e9a83619a Mon Sep 17 00:00:00 2001 From: rbygrave Date: Thu, 24 Jun 2021 15:16:28 +1200 Subject: [PATCH 0151/1323] #62 - ENH: [Client generator] Add Map option for header() queryParam() and formParam() --- .../generator/client/ClientMethodWriter.java | 35 ++++++++++++++----- .../http/generator/core/ElementReader.java | 10 ++++-- .../http/generator/core/MethodParam.java | 8 +++-- .../http/generator/core/MethodReader.java | 13 ++++--- tests/test-client/pom.xml | 2 +- .../src/main/java/org/example/Simple.java | 11 ++++++ 6 files changed, 58 insertions(+), 21 deletions(-) diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java index becc703fd..868f392c8 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java @@ -3,7 +3,6 @@ import io.avaje.http.generator.core.*; import javax.lang.model.element.TypeElement; -import java.util.List; import java.util.Set; /** @@ -47,7 +46,7 @@ private void methodStart(Append writer) { if (count++ > 0) { writer.append(", "); } - writer.append(param.getShortType()).append(" "); + writer.append(param.getUType().shortType()).append(" "); writer.append(param.getName()); checkBodyHandler(param); } @@ -143,13 +142,15 @@ private void writeWithHandler() { } private void writeQueryParams(PathSegments pathSegments) { - List params = method.getParams(); - for (MethodParam param : params) { + for (MethodParam param : method.getParams()) { ParamType paramType = param.getParamType(); if (paramType == ParamType.QUERYPARAM) { - PathSegments.Segment segment = pathSegments.segment(param.getParamName()); - if (segment == null) { - writer.append(" .queryParam(\"%s\", %s)", param.getParamName(), param.getName()).eol(); + if (pathSegments.segment(param.getParamName()) == null) { + if (isMap(param)) { + writer.append(" .queryParam(%s)", param.getName()).eol(); + } else { + writer.append(" .queryParam(\"%s\", %s)", param.getParamName(), param.getName()).eol(); + } } } } @@ -159,7 +160,11 @@ private void writeHeaders() { for (MethodParam param : method.getParams()) { ParamType paramType = param.getParamType(); if (paramType == ParamType.HEADER) { - writer.append(" .header(\"%s\", %s)", param.getParamName(), param.getName()).eol(); + if (isMap(param)) { + writer.append(" .header(%s)", param.getName()).eol(); + } else { + writer.append(" .header(\"%s\", %s)", param.getParamName(), param.getName()).eol(); + } } } } @@ -168,7 +173,11 @@ private void writeFormParams() { for (MethodParam param : method.getParams()) { ParamType paramType = param.getParamType(); if (paramType == ParamType.FORMPARAM) { - writer.append(" .formParam(\"%s\", %s)", param.getParamName(), param.getName()).eol(); + if (isMap(param)) { + writer.append(" .formParam(%s)", param.getName()).eol(); + } else { + writer.append(" .formParam(\"%s\", %s)", param.getParamName(), param.getName()).eol(); + } } else if (paramType == ParamType.FORM) { TypeElement formBeanType = ctx.getTypeElement(param.getRawType()); BeanParamReader form = new BeanParamReader(ctx, formBeanType, param.getName(), param.getShortType(), ParamType.FORMPARAM); @@ -203,6 +212,14 @@ private void writePaths(Set segments) { } } + private boolean isMap(MethodParam param) { + return isMap(param.getUType().mainType()); + } + + private boolean isMap(String type0) { + return type0.equals("java.util.Map"); + } + private boolean isList(String type0) { return type0.equals("java.util.List"); } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java index 05d6d5462..7d74e86f1 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java @@ -17,6 +17,7 @@ public class ElementReader { private final ProcessingContext ctx; private final Element element; + private final UType type; private final String rawType; private final String shortType; private final TypeHandler typeHandler; @@ -34,12 +35,13 @@ public class ElementReader { //private boolean notNullJavax; ElementReader(Element element, ProcessingContext ctx, ParamType defaultType, boolean formMarker) { - this(element, Util.typeDef(element.asType()), ctx, defaultType, formMarker); + this(element, null, Util.typeDef(element.asType()), ctx, defaultType, formMarker); } - ElementReader(Element element, String rawType, ProcessingContext ctx, ParamType defaultType, boolean formMarker) { + ElementReader(Element element, UType type, String rawType, ProcessingContext ctx, ParamType defaultType, boolean formMarker) { this.ctx = ctx; this.element = element; + this.type = type; this.rawType = rawType; this.shortType = Util.shortName(rawType); this.contextType = ctx.platform().isContextType(rawType); @@ -291,6 +293,10 @@ public String getRawType() { return rawType; } + public UType getType() { + return type; + } + public Element getElement() { return element; } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodParam.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodParam.java index 2c2da81ec..6ed5ad289 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodParam.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodParam.java @@ -8,8 +8,8 @@ public class MethodParam { private final ElementReader elementParam; - MethodParam(VariableElement param, String rawType, ProcessingContext ctx, ParamType defaultParamType, boolean formMarker) { - this.elementParam = new ElementReader(param, rawType, ctx, defaultParamType, formMarker); + MethodParam(VariableElement param, UType type, String rawType, ProcessingContext ctx, ParamType defaultParamType, boolean formMarker) { + this.elementParam = new ElementReader(param, type, rawType, ctx, defaultParamType, formMarker); } public void writeCtxGet(Append writer, PathSegments segments) { @@ -59,4 +59,8 @@ public String getParamName() { public ParamType getParamType() { return elementParam.getParamType(); } + + public UType getUType() { + return elementParam.getType(); + } } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java index 26f2698a4..f1af1481e 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java @@ -159,17 +159,16 @@ void read() { final List parameters = element.getParameters(); for (int i = 0; i < parameters.size(); i++) { - VariableElement p = parameters.get(i); - - String rawType; + TypeMirror typeMirror; if (actualParams != null) { - rawType = Util.typeDef(actualParams.get(i)); + typeMirror = actualParams.get(i); } else { - rawType = Util.typeDef(p.asType()); + typeMirror = p.asType(); } - - MethodParam param = new MethodParam(p, rawType, ctx, defaultParamType, formMarker); + String rawType = Util.typeDef(typeMirror); + UType type = Util.parse(typeMirror.toString()); + MethodParam param = new MethodParam(p, type, rawType, ctx, defaultParamType, formMarker); params.add(param); param.addImports(bean); } diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index 9a41fe875..f4b167822 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -25,7 +25,7 @@ io.avaje avaje-http-client - 1.7 + 1.8 diff --git a/tests/test-client/src/main/java/org/example/Simple.java b/tests/test-client/src/main/java/org/example/Simple.java index 3b957f1b1..0d8c4c3ab 100644 --- a/tests/test-client/src/main/java/org/example/Simple.java +++ b/tests/test-client/src/main/java/org/example/Simple.java @@ -8,6 +8,7 @@ import java.net.http.HttpResponse; import java.time.LocalDate; import java.util.List; +import java.util.Map; @Client @Path("moo") @@ -17,6 +18,15 @@ public interface Simple { @Get("{uid}/{date}") HttpResponse byIdg(long uid, LocalDate date, @Header URL access, @QueryParam("my-dat") LocalDate dt); + @Get("{uid}/withParams") + HttpResponse withParams(long uid, @QueryParam Map params); + + @Post("postFormWithParams") + void postFormWithParams(long uid, @FormParam Map frmParams, @Header Map headers, @QueryParam Map qparams); + + @Post("post3") + void post3(long uid, @Header String xHead, @Header("a-b") String ab); + @Get("users/{user}/repos") List listRepos(String user, String other); @@ -73,6 +83,7 @@ public boolean isActive() { public String email() { return email; } + public void setName(String name) { this.name = name; } From a89b69f7b43ca4217a798eb2ccd2bc9d8576b4b0 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Thu, 24 Jun 2021 18:31:13 +1200 Subject: [PATCH 0152/1323] #62 - ENH: [Client generator] Add Map option for header() queryParam() and formParam() --- http-generator-client/pom.xml | 2 +- tests/test-client/pom.xml | 39 +++++++++--- .../src/main/java/org/example/CommonApi.java | 24 ++++++++ .../java/org/example/client/package-info.java | 5 ++ .../org/example/server/CommonController.java | 25 ++++++++ .../main/java/org/example/server/Main.java | 28 +++++++++ .../test/java/org/example/CommonApiTest.java | 59 +++++++++++++++++++ .../src/test/java/org/example/SimpleTest.java | 2 + 8 files changed, 176 insertions(+), 8 deletions(-) create mode 100644 tests/test-client/src/main/java/org/example/CommonApi.java create mode 100644 tests/test-client/src/main/java/org/example/client/package-info.java create mode 100644 tests/test-client/src/main/java/org/example/server/CommonController.java create mode 100644 tests/test-client/src/main/java/org/example/server/Main.java create mode 100644 tests/test-client/src/test/java/org/example/CommonApiTest.java diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index a8cd8abe1..1bf958816 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -9,7 +9,7 @@ .. - avaje-http-generator-client + avaje-http-client-generator 11 diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index f4b167822..8e1c54061 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -14,6 +14,11 @@ test-client 1 + + 1.6 + 6.0 + + @@ -28,18 +33,18 @@ 1.8 - - com.fasterxml.jackson.core - jackson-databind - 2.12.3 - - io.avaje avaje-http-api 1.7-SNAPSHOT + + com.fasterxml.jackson.core + jackson-databind + 2.12.3 + + com.squareup.retrofit2 retrofit @@ -58,6 +63,16 @@ 2.9.0 + + io.avaje + avaje-jex + ${jex.version} + + + io.avaje + avaje-inject + ${avaje-inject.version} + org.junit.jupiter @@ -92,9 +107,19 @@ io.avaje - avaje-http-generator-client + avaje-http-client-generator 1.7-SNAPSHOT + + io.avaje + avaje-http-jex-generator + 1.7-SNAPSHOT + + + io.avaje + avaje-inject-generator + ${avaje-inject.version} + diff --git a/tests/test-client/src/main/java/org/example/CommonApi.java b/tests/test-client/src/main/java/org/example/CommonApi.java new file mode 100644 index 000000000..fd204148e --- /dev/null +++ b/tests/test-client/src/main/java/org/example/CommonApi.java @@ -0,0 +1,24 @@ +package org.example; + +import io.avaje.http.api.Get; +import io.avaje.http.api.Path; +import io.avaje.http.api.Produces; + +import java.time.LocalDate; + +@Path("/common") +public interface CommonApi { + + @Produces("text/plain") + @Get("plain") + String hello(); + + @Produces("text/plain") + @Get("name/{name}") + String name(String name); + + @Produces("text/plain") + @Get("{id}/{name}") + String p2(long id, String name, LocalDate after, Boolean more); + +} diff --git a/tests/test-client/src/main/java/org/example/client/package-info.java b/tests/test-client/src/main/java/org/example/client/package-info.java new file mode 100644 index 000000000..65acc3114 --- /dev/null +++ b/tests/test-client/src/main/java/org/example/client/package-info.java @@ -0,0 +1,5 @@ +@Client.Import(types = CommonApi.class) +package org.example.client; + +import io.avaje.http.api.Client; +import org.example.CommonApi; diff --git a/tests/test-client/src/main/java/org/example/server/CommonController.java b/tests/test-client/src/main/java/org/example/server/CommonController.java new file mode 100644 index 000000000..33ea9f1da --- /dev/null +++ b/tests/test-client/src/main/java/org/example/server/CommonController.java @@ -0,0 +1,25 @@ +package org.example.server; + +import io.avaje.http.api.Controller; +import org.example.CommonApi; + +import java.time.LocalDate; + +@Controller +public class CommonController implements CommonApi { + + @Override + public String hello() { + return "hello world"; + } + + @Override + public String name(String name) { + return "name[" + name + "]"; + } + + @Override + public String p2(long id, String name, LocalDate after, Boolean more) { + return "p2[" + id + ";" + name + "; after:" + after + " more:" + more + "]"; + } +} diff --git a/tests/test-client/src/main/java/org/example/server/Main.java b/tests/test-client/src/main/java/org/example/server/Main.java new file mode 100644 index 000000000..304c0ebad --- /dev/null +++ b/tests/test-client/src/main/java/org/example/server/Main.java @@ -0,0 +1,28 @@ +package org.example.server; + +import io.avaje.inject.ApplicationScope; +import io.avaje.inject.BeanScope; +import io.avaje.jex.Jex; +import io.avaje.jex.Routing; + +import java.util.List; + +public class Main { + + public static void main(String[] args) { + start(8090); + } + + public static Jex.Server start(int port) { + return start(port, ApplicationScope.scope()); + } + + public static Jex.Server start(int port, BeanScope context) { + + final List services = context.list(Routing.Service.class); + + final Jex jex = Jex.create(); + jex.routing().addAll(services); + return jex.port(port).start(); + } +} diff --git a/tests/test-client/src/test/java/org/example/CommonApiTest.java b/tests/test-client/src/test/java/org/example/CommonApiTest.java new file mode 100644 index 000000000..511169977 --- /dev/null +++ b/tests/test-client/src/test/java/org/example/CommonApiTest.java @@ -0,0 +1,59 @@ +package org.example; + +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import io.avaje.http.client.HttpClientContext; +import io.avaje.http.client.JacksonBodyAdapter; +import io.avaje.http.client.RequestLogger; +import org.example.server.Main; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +import java.time.LocalDate; +import java.util.Random; + +import static org.assertj.core.api.Assertions.assertThat; + +class CommonApiTest { + + static CommonApi client; + + @BeforeAll + static void start() { + + final int port = new Random().nextInt(1000) + 10_000; + Main.start(port); + + ObjectMapper objectMapper = new ObjectMapper() + .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + + final HttpClientContext clientContext = HttpClientContext.newBuilder() + .withBaseUrl("http://localhost:" + port) + .withRequestListener(new RequestLogger()) + .withBodyAdapter(new JacksonBodyAdapter(objectMapper)) + .build(); + + client = clientContext.create(CommonApi.class); + } + + @Test + void hello() { + assertThat(client.hello()).isEqualTo("hello world"); + } + + @Test + void name() { + assertThat(client.name("foo")).isEqualTo("name[foo]"); + assertThat(client.name("bar")).isEqualTo("name[bar]"); + } + + @Test + void p2() { + final LocalDate date = LocalDate.of(2021, 6, 24); + final String result = client.p2(42, "foo", date, false); + assertThat(result).isEqualTo("p2[42;foo; after:2021-06-24 more:false]"); + + final String result2 = client.p2(44, "bar", null, true); + assertThat(result2).isEqualTo("p2[44;bar; after:null more:true]"); + } +} diff --git a/tests/test-client/src/test/java/org/example/SimpleTest.java b/tests/test-client/src/test/java/org/example/SimpleTest.java index 8cf110b28..98e916fca 100644 --- a/tests/test-client/src/test/java/org/example/SimpleTest.java +++ b/tests/test-client/src/test/java/org/example/SimpleTest.java @@ -7,6 +7,7 @@ import io.avaje.http.client.JacksonBodyAdapter; import io.avaje.http.client.RequestLogger; import org.example.httpclient.GitHubUsers$HttpClient; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import java.util.List; @@ -15,6 +16,7 @@ public class SimpleTest { + @Disabled @Test void listRepos() { From 768f48a8530db2d2a9a63e37d030e741b38979c0 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Wed, 30 Jun 2021 20:54:09 +1200 Subject: [PATCH 0153/1323] #60 - Validation for bean params for controller class @Get method --- .../http/generator/core/ElementReader.java | 13 +++++++-- .../http/generator/core/MethodReader.java | 2 +- .../org/example/myapp/web/GetBeanForm.java | 29 +++++++++++++++++++ .../example/myapp/web/HelloController.java | 18 +++++------- .../example/myapp/HelloControllerTest.java | 28 ++++++++++++++++-- 5 files changed, 75 insertions(+), 15 deletions(-) create mode 100644 tests/test-javalin/src/main/java/org/example/myapp/web/GetBeanForm.java diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java index 7d74e86f1..f105f93dc 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java @@ -12,6 +12,7 @@ import javax.lang.model.element.Element; import javax.lang.model.element.TypeElement; +import javax.validation.Valid; public class ElementReader { @@ -179,8 +180,16 @@ void buildApiDocumentation(MethodDocBuilder methodDoc) { void writeValidate(Append writer) { if (!isPlatformContext() && typeHandler == null) { - writer.append("validator.validate(%s);", varName).eol(); - writer.append(" "); + TypeElement formBeanType = ctx.getTypeElement(rawType); + if (formBeanType != null) { + final Valid valid = formBeanType.getAnnotation(Valid.class); + if (valid != null) { + writer.append("validator.validate(%s);", varName).eol(); + } else { + writer.append("// no validation required on %s", varName).eol(); + } + writer.append(" "); + } } } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java index f1af1481e..34406e613 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java @@ -233,7 +233,7 @@ public String getFullPath() { } public boolean includeValidate() { - return bean.isIncludeValidator() && webMethod != WebMethod.GET; + return bean.isIncludeValidator(); } public String simpleName() { diff --git a/tests/test-javalin/src/main/java/org/example/myapp/web/GetBeanForm.java b/tests/test-javalin/src/main/java/org/example/myapp/web/GetBeanForm.java new file mode 100644 index 000000000..f92072efb --- /dev/null +++ b/tests/test-javalin/src/main/java/org/example/myapp/web/GetBeanForm.java @@ -0,0 +1,29 @@ +package org.example.myapp.web; + +import javax.validation.Valid; +import javax.validation.constraints.Email; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; + +@Valid +public class GetBeanForm { + + @NotNull @Size(min = 2, max = 150) + String name; + + @Email @Size(max = 100) + String email; + + public GetBeanForm(String name, String email) { + this.name = name; + this.email = email; + } + + @Override + public String toString() { + return "HelloForm{" + + "name='" + name + '\'' + + ", email='" + email + '\'' + + '}'; + } +} diff --git a/tests/test-javalin/src/main/java/org/example/myapp/web/HelloController.java b/tests/test-javalin/src/main/java/org/example/myapp/web/HelloController.java index c600634ac..e684d9c02 100644 --- a/tests/test-javalin/src/main/java/org/example/myapp/web/HelloController.java +++ b/tests/test-javalin/src/main/java/org/example/myapp/web/HelloController.java @@ -1,20 +1,12 @@ package org.example.myapp.web; -import io.avaje.http.api.Controller; -import io.avaje.http.api.Default; -import io.avaje.http.api.Delete; -import io.avaje.http.api.Form; -import io.avaje.http.api.Get; -import io.avaje.http.api.MediaType; -import io.avaje.http.api.Path; -import io.avaje.http.api.Post; -import io.avaje.http.api.Produces; -import io.avaje.http.api.QueryParam; +import io.avaje.http.api.*; import io.javalin.http.Context; import io.swagger.v3.oas.annotations.Hidden; import org.example.myapp.service.MyService; import jakarta.inject.Inject; + import javax.validation.Valid; import java.time.LocalDate; import java.util.ArrayList; @@ -126,6 +118,12 @@ HelloDto saveForm3(HelloForm helloForm) { return new HelloDto(52, helloForm.name, helloForm.email); } + @Produces("text/plain") + @Get("withValidBean") + String getGetBeanForm(@BeanParam GetBeanForm bean) { + return "ok name:" + bean.name; + } + @Hidden @Get List getAll() { diff --git a/tests/test-javalin/src/test/java/org/example/myapp/HelloControllerTest.java b/tests/test-javalin/src/test/java/org/example/myapp/HelloControllerTest.java index 848562d00..32ce0754c 100644 --- a/tests/test-javalin/src/test/java/org/example/myapp/HelloControllerTest.java +++ b/tests/test-javalin/src/test/java/org/example/myapp/HelloControllerTest.java @@ -41,6 +41,7 @@ class HelloControllerTest extends BaseWebTest { .with(httpClient) .build(); } + @Test void hello() { final Response response = get(baseUrl + "/hello/message"); @@ -214,9 +215,9 @@ void postForm_validation_expect_badRequest() { .asVoid(); } catch (HttpException e) { - assertEquals(422, e.getStatusCode()); + assertEquals(422, e.statusCode()); - final HttpResponse httpResponse = e.getHttpResponse(); + final HttpResponse httpResponse = e.httpResponse(); assertNotNull(httpResponse); assertEquals(422, httpResponse.statusCode()); @@ -229,6 +230,29 @@ void postForm_validation_expect_badRequest() { } } + @Test + void get_validate_bean_expect422() { + final HttpResponse hres = clientContext.request() + .path("hello/withValidBean") + .queryParam("email", "user@foo.com") + .GET() + .asString(); + + assertThat(hres.statusCode()).isEqualTo(422); + } + + @Test + void get_validate_bean_expect200() { + final HttpResponse hres = clientContext.request() + .path("hello/withValidBean") + .queryParam("name", "hello") + .queryParam("email", "user@foo.com") + .GET() + .asString(); + + assertThat(hres.statusCode()).isEqualTo(200); + } + @Test void delete() { given().delete(baseUrl + "/hello/52") From fb3a11c78122b82d9225c0322534ed2202b71ca1 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Wed, 30 Jun 2021 22:20:36 +1200 Subject: [PATCH 0154/1323] #42 - Support @Valid per methods rather than per controller --- .../http/generator/core/ControllerReader.java | 42 +++++++++++-------- .../http/generator/core/ElementReader.java | 35 ++++++++-------- .../http/generator/core/MethodReader.java | 11 ++++- .../src/main/resources/public/openapi.json | 42 +++++++++++++++++++ .../src/main/java/org/example/Main.java | 13 ++++++ .../java/org/example/web/HelloController.java | 13 ++++-- .../main/java/org/example/web/HelloDto.java | 5 +++ .../src/main/resources/public/openapi.json | 20 +++++++++ .../java/org/example/web/BaseWebTest.java | 3 ++ .../java/org/example/web/ErrorResponse.java | 27 ++++++++++++ .../org/example/web/HelloControllerTest.java | 33 +++++++++++++++ .../src/test/resources/logback-test.xml | 2 +- 12 files changed, 205 insertions(+), 41 deletions(-) create mode 100644 tests/test-jex/src/test/java/org/example/web/ErrorResponse.java diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java index e9528147e..156e12162 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java @@ -26,33 +26,25 @@ public class ControllerReader { private final ProcessingContext ctx; - private final TypeElement beanType; - private final List interfaces; - private final List interfaceMethods; - private final List roles; - private final List methods = new ArrayList<>(); - private final Set staticImportTypes = new TreeSet<>(); - private final Set importTypes = new TreeSet<>(); /** * The produces media type for the controller. Null implies JSON. */ private final String produces; - - private final boolean includeValidator; + private final boolean hasValid; + private boolean methodHasValid; /** * Flag set when the controller is dependant on a request scope type. */ private boolean requestScope; - private boolean docHidden; public ControllerReader(TypeElement beanType, ProcessingContext ctx) { @@ -64,14 +56,14 @@ public ControllerReader(TypeElement beanType, ProcessingContext ctx) { if (ctx.isOpenApiAvailable()) { docHidden = initDocHidden(); } - includeValidator = initIncludeValidator(); + this.hasValid = initHasValid(); this.produces = initProduces(); } protected void addImports(boolean withSingleton) { importTypes.add(Constants.IMPORT_HTTP_API); importTypes.add(beanType.getQualifiedName().toString()); - if (includeValidator) { + if (hasValid || methodHasValid) { importTypes.add(Constants.VALIDATOR); } if (withSingleton) { @@ -137,7 +129,7 @@ private boolean initDocHidden() { return findAnnotation(Hidden.class) != null; } - private boolean initIncludeValidator() { + private boolean initHasValid() { return findAnnotation(Valid.class) != null; } @@ -154,7 +146,11 @@ public boolean isDocHidden() { } public boolean isIncludeValidator() { - return includeValidator; + return hasValid || methodHasValid; + } + + public boolean hasValid() { + return hasValid; } /** @@ -166,7 +162,6 @@ boolean isRequestScoped() { } public void read(boolean withSingleton) { - addImports(withSingleton); if (!roles.isEmpty()) { ctx.platform().controllerRoles(roles, this); } @@ -178,6 +173,21 @@ public void read(boolean withSingleton) { } } readSuper(beanType); + deriveIncludeValidation(); + addImports(withSingleton); + } + + private void deriveIncludeValidation() { + methodHasValid = methodHasValid(); + } + + private boolean methodHasValid() { + for (MethodReader method : methods) { + if (method.hasValid()) { + return true; + } + } + return false; } private void readField(Element element) { @@ -215,13 +225,11 @@ private void readMethod(ExecutableElement element) { } private void readMethod(ExecutableElement method, DeclaredType declaredType) { - ExecutableType actualExecutable = null; if (declaredType != null) { // actual taking into account generics actualExecutable = (ExecutableType) ctx.asMemberOf(declaredType, method); } - MethodReader methodReader = new MethodReader(this, method, actualExecutable, ctx); if (methodReader.isWebMethod()) { methodReader.read(); diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java index f105f93dc..94813c6fa 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java @@ -1,12 +1,6 @@ package io.avaje.http.generator.core; -import io.avaje.http.api.BeanParam; -import io.avaje.http.api.Cookie; -import io.avaje.http.api.Default; -import io.avaje.http.api.Form; -import io.avaje.http.api.FormParam; -import io.avaje.http.api.Header; -import io.avaje.http.api.QueryParam; +import io.avaje.http.api.*; import io.avaje.http.generator.core.openapi.MethodDocBuilder; import io.avaje.http.generator.core.openapi.MethodParamDocBuilder; @@ -26,6 +20,7 @@ public class ElementReader { private final String snakeName; private final boolean formMarker; private final boolean contextType; + private final boolean useValidation; private String paramName; private ParamType paramType; @@ -53,11 +48,21 @@ public class ElementReader { this.paramName = varName; if (!contextType) { readAnnotations(element, defaultType); + useValidation = useValidation(); } else { paramType = ParamType.CONTEXT; + useValidation = false; } } + private boolean useValidation() { + if (typeHandler != null) { + return false; + } + TypeElement elementType = ctx.getTypeElement(rawType); + return elementType != null && elementType.getAnnotation(Valid.class) != null; + } + private void readAnnotations(Element element, ParamType defaultType) { notNullKotlin = (element.getAnnotation(org.jetbrains.annotations.NotNull.class) != null); @@ -179,17 +184,13 @@ void buildApiDocumentation(MethodDocBuilder methodDoc) { } void writeValidate(Append writer) { - if (!isPlatformContext() && typeHandler == null) { - TypeElement formBeanType = ctx.getTypeElement(rawType); - if (formBeanType != null) { - final Valid valid = formBeanType.getAnnotation(Valid.class); - if (valid != null) { - writer.append("validator.validate(%s);", varName).eol(); - } else { - writer.append("// no validation required on %s", varName).eol(); - } - writer.append(" "); + if (!contextType && typeHandler == null) { + if (useValidation) { + writer.append("validator.validate(%s);", varName).eol(); + } else { + writer.append("// no validation required on %s", varName).eol(); } + writer.append(" "); } } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java index 34406e613..1dc024e14 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java @@ -18,6 +18,7 @@ import javax.lang.model.type.ExecutableType; import javax.lang.model.type.TypeKind; import javax.lang.model.type.TypeMirror; +import javax.validation.Valid; import java.lang.annotation.Annotation; import java.util.ArrayList; import java.util.List; @@ -49,6 +50,7 @@ public class MethodReader { private final List actualParams; private final PathSegments pathSegments; + private final boolean hasValid; MethodReader(ControllerReader bean, ExecutableElement element, ExecutableType actualExecutable, ProcessingContext ctx) { this.ctx = ctx; @@ -60,11 +62,12 @@ public class MethodReader { this.methodRoles = Util.findRoles(element); this.javadoc = Javadoc.parse(ctx.getDocComment(element)); this.produces = produces(bean); - initWebMethodViaAnnotation(); if (isWebMethod()) { + this.hasValid = findAnnotation(Valid.class) != null; this.pathSegments = PathSegments.parse(Util.combinePath(bean.getPath(), webMethodPath)); } else { + this.hasValid = false; this.pathSegments = null; } } @@ -233,7 +236,11 @@ public String getFullPath() { } public boolean includeValidate() { - return bean.isIncludeValidator(); + return bean.hasValid() || hasValid; + } + + boolean hasValid() { + return hasValid; } public String simpleName() { diff --git a/tests/test-javalin/src/main/resources/public/openapi.json b/tests/test-javalin/src/main/resources/public/openapi.json index 4997f80bb..d7259d38d 100644 --- a/tests/test-javalin/src/main/resources/public/openapi.json +++ b/tests/test-javalin/src/main/resources/public/openapi.json @@ -482,6 +482,32 @@ } } }, + "/hello/withValidBean" : { + "get" : { + "tags" : [ ], + "summary" : "", + "description" : "", + "parameters" : [ { + "name" : "bean", + "in" : "bean", + "schema" : { + "$ref" : "#/components/schemas/GetBeanForm" + } + } ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, "/hello/{id}" : { "delete" : { "tags" : [ ], @@ -602,6 +628,22 @@ } } }, + "GetBeanForm" : { + "type" : "object", + "properties" : { + "name" : { + "maxLength" : 150, + "minLength" : 2, + "type" : "string", + "nullable" : false + }, + "email" : { + "maxLength" : 100, + "type" : "string", + "format" : "email" + } + } + }, "HelloDto" : { "type" : "object", "properties" : { diff --git a/tests/test-jex/src/main/java/org/example/Main.java b/tests/test-jex/src/main/java/org/example/Main.java index e6b46a83d..e6b912034 100644 --- a/tests/test-jex/src/main/java/org/example/Main.java +++ b/tests/test-jex/src/main/java/org/example/Main.java @@ -1,10 +1,14 @@ package org.example; +import io.avaje.http.api.ValidationException; import io.avaje.inject.ApplicationScope; import io.avaje.inject.BeanScope; import io.avaje.jex.Jex; import io.avaje.jex.Routing; +import java.util.LinkedHashMap; +import java.util.Map; + public class Main { public static void main(String[] args) { @@ -18,6 +22,15 @@ public static Jex.Server start(int port) { public static Jex.Server start(int port, BeanScope context) { final Jex jex = Jex.create(); jex.routing().addAll(context.list(Routing.Service.class)); + + jex.exception(ValidationException.class, (exception, ctx) -> { + Map map = new LinkedHashMap<>(); + map.put("message", exception.getMessage()); + map.put("errors", exception.getErrors()); + ctx.status(exception.getStatus()); + ctx.json(map); + }); + return jex.port(port).start(); } } diff --git a/tests/test-jex/src/main/java/org/example/web/HelloController.java b/tests/test-jex/src/main/java/org/example/web/HelloController.java index 86e44c0f8..b0b286e92 100644 --- a/tests/test-jex/src/main/java/org/example/web/HelloController.java +++ b/tests/test-jex/src/main/java/org/example/web/HelloController.java @@ -1,11 +1,10 @@ package org.example.web; -import io.avaje.http.api.Controller; -import io.avaje.http.api.Get; -import io.avaje.http.api.Path; -import io.avaje.http.api.Produces; +import io.avaje.http.api.*; import io.avaje.jex.Context; +import javax.validation.Valid; + // @Roles(AppRoles.BASIC_USER) @Controller @Path("/") @@ -37,4 +36,10 @@ String name(String name) { String splat(String name, Context ctx) { return "got name:" + name + " splat0:" + ctx.splat(0) + " splat1:" + ctx.splat(1); } + + @Valid + @Put + void put(HelloDto dto) { + dto.hashCode(); + } } diff --git a/tests/test-jex/src/main/java/org/example/web/HelloDto.java b/tests/test-jex/src/main/java/org/example/web/HelloDto.java index c8d59e014..61eb7651a 100644 --- a/tests/test-jex/src/main/java/org/example/web/HelloDto.java +++ b/tests/test-jex/src/main/java/org/example/web/HelloDto.java @@ -1,6 +1,11 @@ package org.example.web; +import javax.validation.Valid; +import javax.validation.constraints.NotNull; + +@Valid public class HelloDto { public int id; + @NotNull public String name; } diff --git a/tests/test-jex/src/main/resources/public/openapi.json b/tests/test-jex/src/main/resources/public/openapi.json index 9a091936a..e5c4c302b 100644 --- a/tests/test-jex/src/main/resources/public/openapi.json +++ b/tests/test-jex/src/main/resources/public/openapi.json @@ -22,6 +22,26 @@ } } } + }, + "put" : { + "tags" : [ ], + "summary" : "", + "description" : "", + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/HelloDto" + } + } + }, + "required" : true + }, + "responses" : { + "204" : { + "description" : "No content" + } + } } }, "/other/{name}" : { diff --git a/tests/test-jex/src/test/java/org/example/web/BaseWebTest.java b/tests/test-jex/src/test/java/org/example/web/BaseWebTest.java index ed2dc91a9..79ef6e747 100644 --- a/tests/test-jex/src/test/java/org/example/web/BaseWebTest.java +++ b/tests/test-jex/src/test/java/org/example/web/BaseWebTest.java @@ -9,6 +9,8 @@ import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; +import java.time.Duration; + public class BaseWebTest { static Jex.Server webServer; @@ -29,6 +31,7 @@ public static void shutdown() { public static HttpClientContext client() { return HttpClientContext.newBuilder() .withBaseUrl(baseUrl) + .withRequestTimeout(Duration.ofMinutes(2)) .withRequestListener(new RequestLogger()) .withBodyAdapter(new JacksonBodyAdapter(new ObjectMapper())) .build(); diff --git a/tests/test-jex/src/test/java/org/example/web/ErrorResponse.java b/tests/test-jex/src/test/java/org/example/web/ErrorResponse.java new file mode 100644 index 000000000..f59f2ee3f --- /dev/null +++ b/tests/test-jex/src/test/java/org/example/web/ErrorResponse.java @@ -0,0 +1,27 @@ +package org.example.web; + +import java.util.LinkedHashMap; +import java.util.Map; + +public class ErrorResponse { + + private String message; + + private Map errors = new LinkedHashMap<>(); + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public Map getErrors() { + return errors; + } + + public void setErrors(Map errors) { + this.errors = errors; + } +} diff --git a/tests/test-jex/src/test/java/org/example/web/HelloControllerTest.java b/tests/test-jex/src/test/java/org/example/web/HelloControllerTest.java index a464a62f0..62c20319e 100644 --- a/tests/test-jex/src/test/java/org/example/web/HelloControllerTest.java +++ b/tests/test-jex/src/test/java/org/example/web/HelloControllerTest.java @@ -1,12 +1,14 @@ package org.example.web; import io.avaje.http.client.HttpClientContext; +import io.avaje.http.client.HttpException; import org.junit.jupiter.api.Test; import java.net.http.HttpResponse; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; class HelloControllerTest extends BaseWebTest { @@ -40,4 +42,35 @@ void getName() { void splat() { assertEquals("got name:one splat0:a/b splat1:x/y/z", client.request().path("splat/one/a/b/other/x/y/z").GET().asString().body()); } + + @Test + void validation() { + + HelloDto helloDto = new HelloDto(); + helloDto.id = 42; + + final HttpResponse hres = client.request() + .body(helloDto) + .PUT().asString(); + + assertThat(hres.statusCode()).isEqualTo(422); + assertThat(hres.body()).contains("{\"name\":\"must not be null\"}"); + } + + @Test + void validation_expect_HttpException() { + + HelloDto helloDto = new HelloDto(); + helloDto.id = 42; + + final HttpException ex = assertThrows(HttpException.class, () -> + client.request() + .body(helloDto) + .PUT().asVoid()); + + assertThat(ex.statusCode()).isEqualTo(422); + + final ErrorResponse errBean = ex.bean(ErrorResponse.class); + assertThat(errBean.getErrors().get("name")).isEqualTo("must not be null"); + } } diff --git a/tests/test-jex/src/test/resources/logback-test.xml b/tests/test-jex/src/test/resources/logback-test.xml index 055b7e870..4e60ed2f6 100644 --- a/tests/test-jex/src/test/resources/logback-test.xml +++ b/tests/test-jex/src/test/resources/logback-test.xml @@ -14,6 +14,6 @@ - + From 000cd48f4597cb47f7c99a60fc041a7463187d99 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Wed, 30 Jun 2021 22:33:25 +1200 Subject: [PATCH 0155/1323] Bump to avaje-inject 6.1, add requires=Validator.class to tests --- http-hibernate-validator/pom.xml | 4 ++-- tests/test-client/pom.xml | 2 +- tests/test-helidon/pom.xml | 4 ++-- tests/test-javalin/pom.xml | 4 ++-- .../src/main/java/org/example/myapp/Main.java | 8 +++----- tests/test-jex/pom.xml | 2 +- tests/test-jex/src/main/java/org/example/Main.java | 3 +++ tests/test-jex/src/main/resources/public/openapi.json | 3 ++- tests/test-spark/pom.xml | 4 ++-- 9 files changed, 18 insertions(+), 16 deletions(-) diff --git a/http-hibernate-validator/pom.xml b/http-hibernate-validator/pom.xml index 64e801fda..f1f4a0b30 100644 --- a/http-hibernate-validator/pom.xml +++ b/http-hibernate-validator/pom.xml @@ -41,7 +41,7 @@ io.avaje avaje-inject - 6.0 + 6.1 provided @@ -50,7 +50,7 @@ io.avaje avaje-inject-generator - 6.0 + 6.1 provided diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index 8e1c54061..af3725062 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -16,7 +16,7 @@ 1.6 - 6.0 + 6.1 diff --git a/tests/test-helidon/pom.xml b/tests/test-helidon/pom.xml index 339ce8b43..a177a5175 100644 --- a/tests/test-helidon/pom.xml +++ b/tests/test-helidon/pom.xml @@ -41,12 +41,12 @@ io.avaje avaje-inject - 6.0 + 6.1 io.avaje avaje-inject-generator - 6.0 + 6.1 provided diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index bf5a21cb0..57e38cd07 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -52,7 +52,7 @@ io.avaje avaje-inject - 6.0 + 6.1 @@ -78,7 +78,7 @@ io.avaje avaje-inject-generator - 6.0 + 6.1 provided diff --git a/tests/test-javalin/src/main/java/org/example/myapp/Main.java b/tests/test-javalin/src/main/java/org/example/myapp/Main.java index 830a2ca6a..860ed77e7 100644 --- a/tests/test-javalin/src/main/java/org/example/myapp/Main.java +++ b/tests/test-javalin/src/main/java/org/example/myapp/Main.java @@ -1,10 +1,8 @@ package org.example.myapp; -import io.avaje.http.api.InvalidPathArgumentException; -import io.avaje.http.api.InvalidTypeArgumentException; -import io.avaje.http.api.ValidationException; -import io.avaje.http.api.WebRoutes; +import io.avaje.http.api.*; import io.avaje.inject.ApplicationScope; +import io.avaje.inject.InjectModule; import io.javalin.Javalin; import io.javalin.http.staticfiles.Location; import io.swagger.v3.oas.annotations.OpenAPIDefinition; @@ -16,7 +14,7 @@ import java.util.List; import java.util.Map; -//@ContextModule(name = "app", dependsOn= "validator") +@InjectModule(name = "app", dependsOn= "validator", requires = Validator.class) @OpenAPIDefinition(info = @Info(title = "Example service", description = "Example Javalin controllers with Java and Maven")) public class Main { diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 8d31ca1f6..feae1ab4b 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -19,7 +19,7 @@ 1.6 2.0.8 2.12.3 - 6.0 + 6.1 1.7-SNAPSHOT diff --git a/tests/test-jex/src/main/java/org/example/Main.java b/tests/test-jex/src/main/java/org/example/Main.java index e6b912034..23a6bccc7 100644 --- a/tests/test-jex/src/main/java/org/example/Main.java +++ b/tests/test-jex/src/main/java/org/example/Main.java @@ -1,14 +1,17 @@ package org.example; import io.avaje.http.api.ValidationException; +import io.avaje.http.api.Validator; import io.avaje.inject.ApplicationScope; import io.avaje.inject.BeanScope; +import io.avaje.inject.InjectModule; import io.avaje.jex.Jex; import io.avaje.jex.Routing; import java.util.LinkedHashMap; import java.util.Map; +@InjectModule(requires = Validator.class) public class Main { public static void main(String[] args) { diff --git a/tests/test-jex/src/main/resources/public/openapi.json b/tests/test-jex/src/main/resources/public/openapi.json index e5c4c302b..14774b6dc 100644 --- a/tests/test-jex/src/main/resources/public/openapi.json +++ b/tests/test-jex/src/main/resources/public/openapi.json @@ -129,7 +129,8 @@ "nullable" : false }, "name" : { - "type" : "string" + "type" : "string", + "nullable" : false } } } diff --git a/tests/test-spark/pom.xml b/tests/test-spark/pom.xml index 8a8862f1c..3ec3b8498 100644 --- a/tests/test-spark/pom.xml +++ b/tests/test-spark/pom.xml @@ -43,7 +43,7 @@ io.avaje avaje-inject - 6.0 + 6.1 @@ -69,7 +69,7 @@ io.avaje avaje-inject-generator - 6.0 + 6.1 provided From 502f1a653fd66a30bcb56f0f4ae4511f884bf102 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Wed, 30 Jun 2021 22:34:29 +1200 Subject: [PATCH 0156/1323] Temp disable test modules for release --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index cd389f2b6..90c0554b4 100644 --- a/pom.xml +++ b/pom.xml @@ -39,7 +39,7 @@ http-generator-jex http-generator-helidon http-generator-client - tests + From 67e0775478565b043c966276ebc482b61e9ff068 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Wed, 30 Jun 2021 22:35:13 +1200 Subject: [PATCH 0157/1323] [maven-release-plugin] prepare release avaje-http-generator-parent-1.7 --- http-api/pom.xml | 4 ++-- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 4 ++-- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- pom.xml | 4 ++-- 7 files changed, 10 insertions(+), 10 deletions(-) diff --git a/http-api/pom.xml b/http-api/pom.xml index 296233edd..c714a739d 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-generator-parent - 1.7-SNAPSHOT + 1.7 .. @@ -20,7 +20,7 @@ scm:git:git@github.com:avaje/avaje-http.git - HEAD + avaje-http-generator-parent-1.7 diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index 1bf958816..b72dc4193 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -5,7 +5,7 @@ io.avaje avaje-http-generator-parent - 1.7-SNAPSHOT + 1.7 .. diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index a3c01a0ae..c2d40a250 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-generator-parent - 1.7-SNAPSHOT + 1.7 .. @@ -33,7 +33,7 @@ io.avaje avaje-http-api - 1.7-SNAPSHOT + 1.7 diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index 00f79d176..08cca7afb 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-generator-parent - 1.7-SNAPSHOT + 1.7 .. diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index 419756c14..d488efbc1 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-generator-parent - 1.7-SNAPSHOT + 1.7 .. diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index 77e87476d..b080c53e4 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-generator-parent - 1.7-SNAPSHOT + 1.7 .. diff --git a/pom.xml b/pom.xml index 90c0554b4..375deb94b 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-generator-parent - 1.7-SNAPSHOT + 1.7 pom @@ -15,7 +15,7 @@ scm:git:git@github.com:avaje/avaje-http.git - HEAD + avaje-http-generator-parent-1.7 From 1ad97d257e34f04cfcabb179fa66a527338c01fc Mon Sep 17 00:00:00 2001 From: rbygrave Date: Wed, 30 Jun 2021 22:35:23 +1200 Subject: [PATCH 0158/1323] [maven-release-plugin] prepare for next development iteration --- http-api/pom.xml | 4 ++-- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 4 ++-- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- pom.xml | 4 ++-- 7 files changed, 10 insertions(+), 10 deletions(-) diff --git a/http-api/pom.xml b/http-api/pom.xml index c714a739d..f9ad932de 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-generator-parent - 1.7 + 1.8-SNAPSHOT .. @@ -20,7 +20,7 @@ scm:git:git@github.com:avaje/avaje-http.git - avaje-http-generator-parent-1.7 + HEAD diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index b72dc4193..436bf80e6 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -5,7 +5,7 @@ io.avaje avaje-http-generator-parent - 1.7 + 1.8-SNAPSHOT .. diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index c2d40a250..9a2f929c9 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-generator-parent - 1.7 + 1.8-SNAPSHOT .. @@ -33,7 +33,7 @@ io.avaje avaje-http-api - 1.7 + 1.8-SNAPSHOT diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index 08cca7afb..1e506a1b2 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-generator-parent - 1.7 + 1.8-SNAPSHOT .. diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index d488efbc1..b9ef12c6c 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-generator-parent - 1.7 + 1.8-SNAPSHOT .. diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index b080c53e4..4c03d0c9b 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-generator-parent - 1.7 + 1.8-SNAPSHOT .. diff --git a/pom.xml b/pom.xml index 375deb94b..991d2f980 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-generator-parent - 1.7 + 1.8-SNAPSHOT pom @@ -15,7 +15,7 @@ scm:git:git@github.com:avaje/avaje-http.git - avaje-http-generator-parent-1.7 + HEAD From 225b275504dd83e91da2234e6ff58bd91cf3511f Mon Sep 17 00:00:00 2001 From: rbygrave Date: Wed, 30 Jun 2021 22:41:01 +1200 Subject: [PATCH 0159/1323] Bump test modules to 1.8-SNAPSHOT --- pom.xml | 2 +- tests/test-client/pom.xml | 6 +++--- tests/test-helidon/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-spark/pom.xml | 4 ++-- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/pom.xml b/pom.xml index 991d2f980..ef7354e27 100644 --- a/pom.xml +++ b/pom.xml @@ -39,7 +39,7 @@ http-generator-jex http-generator-helidon http-generator-client - + tests diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index af3725062..7d2780979 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -36,7 +36,7 @@ io.avaje avaje-http-api - 1.7-SNAPSHOT + 1.8-SNAPSHOT @@ -108,12 +108,12 @@ io.avaje avaje-http-client-generator - 1.7-SNAPSHOT + 1.8-SNAPSHOT io.avaje avaje-http-jex-generator - 1.7-SNAPSHOT + 1.8-SNAPSHOT io.avaje diff --git a/tests/test-helidon/pom.xml b/tests/test-helidon/pom.xml index a177a5175..c1979432c 100644 --- a/tests/test-helidon/pom.xml +++ b/tests/test-helidon/pom.xml @@ -17,7 +17,7 @@ org.example.Main 2.3.0 - 1.7-SNAPSHOT + 1.8-SNAPSHOT diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 57e38cd07..f2749b232 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -20,7 +20,7 @@ 2.0.8 1.3.71 2.12.3 - 1.7-SNAPSHOT + 1.8-SNAPSHOT diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index feae1ab4b..326dc2d3f 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -20,7 +20,7 @@ 2.0.8 2.12.3 6.1 - 1.7-SNAPSHOT + 1.8-SNAPSHOT diff --git a/tests/test-spark/pom.xml b/tests/test-spark/pom.xml index 3ec3b8498..8a2146642 100644 --- a/tests/test-spark/pom.xml +++ b/tests/test-spark/pom.xml @@ -17,7 +17,7 @@ org.example.myapp.Main 2.0.8 - 1.7-SNAPSHOT + 1.8-SNAPSHOT @@ -76,7 +76,7 @@ io.avaje avaje-http-spark-generator - 1.7-SNAPSHOT + 1.8-SNAPSHOT provided From eea568cbe99731b927eb73ff838e091355614de8 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Wed, 30 Jun 2021 22:42:19 +1200 Subject: [PATCH 0160/1323] Update README with correct version --- http-client/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/http-client/README.md b/http-client/README.md index e38859ed6..cc55b62c6 100644 --- a/http-client/README.md +++ b/http-client/README.md @@ -18,7 +18,7 @@ A lightweight wrapper to the [JDK 11+ Java Http Client](http://openjdk.java.net/ io.avaje avaje-http-client - 1.9 + 1.8 ``` From 52a600d3b72c286aa7cfa3adfda871d540333e37 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Mon, 5 Jul 2021 10:27:03 +1200 Subject: [PATCH 0161/1323] #23 - ENH: Add CompletableFuture asByteArray(), asLines() asInputStream() --- .../java/io/avaje/http/client/DHttpAsync.java | 33 ++++++++--- .../avaje/http/client/HttpAsyncResponse.java | 26 +++++++- .../http/client/HelloControllerTest.java | 59 +++++++++++++++++++ 3 files changed, 109 insertions(+), 9 deletions(-) diff --git a/http-client/client/src/main/java/io/avaje/http/client/DHttpAsync.java b/http-client/client/src/main/java/io/avaje/http/client/DHttpAsync.java index 721296ee7..dba3cce5a 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/DHttpAsync.java +++ b/http-client/client/src/main/java/io/avaje/http/client/DHttpAsync.java @@ -1,5 +1,6 @@ package io.avaje.http.client; +import java.io.InputStream; import java.net.http.HttpResponse; import java.util.List; import java.util.concurrent.CompletableFuture; @@ -13,20 +14,25 @@ class DHttpAsync implements HttpAsyncResponse { this.request = request; } - @Override - public CompletableFuture> withHandler(HttpResponse.BodyHandler handler) { + private CompletableFuture> with(boolean loggable, HttpResponse.BodyHandler handler) { return request - .performSendAsync(false, handler) + .performSendAsync(loggable, handler) .thenApply(request::afterAsync); } + @Override + public CompletableFuture> withHandler(HttpResponse.BodyHandler handler) { + return with(false, handler); + } + @Override public CompletableFuture> asDiscarding() { - return withHandler(HttpResponse.BodyHandlers.discarding()); + return with(false, HttpResponse.BodyHandlers.discarding()); } @Override public CompletableFuture> asVoid() { + // read the response content as bytes so that it is available for error response return request .performSendAsync(true, HttpResponse.BodyHandlers.ofByteArray()) .thenApply(request::asyncVoid); @@ -34,9 +40,22 @@ public CompletableFuture> asVoid() { @Override public CompletableFuture> asString() { - return request - .performSendAsync(true, HttpResponse.BodyHandlers.ofString()) - .thenApply(request::afterAsync); + return with(true, HttpResponse.BodyHandlers.ofString()); + } + + @Override + public CompletableFuture> asByteArray() { + return with(true, HttpResponse.BodyHandlers.ofByteArray()); + } + + @Override + public CompletableFuture>> asLines() { + return with(false, HttpResponse.BodyHandlers.ofLines()); + } + + @Override + public CompletableFuture> asInputStream() { + return with(false, HttpResponse.BodyHandlers.ofInputStream()); } @Override diff --git a/http-client/client/src/main/java/io/avaje/http/client/HttpAsyncResponse.java b/http-client/client/src/main/java/io/avaje/http/client/HttpAsyncResponse.java index 73b5bfc07..ebf4159f9 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/HttpAsyncResponse.java +++ b/http-client/client/src/main/java/io/avaje/http/client/HttpAsyncResponse.java @@ -1,5 +1,6 @@ package io.avaje.http.client; +import java.io.InputStream; import java.net.http.HttpResponse; import java.util.List; import java.util.concurrent.CompletableFuture; @@ -110,6 +111,27 @@ public interface HttpAsyncResponse { */ CompletableFuture> asString(); + /** + * Process as response {@literal HttpResponse}. + * + * @return The CompletableFuture of the response + */ + CompletableFuture> asByteArray(); + + /** + * Process as response {@literal HttpResponse>}. + * + * @return The CompletableFuture of the response + */ + CompletableFuture>> asLines(); + + /** + * Process as response {@literal HttpResponse}. + * + * @return The CompletableFuture of the response + */ + CompletableFuture> asInputStream(); + /** * Process with any given {@code HttpResponse.BodyHandler}. * @@ -147,10 +169,10 @@ public interface HttpAsyncResponse { * }); * } * - * @param bodyHandlers The body handler to use to process the response + * @param bodyHandler The body handler to use to process the response * @return The CompletableFuture of the response */ - CompletableFuture> withHandler(HttpResponse.BodyHandler bodyHandlers); + CompletableFuture> withHandler(HttpResponse.BodyHandler bodyHandler); /** * Process expecting a bean response body (typically from json content). diff --git a/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java b/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java index f67e18a78..d8197d0d0 100644 --- a/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java +++ b/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java @@ -7,6 +7,7 @@ import java.io.*; import java.net.http.HttpClient; import java.net.http.HttpResponse; +import java.nio.charset.StandardCharsets; import java.nio.file.Path; import java.time.Duration; import java.time.LocalDate; @@ -58,6 +59,22 @@ void asLines() { assertThat(lines.get(0)).contains("{\"id\":1, \"name\":\"one\"}"); } + @Test + void asLines_async() throws ExecutionException, InterruptedException { + final CompletableFuture>> future = clientContext.request() + .path("hello").path("stream") + .GET() + .async() + .asLines(); + + final HttpResponse> hres = future.get(); + assertThat(hres.statusCode()).isEqualTo(200); + final List lines = hres.body().collect(Collectors.toList()); + + assertThat(lines).hasSize(4); + assertThat(lines.get(0)).contains("{\"id\":1, \"name\":\"one\"}"); + } + @Test void asInputStream() throws IOException { final HttpResponse hres = @@ -78,6 +95,26 @@ void asInputStream() throws IOException { assertThat(allLines.get(0)).contains("{\"id\":1, \"name\":\"one\"}"); } + @Test + void asInputStream_async() throws IOException, ExecutionException, InterruptedException { + final CompletableFuture> future = clientContext.request() + .path("hello").path("stream") + .GET() + .async().asInputStream(); + + final HttpResponse hres = future.get(); + assertThat(hres.statusCode()).isEqualTo(200); + final LineNumberReader reader = new LineNumberReader(new InputStreamReader(hres.body())); + + List allLines = new ArrayList<>(); + String line; + while ((line = reader.readLine()) != null) { + allLines.add(line); + } + assertThat(allLines).hasSize(4); + assertThat(allLines.get(0)).contains("{\"id\":1, \"name\":\"one\"}"); + } + @Test void asFile() throws IOException { final Path path = File.createTempFile("test", "dump").toPath(); @@ -241,6 +278,28 @@ void get_helloMessage() { assertThat(hres.statusCode()).isEqualTo(200); } + @Test + void asByteArray() { + final HttpResponse hres = clientContext.request() + .path("hello").path("message") + .GET().asByteArray(); + + final byte[] body = hres.body(); + assertThat(new String(body, StandardCharsets.UTF_8)).contains("hello world"); + assertThat(hres.statusCode()).isEqualTo(200); + } + + @Test + void asByteArray_async() throws ExecutionException, InterruptedException { + final CompletableFuture> future = clientContext.request() + .path("hello").path("message") + .GET().async().asByteArray(); + + final HttpResponse hres = future.get(); + assertThat(new String(hres.body(), StandardCharsets.UTF_8)).contains("hello world"); + assertThat(hres.statusCode()).isEqualTo(200); + } + @Test void get_notFound() { UUID nullUUID = null; From a13f8f4bedd0e127960168d4f459644a1b946216 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Mon, 5 Jul 2021 15:26:31 +1200 Subject: [PATCH 0162/1323] #23 - ENH: Add HttpCall asByteArray(), asLines() asInputStream() --- .../java/io/avaje/http/client/DHttpCall.java | 49 ++++++++++ .../avaje/http/client/HttpCallResponse.java | 22 +++++ .../http/client/HelloControllerTest.java | 98 +++++++++++++++++-- 3 files changed, 159 insertions(+), 10 deletions(-) diff --git a/http-client/client/src/main/java/io/avaje/http/client/DHttpCall.java b/http-client/client/src/main/java/io/avaje/http/client/DHttpCall.java index 96f731e07..53ec3abba 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/DHttpCall.java +++ b/http-client/client/src/main/java/io/avaje/http/client/DHttpCall.java @@ -1,5 +1,6 @@ package io.avaje.http.client; +import java.io.InputStream; import java.net.http.HttpResponse; import java.util.List; import java.util.concurrent.CompletableFuture; @@ -28,6 +29,21 @@ public HttpCall> asString() { return new CallString(); } + @Override + public HttpCall> asByteArray() { + return new CallBytes(); + } + + @Override + public HttpCall>> asLines() { + return new CallLines(); + } + + @Override + public HttpCall> asInputStream() { + return new CallInputStream(); + } + @Override public HttpCall> withHandler(HttpResponse.BodyHandler bodyHandler) { return new CallHandler<>(bodyHandler); @@ -81,6 +97,39 @@ public CompletableFuture> async() { } } + private class CallBytes implements HttpCall> { + @Override + public HttpResponse execute() { + return request.asByteArray(); + } + @Override + public CompletableFuture> async() { + return request.async().asByteArray(); + } + } + + private class CallLines implements HttpCall>> { + @Override + public HttpResponse> execute() { + return request.asLines(); + } + @Override + public CompletableFuture>> async() { + return request.async().asLines(); + } + } + + private class CallInputStream implements HttpCall> { + @Override + public HttpResponse execute() { + return request.asInputStream(); + } + @Override + public CompletableFuture> async() { + return request.async().asInputStream(); + } + } + private class CallBean implements HttpCall { private final Class type; CallBean(Class type) { diff --git a/http-client/client/src/main/java/io/avaje/http/client/HttpCallResponse.java b/http-client/client/src/main/java/io/avaje/http/client/HttpCallResponse.java index f657fef2b..dec31adb4 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/HttpCallResponse.java +++ b/http-client/client/src/main/java/io/avaje/http/client/HttpCallResponse.java @@ -1,5 +1,6 @@ package io.avaje.http.client; +import java.io.InputStream; import java.net.http.HttpResponse; import java.util.List; import java.util.stream.Stream; @@ -80,6 +81,27 @@ public interface HttpCallResponse { */ HttpCall> asString(); + /** + * Process as response {@literal HttpResponse}. + * + * @return The CompletableFuture of the response + */ + HttpCall> asByteArray(); + + /** + * Process as response {@literal HttpResponse>}. + * + * @return The CompletableFuture of the response + */ + HttpCall>> asLines(); + + /** + * Process as response {@literal HttpResponse}. + * + * @return The CompletableFuture of the response + */ + HttpCall> asInputStream(); + /** * Call using any given {@code HttpResponse.BodyHandler}. *

{@code
diff --git a/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java b/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java
index d8197d0d0..d06f9aa46 100644
--- a/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java
+++ b/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java
@@ -75,6 +75,36 @@ void asLines_async() throws ExecutionException, InterruptedException {
     assertThat(lines.get(0)).contains("{\"id\":1, \"name\":\"one\"}");
   }
 
+  @Test
+  void asLines_callExecute() {
+    final HttpResponse> hres =
+      clientContext.request()
+        .path("hello").path("stream")
+        .GET()
+        .call().asLines().execute();
+
+    assertThat(hres.statusCode()).isEqualTo(200);
+    final List lines = hres.body().collect(Collectors.toList());
+
+    assertThat(lines).hasSize(4);
+    assertThat(lines.get(0)).contains("{\"id\":1, \"name\":\"one\"}");
+  }
+
+  @Test
+  void asLines_callAsync() throws ExecutionException, InterruptedException {
+    final HttpResponse> hres =
+      clientContext.request()
+        .path("hello").path("stream")
+        .GET()
+        .call().asLines().async().get();
+
+    assertThat(hres.statusCode()).isEqualTo(200);
+    final List lines = hres.body().collect(Collectors.toList());
+
+    assertThat(lines).hasSize(4);
+    assertThat(lines.get(0)).contains("{\"id\":1, \"name\":\"one\"}");
+  }
+
   @Test
   void asInputStream() throws IOException {
     final HttpResponse hres =
@@ -84,13 +114,7 @@ void asInputStream() throws IOException {
         .asInputStream();
 
     assertThat(hres.statusCode()).isEqualTo(200);
-    final LineNumberReader reader = new LineNumberReader(new InputStreamReader(hres.body()));
-
-    List allLines = new ArrayList<>();
-    String line;
-    while ((line = reader.readLine()) != null) {
-      allLines.add(line);
-    }
+    List allLines = readLines(hres);
     assertThat(allLines).hasSize(4);
     assertThat(allLines.get(0)).contains("{\"id\":1, \"name\":\"one\"}");
   }
@@ -104,15 +128,49 @@ void asInputStream_async() throws IOException, ExecutionException, InterruptedEx
 
     final HttpResponse hres = future.get();
     assertThat(hres.statusCode()).isEqualTo(200);
-    final LineNumberReader reader = new LineNumberReader(new InputStreamReader(hres.body()));
+    List allLines = readLines(hres);
+    assertThat(allLines).hasSize(4);
+    assertThat(allLines.get(0)).contains("{\"id\":1, \"name\":\"one\"}");
+  }
+
+  @Test
+  void asInputStream_callExecute() throws IOException {
+    final HttpResponse hres =
+      clientContext.request()
+        .path("hello").path("stream")
+        .GET()
+        .call()
+        .asInputStream().execute();
+
+    assertThat(hres.statusCode()).isEqualTo(200);
+    List allLines = readLines(hres);
+    assertThat(allLines).hasSize(4);
+    assertThat(allLines.get(0)).contains("{\"id\":1, \"name\":\"one\"}");
+  }
+
+  @Test
+  void asInputStream_callAsync() throws IOException, ExecutionException, InterruptedException {
+    final HttpResponse hres =
+      clientContext.request()
+        .path("hello").path("stream")
+        .GET()
+        .call()
+        .asInputStream().async().get();
+
+    assertThat(hres.statusCode()).isEqualTo(200);
+    List allLines = readLines(hres);
+    assertThat(allLines).hasSize(4);
+    assertThat(allLines.get(0)).contains("{\"id\":1, \"name\":\"one\"}");
+  }
 
+  private List readLines(HttpResponse hres) throws IOException {
+    final LineNumberReader reader = new LineNumberReader(new InputStreamReader(hres.body()));
     List allLines = new ArrayList<>();
     String line;
     while ((line = reader.readLine()) != null) {
       allLines.add(line);
     }
-    assertThat(allLines).hasSize(4);
-    assertThat(allLines.get(0)).contains("{\"id\":1, \"name\":\"one\"}");
+    return allLines;
   }
 
   @Test
@@ -353,6 +411,26 @@ void callStringAsync() throws ExecutionException, InterruptedException {
     assertThat(hres.statusCode()).isEqualTo(200);
   }
 
+  @Test
+  void callBytes() {
+    final HttpResponse hres = clientContext.request()
+      .path("hello").path("message")
+      .GET().call().asByteArray().execute();
+
+    assertThat(new String(hres.body(), StandardCharsets.UTF_8)).contains("hello world");
+    assertThat(hres.statusCode()).isEqualTo(200);
+  }
+
+  @Test
+  void callBytesAsync() throws ExecutionException, InterruptedException {
+    final HttpResponse hres = clientContext.request()
+      .path("hello").path("message")
+      .GET().call().asByteArray().async().get();
+
+    assertThat(new String(hres.body(), StandardCharsets.UTF_8)).contains("hello world");
+    assertThat(hres.statusCode()).isEqualTo(200);
+  }
+
   @Test
   void callWithHandler() {
     final HttpResponse hres = clientContext.request()

From b4684f8a22e4d5bc5339d19c05c6a2e3930c4679 Mon Sep 17 00:00:00 2001
From: rbygrave 
Date: Mon, 5 Jul 2021 20:15:02 +1200
Subject: [PATCH 0163/1323] #63 - Support client code generation for
 CompletableFuture and HttpCall with various generic types

---
 .../generator/client/ClientMethodWriter.java  |  7 +-
 .../http/generator/client/KnownResponse.java  | 34 +++++--
 tests/test-client/pom.xml                     |  2 +-
 .../src/main/java/org/example/JunkApi.java    | 93 +++++++++++++++++++
 4 files changed, 126 insertions(+), 10 deletions(-)
 create mode 100644 tests/test-client/src/main/java/org/example/JunkApi.java

diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java
index 868f392c8..083bb605a 100644
--- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java
+++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java
@@ -38,6 +38,9 @@ void addImportTypes(ControllerReader reader) {
   }
 
   private void methodStart(Append writer) {
+    for (MethodParam param : method.getParams()) {
+      checkBodyHandler(param);
+    }
     writer.append("  // %s %s", webMethod, method.getWebMethodPath()).eol();
     writer.append("  @Override").eol();
     writer.append("  public %s %s(", returnType.shortType(), method.simpleName());
@@ -48,7 +51,6 @@ private void methodStart(Append writer) {
       }
       writer.append(param.getUType().shortType()).append(" ");
       writer.append(param.getName());
-      checkBodyHandler(param);
     }
     writer.append(") {").eol();
   }
@@ -59,6 +61,7 @@ private void methodStart(Append writer) {
   private void checkBodyHandler(MethodParam param) {
     if (param.getRawType().startsWith(BODY_HANDLER)) {
       bodyHandlerParam = param;
+      param.getUType().param0();
     }
   }
 
@@ -82,7 +85,7 @@ void write() {
     WebMethod webMethod = method.getWebMethod();
     writer.append("      .%s()", webMethod.name()).eol();
     if (returnType == UType.VOID) {
-      writer.append("      .asDiscarding();").eol();
+      writer.append("      .asVoid();").eol();
     } else {
       String known = KNOWN_RESPONSE.get(returnType.full());
       if (known != null) {
diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/KnownResponse.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/KnownResponse.java
index a7dc0c248..835cfda88 100644
--- a/http-generator-client/src/main/java/io/avaje/http/generator/client/KnownResponse.java
+++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/KnownResponse.java
@@ -12,20 +12,40 @@ class KnownResponse {
 
   KnownResponse() {
     map.put("void", ".asVoid();");
+    map.put("java.lang.String", ".asPlainString().body();");
+
     map.put("java.net.http.HttpResponse", ".asVoid();");
     map.put("java.net.http.HttpResponse", ".asString();");
-    map.put("java.lang.String", ".asString().body();");
-    map.put("java.net.http.HttpResponse", ".asInputStream();");
-    map.put("java.io.InputStream", ".asInputStream().body();");
-    map.put("java.net.http.HttpResponse>", ".asLines();");
-    map.put("java.util.Stream", ".asLines().body();");
     map.put("java.net.http.HttpResponse", ".asByteArray();");
-    map.put("byte[]", ".asByteArray().body();");
-    map.put("java.util.concurrent.CompletableFuture", ".async().asVoid();");
+    map.put("java.net.http.HttpResponse", ".asInputStream();");
+    map.put("java.net.http.HttpResponse>", ".asLines();");
+
     map.put("java.util.concurrent.CompletableFuture>", ".async().asVoid();");
     map.put("java.util.concurrent.CompletableFuture>", ".async().asString();");
+    map.put("java.util.concurrent.CompletableFuture>", ".async().asByteArray();");
+    map.put("java.util.concurrent.CompletableFuture>", ".async().asInputStream();");
+    map.put("java.util.concurrent.CompletableFuture>>", ".async().asLines();");
+
     map.put("io.avaje.http.client.HttpCall>", ".call().asVoid();");
     map.put("io.avaje.http.client.HttpCall>", ".call().asString();");
+    map.put("io.avaje.http.client.HttpCall>", ".call().asByteArray();");
+    map.put("io.avaje.http.client.HttpCall>", ".call().asInputStream();");
+    map.put("io.avaje.http.client.HttpCall>>", ".call().asLines();");
+
+    // Not supported response types - need HttpResponse for these ones
+    map.put("byte[]", ".notSupported(); // Use HttpResponse instead?");
+    map.put("java.io.InputStream", ".notSupported(); // Use HttpResponse instead?");
+    map.put("java.util.stream.Stream", ".notSupported(); // Use HttpResponse> instead?");
+    map.put("java.util.concurrent.CompletableFuture", ".notSupported(); // Use CompletableFuture instead");
+    map.put("java.util.concurrent.CompletableFuture", ".notSupported(); // Use CompletableFuture instead");
+    map.put("java.util.concurrent.CompletableFuture", ".notSupported(); // Use CompletableFuture instead");
+    map.put("java.util.concurrent.CompletableFuture", ".notSupported(); // Use CompletableFuture instead");
+    map.put("java.util.concurrent.CompletableFuture>", ".notSupported(); // Use CompletableFuture> instead");
+    map.put("io.avaje.http.client.HttpCall", ".notSupported(); // Use HttpCall instead");
+    map.put("io.avaje.http.client.HttpCall", ".notSupported(); // Use HttpCall instead");
+    map.put("io.avaje.http.client.HttpCall", ".notSupported(); // Use HttpCall instead");
+    map.put("io.avaje.http.client.HttpCall", ".notSupported(); // Use HttpCall instead");
+    map.put("io.avaje.http.client.HttpCall>", ".notSupported(); // Use HttpCall> instead");
   }
 
   String get(String full) {
diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml
index 7d2780979..09d42e655 100644
--- a/tests/test-client/pom.xml
+++ b/tests/test-client/pom.xml
@@ -30,7 +30,7 @@
     
       io.avaje
       avaje-http-client
-      1.8
+      1.9-SNAPSHOT
     
 
     
diff --git a/tests/test-client/src/main/java/org/example/JunkApi.java b/tests/test-client/src/main/java/org/example/JunkApi.java
new file mode 100644
index 000000000..2bb30413c
--- /dev/null
+++ b/tests/test-client/src/main/java/org/example/JunkApi.java
@@ -0,0 +1,93 @@
+package org.example;
+
+import io.avaje.http.api.Client;
+import io.avaje.http.api.Post;
+import io.avaje.http.client.HttpCall;
+
+import java.io.InputStream;
+import java.net.http.HttpResponse;
+import java.util.List;
+import java.util.concurrent.CompletableFuture;
+import java.util.stream.Stream;
+
+@Client
+public interface JunkApi {
+
+  @Post
+  void asVoid();
+
+  @Post
+  HttpResponse asVoid2();
+
+  @Post
+  String asPlainString();
+
+  @Post
+  HttpResponse asString2();
+
+  // @Post byte[] asBytesErr();
+  @Post
+  HttpResponse asBytes2();
+
+  // @Post InputStream asInputStreamErr();
+  @Post
+  HttpResponse asInputStream2();
+
+  // @Post Stream asLinesErr();
+  @Post
+  HttpResponse> asLines2();
+
+  @Post
+  Repo bean();
+
+  @Post
+  List list();
+
+  @Post
+  Stream stream();
+
+  // -------
+
+  // @Post CompletableFuture cfVoidErr();
+  @Post
+  CompletableFuture> cfVoid();
+
+  // @Post  CompletableFuture cfStringErr();
+  @Post
+  CompletableFuture> cfString();
+
+  // @Post CompletableFuture cfBytesErr();
+  @Post
+  CompletableFuture> cfBytes();
+
+  // @Post CompletableFuture cfInputStreamErr2();
+  @Post
+  CompletableFuture> cfInputStream();
+
+  // @Post CompletableFuture> cfLinesErr();
+  @Post
+  CompletableFuture>> cfLines();
+
+  // @Post CompletableFuture cfVoidErr();
+  @Post
+  HttpCall> callVoid();
+
+  // @Post  CompletableFuture cfStringErr();
+  @Post
+  HttpCall> callString();
+
+  // @Post HttpCall callBytesErr();
+  @Post
+  HttpCall> callBytes();
+
+  // @Post HttpCall callInputStreamErr();
+  @Post
+  HttpCall> callInputStream();
+
+  // @Post HttpCall> callLinesErr();
+  @Post
+  HttpCall>> callLines();
+
+//  @Get
+//   HttpResponse withH(HttpResponse.BodyHandler handler);
+}

From 675fc91ffb3215960bdb6f69fa903c50b44f77a6 Mon Sep 17 00:00:00 2001
From: rbygrave 
Date: Mon, 5 Jul 2021 20:39:28 +1200
Subject: [PATCH 0164/1323] #63 - Add support for HttpResponse.BodyHandler with
 and without generic parameters

---
 .../generator/client/ClientMethodWriter.java  |  5 +--
 .../io/avaje/http/generator/core/UType.java   | 18 +++++++++-
 .../avaje/http/generator/core/UtilTest.java   | 36 +++++++++++++++++++
 .../src/main/java/org/example/JunkApi.java    | 22 ++++++++++--
 4 files changed, 76 insertions(+), 5 deletions(-)

diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java
index 083bb605a..9a6ec806e 100644
--- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java
+++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java
@@ -21,6 +21,7 @@ class ClientMethodWriter {
   private final ProcessingContext ctx;
   private final UType returnType;
   private MethodParam bodyHandlerParam;
+  private String methodGenericParams = "";
 
   ClientMethodWriter(MethodReader method, Append writer, ProcessingContext ctx) {
     this.method = method;
@@ -43,7 +44,7 @@ private void methodStart(Append writer) {
     }
     writer.append("  // %s %s", webMethod, method.getWebMethodPath()).eol();
     writer.append("  @Override").eol();
-    writer.append("  public %s %s(", returnType.shortType(), method.simpleName());
+    writer.append("  public %s%s %s(", methodGenericParams, returnType.shortType(), method.simpleName());
     int count = 0;
     for (MethodParam param : method.getParams()) {
       if (count++ > 0) {
@@ -61,7 +62,7 @@ private void methodStart(Append writer) {
   private void checkBodyHandler(MethodParam param) {
     if (param.getRawType().startsWith(BODY_HANDLER)) {
       bodyHandlerParam = param;
-      param.getUType().param0();
+      methodGenericParams = param.getUType().genericParams();
     }
   }
 
diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java
index 9f7c9fdf7..788f3669f 100644
--- a/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java
+++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java
@@ -40,6 +40,10 @@ default String param1() {
    */
   String full();
 
+  default String genericParams() {
+    return "";
+  }
+
   class VoidType implements UType {
 
     @Override
@@ -129,13 +133,25 @@ public String full() {
     public Set importTypes() {
       Set set = new LinkedHashSet<>();
       for (String type : allTypes) {
-        if (!type.startsWith("java.lang.")) {
+        if (!type.startsWith("java.lang.") && type.indexOf('.') > -1) {
           set.add(type);
         }
       }
       return set;
     }
 
+    @Override
+    public String genericParams() {
+      final StringJoiner joiner = new StringJoiner(",");
+      for (String type : allTypes) {
+        if (type.indexOf('.') == -1) {
+          joiner.add(type);
+        }
+      }
+      final String commaDelim = joiner.toString();
+      return commaDelim.isEmpty() ? "" : "<" + commaDelim + "> ";
+    }
+
     @Override
     public String shortType() {
       return shortRawType;
diff --git a/http-generator-core/src/test/java/io/avaje/http/generator/core/UtilTest.java b/http-generator-core/src/test/java/io/avaje/http/generator/core/UtilTest.java
index dc99e2a66..c04da033d 100644
--- a/http-generator-core/src/test/java/io/avaje/http/generator/core/UtilTest.java
+++ b/http-generator-core/src/test/java/io/avaje/http/generator/core/UtilTest.java
@@ -129,4 +129,40 @@ void parse_CompletableFutureStreamBean() {
     assertThat(type.importTypes()).containsExactly("java.util.concurrent.CompletableFuture", "java.util.Stream", "org.example.Repo");
     assertThat(type.shortType()).isEqualTo("CompletableFuture>");
   }
+
+  @Test
+  void parse_BodyHandler_E() {
+    UType type = Util.parse("java.net.http.HttpResponse.BodyHandler");
+
+    assertThat(type.importTypes()).containsExactly("java.net.http.HttpResponse.BodyHandler");
+    assertThat(type.shortType()).isEqualTo("BodyHandler");
+    assertThat(type.genericParams()).isEqualTo(" ");
+  }
+
+  @Test
+  void parse_BodyHandler_Path() {
+    UType type = Util.parse("java.net.http.HttpResponse.BodyHandler");
+
+    assertThat(type.importTypes()).containsExactly("java.net.http.HttpResponse.BodyHandler", "java.util.Path");
+    assertThat(type.shortType()).isEqualTo("BodyHandler");
+    assertThat(type.genericParams()).isEqualTo("");
+  }
+
+  @Test
+  void parse_BodyHandler_Multi() {
+    UType type = Util.parse("java.net.http.HttpResponse.BodyHandler>");
+
+    assertThat(type.importTypes()).containsExactly("java.net.http.HttpResponse.BodyHandler", "some.Foo");
+    assertThat(type.shortType()).isEqualTo("BodyHandler>");
+    assertThat(type.genericParams()).isEqualTo(" ");
+  }
+
+  @Test
+  void parse_BodyHandler_Multi2() {
+    UType type = Util.parse("java.net.http.HttpResponse.BodyHandler>>");
+
+    assertThat(type.importTypes()).containsExactly("java.net.http.HttpResponse.BodyHandler", "some.Foo", "some.Bar");
+    assertThat(type.shortType()).isEqualTo("BodyHandler>>");
+    assertThat(type.genericParams()).isEqualTo(" ");
+  }
 }
diff --git a/tests/test-client/src/main/java/org/example/JunkApi.java b/tests/test-client/src/main/java/org/example/JunkApi.java
index 2bb30413c..4af608629 100644
--- a/tests/test-client/src/main/java/org/example/JunkApi.java
+++ b/tests/test-client/src/main/java/org/example/JunkApi.java
@@ -1,11 +1,13 @@
 package org.example;
 
 import io.avaje.http.api.Client;
+import io.avaje.http.api.Get;
 import io.avaje.http.api.Post;
 import io.avaje.http.client.HttpCall;
 
 import java.io.InputStream;
 import java.net.http.HttpResponse;
+import java.nio.file.Path;
 import java.util.List;
 import java.util.concurrent.CompletableFuture;
 import java.util.stream.Stream;
@@ -88,6 +90,22 @@ public interface JunkApi {
   @Post
   HttpCall>> callLines();
 
-//  @Get
-//   HttpResponse withH(HttpResponse.BodyHandler handler);
+  @Get
+   HttpResponse withHandGeneric(HttpResponse.BodyHandler handler);
+
+  @Get
+  HttpResponse withHandPath(HttpResponse.BodyHandler handler);
+
+  @Get
+   CompletableFuture> cfWithHandGeneric(HttpResponse.BodyHandler handler);
+
+  @Get
+  CompletableFuture> cfWithHandPath(HttpResponse.BodyHandler handler);
+
+  @Get
+   HttpCall> callWithHandGeneric(HttpResponse.BodyHandler handler);
+
+  @Get
+  HttpCall> callWithHandPath(HttpResponse.BodyHandler handler);
+
 }

From d5e68ecb52ad62f5819347fbedfea17c1f896c5f Mon Sep 17 00:00:00 2001
From: rbygrave 
Date: Mon, 5 Jul 2021 21:06:49 +1200
Subject: [PATCH 0165/1323] #63 - Add support for HttpResponse.BodyHandler with
 and without generic parameters

---
 .../generator/client/ClientMethodWriter.java  |  1 +
 .../http/generator/core/ElementReader.java    |  6 ++++++
 .../http/generator/core/MethodParam.java      |  4 ++++
 .../avaje/http/generator/core/ParamType.java  |  3 ++-
 .../src/main/java/org/example/JunkApi.java    | 19 +++++++++++++++++--
 5 files changed, 30 insertions(+), 3 deletions(-)

diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java
index 9a6ec806e..214466841 100644
--- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java
+++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java
@@ -61,6 +61,7 @@ private void methodStart(Append writer) {
    */
   private void checkBodyHandler(MethodParam param) {
     if (param.getRawType().startsWith(BODY_HANDLER)) {
+      param.setResponseHandler();
       bodyHandlerParam = param;
       methodGenericParams = param.getUType().genericParams();
     }
diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java
index 94813c6fa..adcb7c8dd 100644
--- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java
+++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java
@@ -8,6 +8,8 @@
 import javax.lang.model.element.TypeElement;
 import javax.validation.Valid;
 
+import static io.avaje.http.generator.core.ParamType.RESPONSE_HANDLER;
+
 public class ElementReader {
 
   private final ProcessingContext ctx;
@@ -310,4 +312,8 @@ public UType getType() {
   public Element getElement() {
     return element;
   }
+
+  public void setResponseHandler() {
+    paramType = RESPONSE_HANDLER;
+  }
 }
diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodParam.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodParam.java
index 6ed5ad289..dc39d0d7c 100644
--- a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodParam.java
+++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodParam.java
@@ -63,4 +63,8 @@ public ParamType getParamType() {
   public UType getUType() {
     return elementParam.getType();
   }
+
+  public void setResponseHandler() {
+    elementParam.setResponseHandler();
+  }
 }
diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ParamType.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ParamType.java
index 084e26457..724c5afe9 100644
--- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ParamType.java
+++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ParamType.java
@@ -10,7 +10,8 @@ public enum ParamType {
   QUERYPARAM("queryParam", "query"),
   FORMPARAM("formParam", "form"),
   COOKIE("cookie", "cookie"),
-  HEADER("header", "header");
+  HEADER("header", "header"),
+  RESPONSE_HANDLER("notUsed", "notUsed");
 
   private final String code;
   private final String type;
diff --git a/tests/test-client/src/main/java/org/example/JunkApi.java b/tests/test-client/src/main/java/org/example/JunkApi.java
index 4af608629..bcc41e58b 100644
--- a/tests/test-client/src/main/java/org/example/JunkApi.java
+++ b/tests/test-client/src/main/java/org/example/JunkApi.java
@@ -6,6 +6,7 @@
 import io.avaje.http.client.HttpCall;
 
 import java.io.InputStream;
+import java.net.http.HttpRequest;
 import java.net.http.HttpResponse;
 import java.nio.file.Path;
 import java.util.List;
@@ -41,13 +42,24 @@ public interface JunkApi {
 
   @Post
   Repo bean();
-
   @Post
   List list();
-
   @Post
   Stream stream();
 
+  @Post
+  CompletableFuture cfBean();
+  @Post
+  CompletableFuture> cfList();
+  @Post
+  CompletableFuture> cfStream();
+
+  @Post
+  HttpCall callBean();
+  @Post
+  HttpCall> callList();
+  @Post
+  HttpCall> callStream();
   // -------
 
   // @Post CompletableFuture cfVoidErr();
@@ -108,4 +120,7 @@ public interface JunkApi {
   @Get
   HttpCall> callWithHandPath(HttpResponse.BodyHandler handler);
 
+  @Post("/{id}/foo/{name}")
+  HttpResponse reqBodyResHand2(HttpResponse.BodyHandler handler, HttpRequest.BodyPublisher body, String id, String name, String other);
+
 }

From 1602a02400cf7ef2ecfced2a7b393afd45e4941a Mon Sep 17 00:00:00 2001
From: rbygrave 
Date: Tue, 6 Jul 2021 12:06:00 +1200
Subject: [PATCH 0166/1323] #24 - ENH: Add asPlainString() with 2XX range check
 (for Client API returning String without HttpResponse)

---
 .../avaje/http/client/DHttpClientContext.java | 19 ++++++-
 .../avaje/http/client/DHttpClientRequest.java |  8 +++
 .../avaje/http/client/HttpClientResponse.java |  8 +++
 .../io/avaje/http/client/HttpException.java   | 15 +++--
 .../http/client/HelloControllerTest.java      | 57 +++++++++++++++++++
 5 files changed, 99 insertions(+), 8 deletions(-)

diff --git a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContext.java b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContext.java
index 496a482c7..a830e872d 100644
--- a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContext.java
+++ b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContext.java
@@ -6,6 +6,7 @@
 import java.net.http.HttpHeaders;
 import java.net.http.HttpRequest;
 import java.net.http.HttpResponse;
+import java.nio.charset.StandardCharsets;
 import java.time.Duration;
 import java.util.List;
 import java.util.Map;
@@ -106,6 +107,20 @@ void checkMaybeThrow(HttpResponse response) {
     }
   }
 
+  @SuppressWarnings("unchecked")
+  public BodyContent readErrorContent(boolean responseAsBytes, HttpResponse httpResponse) {
+    if (responseAsBytes) {
+      return readContent((HttpResponse) httpResponse);
+    }
+    final String contentType = getContentType(httpResponse);
+    final Object body = httpResponse.body();
+    if (body instanceof String) {
+      return new BodyContent(contentType, ((String) body).getBytes(StandardCharsets.UTF_8));
+    }
+    String type = (body == null) ? "null" : body.getClass().toString();
+    throw new IllegalStateException("Unable to translate response body to bytes? Maybe use HttpResponse directly instead?  Response body type: " + type);
+  }
+
   @Override
   public BodyContent readContent(HttpResponse httpResponse) {
     byte[] bodyBytes = decodeContent(httpResponse);
@@ -113,11 +128,11 @@ public BodyContent readContent(HttpResponse httpResponse) {
     return new BodyContent(contentType, bodyBytes);
   }
 
-  String getContentType(HttpResponse httpResponse) {
+  String getContentType(HttpResponse httpResponse) {
     return firstHeader(httpResponse.headers(), "Content-Type", "content-type");
   }
 
-  String getContentEncoding(HttpResponse httpResponse) {
+  String getContentEncoding(HttpResponse httpResponse) {
     return firstHeader(httpResponse.headers(), "Content-Encoding", "content-encoding");
   }
 
diff --git a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java
index 559a9a9ec..b20e06956 100644
--- a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java
+++ b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java
@@ -485,6 +485,14 @@ public HttpResponse asString() {
     return withHandler(HttpResponse.BodyHandlers.ofString());
   }
 
+  @Override
+  public HttpResponse asPlainString() {
+    loggableResponseBody = true;
+    final HttpResponse hres = withHandler(HttpResponse.BodyHandlers.ofString());
+    context.checkResponse(hres);
+    return hres;
+  }
+
   @Override
   public HttpResponse asDiscarding() {
     return withHandler(discarding());
diff --git a/http-client/client/src/main/java/io/avaje/http/client/HttpClientResponse.java b/http-client/client/src/main/java/io/avaje/http/client/HttpClientResponse.java
index fa3ccbb2b..30b9db9ea 100644
--- a/http-client/client/src/main/java/io/avaje/http/client/HttpClientResponse.java
+++ b/http-client/client/src/main/java/io/avaje/http/client/HttpClientResponse.java
@@ -113,6 +113,14 @@ public interface HttpClientResponse {
    */
   HttpResponse asString();
 
+  /**
+   * Return the content as string with check for 200 range status code.
+   * 

+ * If the status code is in the error range then a {@link HttpException} + * is thrown. + */ + HttpResponse asPlainString(); + /** * Return the content as InputStream. */ diff --git a/http-client/client/src/main/java/io/avaje/http/client/HttpException.java b/http-client/client/src/main/java/io/avaje/http/client/HttpException.java index d2adfade3..ff81d25c7 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/HttpException.java +++ b/http-client/client/src/main/java/io/avaje/http/client/HttpException.java @@ -43,6 +43,7 @@ public class HttpException extends RuntimeException { private final int statusCode; + private final boolean responseAsBytes; private DHttpClientContext context; private HttpResponse httpResponse; @@ -52,6 +53,7 @@ public class HttpException extends RuntimeException { public HttpException(int statusCode, String message) { super(message); this.statusCode = statusCode; + this.responseAsBytes = false; } /** @@ -60,6 +62,7 @@ public HttpException(int statusCode, String message) { public HttpException(int statusCode, String message, Throwable cause) { super(message, cause); this.statusCode = statusCode; + this.responseAsBytes = false; } /** @@ -68,6 +71,7 @@ public HttpException(int statusCode, String message, Throwable cause) { public HttpException(int statusCode, Throwable cause) { super(cause); this.statusCode = statusCode; + this.responseAsBytes = false; } HttpException(HttpResponse httpResponse, DHttpClientContext context) { @@ -75,6 +79,7 @@ public HttpException(int statusCode, Throwable cause) { this.httpResponse = httpResponse; this.statusCode = httpResponse.statusCode(); this.context = context; + this.responseAsBytes = false; } HttpException(DHttpClientContext context, HttpResponse httpResponse) { @@ -82,6 +87,7 @@ public HttpException(int statusCode, Throwable cause) { this.httpResponse = httpResponse; this.statusCode = httpResponse.statusCode(); this.context = context; + this.responseAsBytes = true; } /** @@ -90,27 +96,24 @@ public HttpException(int statusCode, Throwable cause) { * @param cls The type of bean to convert the response to * @return The response as a bean */ - @SuppressWarnings("unchecked") public T bean(Class cls) { - final BodyContent body = context.readContent((HttpResponse) httpResponse); + final BodyContent body = context.readErrorContent(responseAsBytes, httpResponse); return context.readBean(cls, body); } /** * Return the response body content as a UTF8 string. */ - @SuppressWarnings("unchecked") public String bodyAsString() { - final BodyContent body = context.readContent((HttpResponse) httpResponse); + final BodyContent body = context.readErrorContent(responseAsBytes, httpResponse); return new String(body.content(), StandardCharsets.UTF_8); } /** * Return the response body content as raw bytes. */ - @SuppressWarnings("unchecked") public byte[] bodyAsBytes() { - final BodyContent body = context.readContent((HttpResponse) httpResponse); + final BodyContent body = context.readErrorContent(responseAsBytes, httpResponse); return body.content(); } diff --git a/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java b/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java index d06f9aa46..e21262430 100644 --- a/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java +++ b/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java @@ -375,6 +375,63 @@ void get_notFound() { assertThat(hres.body()).contains("Not found"); } + @Test + void asString_200() { + final HttpResponse hres = clientContext.request() + .path("hello").path("message") + .GET().asString(); + + assertThat(hres.body()).contains("hello world"); + assertThat(hres.statusCode()).isEqualTo(200); + } + + @Test + void asPlainString_200() { + final HttpResponse hres = clientContext.request() + .path("hello").path("message") + .GET().asPlainString(); + + assertThat(hres.body()).contains("hello world"); + assertThat(hres.statusCode()).isEqualTo(200); + } + + @Test + void asPlainString_throwingHttpException() { + final HttpException httpException = assertThrows(HttpException.class, () -> + clientContext.request() + .path("hello/saveform3") + .formParam("name", "Bax") + .formParam("email", "notValidEmail") + .POST() + .asPlainString()); + + assertThat(httpException.statusCode()).isEqualTo(422); + + // convert json error response body to a bean + final ErrorResponse errorResponse = httpException.bean(ErrorResponse.class); + final Map errorMap = errorResponse.getErrors(); + assertThat(errorMap.get("email")).isEqualTo("must be a well-formed email address"); + } + + @Test + void asString_readInvalidResponse() { + final HttpResponse hres = clientContext.request() + .path("hello/saveform3") + .formParam("name", "Bax") + .formParam("email", "notValidEmail") + .POST() + .asString(); + + assertThat(hres.statusCode()).isEqualTo(422); + + // convert json error response body to a bean + final ErrorResponse errorResponse = clientContext.converters() + .beanReader(ErrorResponse.class).readBody(hres.body()); + + final Map errorMap = errorResponse.getErrors(); + assertThat(errorMap.get("email")).isEqualTo("must be a well-formed email address"); + } + @Test void headers() { final HttpClientRequest request = clientContext.request(); From f03ee6b71a1e2c31743ebe39818309bd70c74162 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Tue, 6 Jul 2021 12:35:39 +1200 Subject: [PATCH 0167/1323] #25 - ENH: Add option to HttpContextBuilder to set proxy, sslContext, sslParameters, authenticator and priority. --- .../client/DHttpClientContextBuilder.java | 57 ++++++++++++++++++- .../avaje/http/client/HttpClientContext.java | 39 +++++++++++++ 2 files changed, 94 insertions(+), 2 deletions(-) diff --git a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContextBuilder.java b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContextBuilder.java index e1425c109..afd3a17a5 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContextBuilder.java +++ b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContextBuilder.java @@ -1,7 +1,11 @@ package io.avaje.http.client; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLParameters; +import java.net.Authenticator; import java.net.CookieHandler; import java.net.CookieManager; +import java.net.ProxySelector; import java.net.http.HttpClient; import java.time.Duration; import java.util.ArrayList; @@ -23,6 +27,11 @@ class DHttpClientContextBuilder implements HttpClientContext.Builder { private HttpClient.Redirect redirect = HttpClient.Redirect.NORMAL; private HttpClient.Version version; private Executor executor; + private ProxySelector proxy; + private SSLContext sslContext; + private SSLParameters sslParameters; + private Authenticator authenticator; + private int priority; private final List interceptors = new ArrayList<>(); private final List listeners = new ArrayList<>(); @@ -102,6 +111,36 @@ public HttpClientContext.Builder withExecutor(Executor executor) { return this; } + @Override + public HttpClientContext.Builder withProxy(ProxySelector proxySelector) { + this.proxy = proxySelector; + return this; + } + + @Override + public HttpClientContext.Builder withSSLContext(SSLContext sslContext) { + this.sslContext = sslContext; + return this; + } + + @Override + public HttpClientContext.Builder withSSLParameters(SSLParameters sslParameters) { + this.sslParameters = sslParameters; + return this; + } + + @Override + public HttpClientContext.Builder withAuthenticator(Authenticator authenticator) { + this.authenticator = authenticator; + return this; + } + + @Override + public HttpClientContext.Builder withPriority(int priority) { + this.priority = priority; + return this; + } + @Override public HttpClientContext build() { requireNonNull(baseUrl, "baseUrl is not specified"); @@ -133,8 +172,7 @@ private RequestIntercept buildIntercept() { } private HttpClient defaultClient() { - final HttpClient.Builder builder = - HttpClient.newBuilder() + final HttpClient.Builder builder = HttpClient.newBuilder() .followRedirects(redirect) .connectTimeout(Duration.ofSeconds(20)); if (cookieHandler != null) { @@ -146,6 +184,21 @@ private HttpClient defaultClient() { if (executor != null) { builder.executor(executor); } + if (proxy != null) { + builder.proxy(proxy); + } + if (sslContext != null) { + builder.sslContext(sslContext); + } + if (sslParameters != null) { + builder.sslParameters(sslParameters); + } + if (authenticator != null) { + builder.authenticator(authenticator); + } + if (priority > 0) { + builder.priority(priority); + } return builder.build(); } diff --git a/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java b/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java index 0abd6e19b..914744d6f 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java +++ b/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java @@ -1,6 +1,10 @@ package io.avaje.http.client; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLParameters; +import java.net.Authenticator; import java.net.CookieHandler; +import java.net.ProxySelector; import java.net.http.HttpClient; import java.net.http.HttpResponse; import java.time.Duration; @@ -223,6 +227,41 @@ interface Builder { */ Builder withExecutor(Executor executor); + /** + * Set the proxy to the underlying {@link HttpClient}. + * + * @see HttpClient.Builder#proxy(ProxySelector) + */ + Builder withProxy(ProxySelector proxySelector); + + /** + * Set the sslContext to the underlying {@link HttpClient}. + * + * @see HttpClient.Builder#sslContext(SSLContext) + */ + Builder withSSLContext(SSLContext sslContext); + + /** + * Set the sslParameters to the underlying {@link HttpClient}. + * + * @see HttpClient.Builder#sslParameters(SSLParameters) + */ + Builder withSSLParameters(SSLParameters sslParameters); + + /** + * Set a HttpClient authenticator to the underlying {@link HttpClient}. + * + * @see HttpClient.Builder#authenticator(Authenticator) + */ + Builder withAuthenticator(Authenticator authenticator); + + /** + * Set the priority for HTTP/2 requests to the underlying {@link HttpClient}. + * + * @see HttpClient.Builder#priority(int) + */ + Builder withPriority(int priority); + /** * Build and return the context. * From 8a9944f24f6cf4144e6806be7ac7f59aa79407cc Mon Sep 17 00:00:00 2001 From: rbygrave Date: Tue, 6 Jul 2021 15:17:59 +1200 Subject: [PATCH 0168/1323] #26 - Expose HttpClientRequest.responseTimeMicros() ... for ease of metrics interceptors --- .../avaje/http/client/BasicAuthIntercept.java | 4 ---- .../avaje/http/client/DHttpClientRequest.java | 19 ++++++++++------- .../avaje/http/client/HttpClientRequest.java | 7 +++++++ .../avaje/http/client/RequestIntercept.java | 8 +++++-- .../io/avaje/http/client/RequestListener.java | 2 +- .../io/avaje/http/client/RequestLogger.java | 2 +- .../http/client/RequestListenerTest.java | 3 +-- .../java/io/avaje/http/client/RetryTest.java | 21 +++++++++++++++++-- 8 files changed, 47 insertions(+), 19 deletions(-) diff --git a/http-client/client/src/main/java/io/avaje/http/client/BasicAuthIntercept.java b/http-client/client/src/main/java/io/avaje/http/client/BasicAuthIntercept.java index 4b02fdcca..431218431 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/BasicAuthIntercept.java +++ b/http-client/client/src/main/java/io/avaje/http/client/BasicAuthIntercept.java @@ -31,8 +31,4 @@ public void beforeRequest(HttpClientRequest request) { request.header("Authorization", headerValue); } - @Override - public void afterResponse(HttpResponse response, HttpClientRequest request) { - // do nothing - } } diff --git a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java index b20e06956..9c6e2493e 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java +++ b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java @@ -43,7 +43,7 @@ class DHttpClientRequest implements HttpClientRequest, HttpClientResponse { private Map> headers; private boolean bodyFormEncoded; - private long requestTimeNanos; + private long responseTimeNanos; private HttpResponse httpResponse; private BodyContent encodedResponseBody; @@ -421,7 +421,7 @@ protected HttpResponse performSend(HttpResponse.BodyHandler responseHa try { return context.send(httpRequest, responseHandler); } finally { - requestTimeNanos = System.nanoTime() - startNanos; + responseTimeNanos = System.nanoTime() - startNanos; } } @@ -449,7 +449,7 @@ protected List asyncList(Class type, HttpResponse response) { } protected Stream asyncStream(Class type, HttpResponse> response) { - requestTimeNanos = System.nanoTime() - startAsyncNanos; + responseTimeNanos = System.nanoTime() - startAsyncNanos; httpResponse = response; context.afterResponse(this); if (response.statusCode() >= 300) { @@ -460,7 +460,7 @@ protected Stream asyncStream(Class type, HttpResponse> } private void afterAsyncEncoded(HttpResponse response) { - requestTimeNanos = System.nanoTime() - startAsyncNanos; + responseTimeNanos = System.nanoTime() - startAsyncNanos; httpResponse = response; encodedResponseBody = context.readContent(response); context.afterResponse(this); @@ -468,12 +468,17 @@ private void afterAsyncEncoded(HttpResponse response) { } protected HttpResponse afterAsync(HttpResponse response) { - requestTimeNanos = System.nanoTime() - startAsyncNanos; + responseTimeNanos = System.nanoTime() - startAsyncNanos; httpResponse = response; context.afterResponse(this); return response; } + @Override + public long responseTimeMicros() { + return responseTimeNanos / 1000; + } + @Override public HttpResponse asByteArray() { return withHandler(HttpResponse.BodyHandlers.ofByteArray()); @@ -573,8 +578,8 @@ boolean isSkipAuthToken() { private class ListenerEvent implements RequestListener.Event { @Override - public long responseTimeNanos() { - return requestTimeNanos; + public long responseTimeMicros() { + return responseTimeNanos / 1000; } @Override diff --git a/http-client/client/src/main/java/io/avaje/http/client/HttpClientRequest.java b/http-client/client/src/main/java/io/avaje/http/client/HttpClientRequest.java index 153423fb1..7050c4b97 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/HttpClientRequest.java +++ b/http-client/client/src/main/java/io/avaje/http/client/HttpClientRequest.java @@ -2,6 +2,7 @@ import java.io.InputStream; import java.net.http.HttpRequest; +import java.net.http.HttpResponse; import java.nio.file.Path; import java.time.Duration; import java.util.List; @@ -345,4 +346,10 @@ default HttpClientResponse delete() { */ HttpClientResponse HEAD(); + /** + * After the response is returned this method returns the response time in microseconds. + *

+ * This is useful for use in {@link RequestIntercept#afterResponse(HttpResponse, HttpClientRequest)} + */ + long responseTimeMicros(); } diff --git a/http-client/client/src/main/java/io/avaje/http/client/RequestIntercept.java b/http-client/client/src/main/java/io/avaje/http/client/RequestIntercept.java index ed487730a..3b9ab906c 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/RequestIntercept.java +++ b/http-client/client/src/main/java/io/avaje/http/client/RequestIntercept.java @@ -12,11 +12,15 @@ public interface RequestIntercept { *

* Typically we can add headers or modify the request prior to it being sent. */ - void beforeRequest(HttpClientRequest request); + default void beforeRequest(HttpClientRequest request) { + // do nothing by default + } /** * After the response has been received. */ - void afterResponse(HttpResponse response, HttpClientRequest request); + default void afterResponse(HttpResponse response, HttpClientRequest request) { + // do nothing by default + } } diff --git a/http-client/client/src/main/java/io/avaje/http/client/RequestListener.java b/http-client/client/src/main/java/io/avaje/http/client/RequestListener.java index 9ee496b02..8da114dbe 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/RequestListener.java +++ b/http-client/client/src/main/java/io/avaje/http/client/RequestListener.java @@ -25,7 +25,7 @@ interface Event { /** * Return the time from request to response in nanos. */ - long responseTimeNanos(); + long responseTimeMicros(); /** * Return the URI for the request. diff --git a/http-client/client/src/main/java/io/avaje/http/client/RequestLogger.java b/http-client/client/src/main/java/io/avaje/http/client/RequestLogger.java index e4d92991e..31bc8deef 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/RequestLogger.java +++ b/http-client/client/src/main/java/io/avaje/http/client/RequestLogger.java @@ -42,7 +42,7 @@ public void response(Event event) { if (log.isDebugEnabled()) { final HttpResponse response = event.response(); final HttpRequest request = response.request(); - long micros = event.responseTimeNanos() / 1000; + long micros = event.responseTimeMicros(); StringBuilder sb = new StringBuilder(); sb.append("statusCode:").append(response.statusCode()) diff --git a/http-client/client/src/test/java/io/avaje/http/client/RequestListenerTest.java b/http-client/client/src/test/java/io/avaje/http/client/RequestListenerTest.java index 400f53cbb..a6806c032 100644 --- a/http-client/client/src/test/java/io/avaje/http/client/RequestListenerTest.java +++ b/http-client/client/src/test/java/io/avaje/http/client/RequestListenerTest.java @@ -1,7 +1,6 @@ package io.avaje.http.client; import com.fasterxml.jackson.databind.ObjectMapper; -import org.example.webserver.HelloDto; import org.junit.jupiter.api.Test; import java.net.http.HttpResponse; @@ -28,7 +27,7 @@ public void response(Event event) { assertThat(event.uri().toString()).isEqualTo("http://localhost:8887/hello/message"); assertThat(event.requestBody()).isNull(); } - assertThat(event.responseTimeNanos()).isGreaterThan(1L); + assertThat(event.responseTimeMicros()).isGreaterThan(1L); assertThat(event.response().statusCode()).isEqualTo(200); assertThat(event.request()).isEqualTo(event.response().request()); } diff --git a/http-client/client/src/test/java/io/avaje/http/client/RetryTest.java b/http-client/client/src/test/java/io/avaje/http/client/RetryTest.java index f828182b9..e318206e3 100644 --- a/http-client/client/src/test/java/io/avaje/http/client/RetryTest.java +++ b/http-client/client/src/test/java/io/avaje/http/client/RetryTest.java @@ -9,26 +9,43 @@ public class RetryTest extends BaseWebTest { + final MyIntercept myIntercept = new MyIntercept(); final HttpClientContext clientContext = initClientWithRetry(); - static HttpClientContext initClientWithRetry() { + HttpClientContext initClientWithRetry() { return HttpClientContext.newBuilder() .withBaseUrl("http://localhost:8887") .withBodyAdapter(new JacksonBodyAdapter(new ObjectMapper())) .withRequestListener(new RequestLogger()) .withRetryHandler(new SimpleRetryHandler(4, 1)) + .withRequestIntercept(myIntercept) .build(); } @Test void retryTest() { - HttpResponse res = clientContext.request() .path("hello/retry") .GET() .asString(); assertThat(res.body()).isEqualTo("All good at 3rd attempt"); + + assertThat(myIntercept.responseTimeMicros).isGreaterThan(1); + assertThat(myIntercept.counter).isEqualTo(1); } + static class MyIntercept implements RequestIntercept { + int counter; + long responseTimeMicros; + + /** + * Not called for the retry attempts. Only called on the final success or error response. + */ + @Override + public void afterResponse(HttpResponse response, HttpClientRequest request) { + counter++; + responseTimeMicros = request.responseTimeMicros(); + } + } } From b7ca81c0cf23a0c61db690ddaff585f84ad72ada Mon Sep 17 00:00:00 2001 From: rbygrave Date: Tue, 6 Jul 2021 15:54:37 +1200 Subject: [PATCH 0169/1323] #27 - ENH: Add HttpClientRequest label ... typically for grouping / using with metrics collection and reporting --- .../io/avaje/http/client/DHttpClientRequest.java | 12 ++++++++++++ .../io/avaje/http/client/HttpClientRequest.java | 16 ++++++++++++++++ .../java/io/avaje/http/client/RetryTest.java | 4 ++++ 3 files changed, 32 insertions(+) diff --git a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java index 9c6e2493e..c67e73cd8 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java +++ b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java @@ -51,6 +51,7 @@ class DHttpClientRequest implements HttpClientRequest, HttpClientResponse { private boolean skipAuthToken; private boolean suppressLogging; private long startAsyncNanos; + private String label; DHttpClientRequest(DHttpClientContext context, Duration requestTimeout) { this.context = context; @@ -71,6 +72,17 @@ public HttpClientRequest suppressLogging() { return this; } + @Override + public HttpClientRequest label(String label) { + this.label = label; + return this; + } + + @Override + public String label() { + return label; + } + @Override public HttpClientRequest requestTimeout(Duration requestTimeout) { this.requestTimeout = requestTimeout; diff --git a/http-client/client/src/main/java/io/avaje/http/client/HttpClientRequest.java b/http-client/client/src/main/java/io/avaje/http/client/HttpClientRequest.java index 7050c4b97..fd6aae491 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/HttpClientRequest.java +++ b/http-client/client/src/main/java/io/avaje/http/client/HttpClientRequest.java @@ -45,6 +45,22 @@ public interface HttpClientRequest { */ HttpClientRequest suppressLogging(); + /** + * Set a label for the request. The label is intended to be used to group and + * identify metrics for the request. + * + * @param label The label that can be used to identify metrics for the request + */ + HttpClientRequest label(String label); + + /** + * Return the label that has been set on this request. + *

+ * Typically the label would be read in {@link RequestIntercept#afterResponse(HttpResponse, HttpClientRequest)} + * to assign request execution metrics. + */ + String label(); + /** * Set the request timeout to use for this request. When not set the default * request timeout will be used. diff --git a/http-client/client/src/test/java/io/avaje/http/client/RetryTest.java b/http-client/client/src/test/java/io/avaje/http/client/RetryTest.java index e318206e3..b58c72541 100644 --- a/http-client/client/src/test/java/io/avaje/http/client/RetryTest.java +++ b/http-client/client/src/test/java/io/avaje/http/client/RetryTest.java @@ -25,6 +25,7 @@ HttpClientContext initClientWithRetry() { @Test void retryTest() { HttpResponse res = clientContext.request() + .label("http_client_hello_retry") .path("hello/retry") .GET() .asString(); @@ -33,11 +34,13 @@ void retryTest() { assertThat(myIntercept.responseTimeMicros).isGreaterThan(1); assertThat(myIntercept.counter).isEqualTo(1); + assertThat(myIntercept.label).isEqualTo("http_client_hello_retry"); } static class MyIntercept implements RequestIntercept { int counter; long responseTimeMicros; + String label; /** * Not called for the retry attempts. Only called on the final success or error response. @@ -46,6 +49,7 @@ static class MyIntercept implements RequestIntercept { public void afterResponse(HttpResponse response, HttpClientRequest request) { counter++; responseTimeMicros = request.responseTimeMicros(); + label = request.label(); } } } From ec9b6b0a0d0e6c3ccd1dfb6acab6268dc9015e29 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Tue, 6 Jul 2021 16:11:51 +1200 Subject: [PATCH 0170/1323] #27 - ENH: Add HttpClientRequest setAttribute() getAttribute() to pass custom attributes between RequestIntercept methods --- .../avaje/http/client/DHttpClientRequest.java | 16 +++++++++++++++ .../avaje/http/client/HttpClientRequest.java | 20 +++++++++++++++++++ .../java/io/avaje/http/client/RetryTest.java | 15 ++++++++++++++ 3 files changed, 51 insertions(+) diff --git a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java index c67e73cd8..9cb67a325 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java +++ b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java @@ -52,6 +52,7 @@ class DHttpClientRequest implements HttpClientRequest, HttpClientResponse { private boolean suppressLogging; private long startAsyncNanos; private String label; + private Map customAttributes; DHttpClientRequest(DHttpClientContext context, Duration requestTimeout) { this.context = context; @@ -83,6 +84,21 @@ public String label() { return label; } + @Override + public HttpClientRequest setAttribute(String key, Object value) { + if (customAttributes == null) { + customAttributes = new HashMap<>(); + } + customAttributes.put(key, value); + return this; + } + + @SuppressWarnings("unchecked") + @Override + public E getAttribute(String key) { + return customAttributes == null ? null : (E) customAttributes.get(key); + } + @Override public HttpClientRequest requestTimeout(Duration requestTimeout) { this.requestTimeout = requestTimeout; diff --git a/http-client/client/src/main/java/io/avaje/http/client/HttpClientRequest.java b/http-client/client/src/main/java/io/avaje/http/client/HttpClientRequest.java index fd6aae491..2b8935537 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/HttpClientRequest.java +++ b/http-client/client/src/main/java/io/avaje/http/client/HttpClientRequest.java @@ -61,6 +61,26 @@ public interface HttpClientRequest { */ String label(); + /** + * Used to pass custom attribute between {@link RequestIntercept} methods. + *

+ * Allows us to pass something between {@code beforeRequest} and {@code afterResponse} + * methods of a {@link RequestIntercept} or between multiple {@link RequestIntercept}. + * + * @param key The unique key used to store the attribute + * @param value The attribute to store + */ + HttpClientRequest setAttribute(String key, Object value); + + /** + * Return a custom attribute typically set by a {@link RequestIntercept#beforeRequest(HttpClientRequest)}. + * + * @param key The key for the custom attribute + * @param The inferred type of the attribute + * @return The custom attribute + */ + E getAttribute(String key); + /** * Set the request timeout to use for this request. When not set the default * request timeout will be used. diff --git a/http-client/client/src/test/java/io/avaje/http/client/RetryTest.java b/http-client/client/src/test/java/io/avaje/http/client/RetryTest.java index b58c72541..794431125 100644 --- a/http-client/client/src/test/java/io/avaje/http/client/RetryTest.java +++ b/http-client/client/src/test/java/io/avaje/http/client/RetryTest.java @@ -33,6 +33,8 @@ void retryTest() { assertThat(res.body()).isEqualTo("All good at 3rd attempt"); assertThat(myIntercept.responseTimeMicros).isGreaterThan(1); + assertThat(myIntercept.customAttributeTimeMillis).isGreaterThan(1); + assertThat(myIntercept.counter).isEqualTo(1); assertThat(myIntercept.label).isEqualTo("http_client_hello_retry"); } @@ -40,13 +42,26 @@ void retryTest() { static class MyIntercept implements RequestIntercept { int counter; long responseTimeMicros; + long customAttributeTimeMillis; String label; + @Override + public void beforeRequest(HttpClientRequest request) { + final String label = request.setAttribute("MY_START_TIME", System.currentTimeMillis()).label(); + assertThat(label).isEqualTo("http_client_hello_retry"); + } + /** * Not called for the retry attempts. Only called on the final success or error response. */ @Override public void afterResponse(HttpResponse response, HttpClientRequest request) { + + final String does_not_exist = request.getAttribute("DOES_NOT_EXIST"); + assertThat(does_not_exist).isNull(); + + long start = request.getAttribute("MY_START_TIME"); + customAttributeTimeMillis = System.currentTimeMillis() - start; counter++; responseTimeMicros = request.responseTimeMicros(); label = request.label(); From 49d1e3f9f7f06fe653c9aa50a0af67fb5caa3aef Mon Sep 17 00:00:00 2001 From: rbygrave Date: Wed, 7 Jul 2021 00:38:46 +1200 Subject: [PATCH 0171/1323] Refactor readResponseContent() for decoding response before afterResponse(this) handling --- .../io/avaje/http/client/DHttpClientRequest.java | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java index 9cb67a325..dd6af4299 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java +++ b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java @@ -393,10 +393,10 @@ public HttpClientResponse TRACE() { } private void readResponseContent() { - final HttpResponse response = asByteArray(); - this.httpResponse = response; - context.checkMaybeThrow(response); + final HttpResponse response = sendWith(HttpResponse.BodyHandlers.ofByteArray()); encodedResponseBody = context.readContent(response); + context.afterResponse(this); + context.checkMaybeThrow(response); } @Override @@ -436,11 +436,19 @@ public Stream stream(Class cls) { @Override public HttpResponse withHandler(HttpResponse.BodyHandler responseHandler) { + final HttpResponse response = sendWith(responseHandler); + context.afterResponse(this); + return response; + } + + /** + * Prepare and send the request but not performing afterResponse() handling. + */ + private HttpResponse sendWith(HttpResponse.BodyHandler responseHandler) { context.beforeRequest(this); addHeaders(); HttpResponse response = performSend(responseHandler); httpResponse = response; - context.afterResponse(this); return response; } From 83dc777663638538794ae1503ccbedcb4c1435b9 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Wed, 7 Jul 2021 14:49:43 +1200 Subject: [PATCH 0172/1323] Bump to 1.8.1-SNAPSHOT to release prior to removal of some deprecated methods --- http-client/client/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/http-client/client/pom.xml b/http-client/client/pom.xml index 8dd48daab..5df9f1894 100644 --- a/http-client/client/pom.xml +++ b/http-client/client/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-client - 1.9-SNAPSHOT + 1.8.1-SNAPSHOT scm:git:git@github.com:avaje/avaje-http-client.git From 680b47ef9960e88a0cca6fb2d33cbd92c0276c4a Mon Sep 17 00:00:00 2001 From: rbygrave Date: Wed, 7 Jul 2021 14:50:44 +1200 Subject: [PATCH 0173/1323] [maven-release-plugin] prepare release avaje-http-client-1.8.1 --- http-client/client/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/http-client/client/pom.xml b/http-client/client/pom.xml index 5df9f1894..0c48975d7 100644 --- a/http-client/client/pom.xml +++ b/http-client/client/pom.xml @@ -9,11 +9,11 @@ io.avaje avaje-http-client - 1.8.1-SNAPSHOT + 1.8.1 scm:git:git@github.com:avaje/avaje-http-client.git - HEAD + avaje-http-client-1.8.1 From b7c36289fb30cf1119c102ff2ace0fbd4567a165 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Wed, 7 Jul 2021 14:50:52 +1200 Subject: [PATCH 0174/1323] [maven-release-plugin] prepare for next development iteration --- http-client/client/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/http-client/client/pom.xml b/http-client/client/pom.xml index 0c48975d7..648f0ba7a 100644 --- a/http-client/client/pom.xml +++ b/http-client/client/pom.xml @@ -9,11 +9,11 @@ io.avaje avaje-http-client - 1.8.1 + 1.8.2-SNAPSHOT scm:git:git@github.com:avaje/avaje-http-client.git - avaje-http-client-1.8.1 + HEAD From a11ad14ad845054e45802ce5b3398a79b5bd93bc Mon Sep 17 00:00:00 2001 From: rbygrave Date: Wed, 7 Jul 2021 15:01:53 +1200 Subject: [PATCH 0175/1323] #28 - Remove deprecated methods for verbs get(), put() etc ... need to use GET() PUT() etc --- http-client/client/pom.xml | 2 +- .../avaje/http/client/HttpClientRequest.java | 40 ------------------- .../avaje/http/client/HttpClientResponse.java | 8 ---- .../io/avaje/http/client/HttpException.java | 16 -------- .../http/client/HelloControllerTest.java | 4 +- http-client/test/pom.xml | 6 +-- .../java/example/github/SimpleHttpClient.java | 2 +- .../test/java/example/github/GithubTest.java | 3 +- 8 files changed, 8 insertions(+), 73 deletions(-) diff --git a/http-client/client/pom.xml b/http-client/client/pom.xml index 648f0ba7a..8dd48daab 100644 --- a/http-client/client/pom.xml +++ b/http-client/client/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-client - 1.8.2-SNAPSHOT + 1.9-SNAPSHOT scm:git:git@github.com:avaje/avaje-http-client.git diff --git a/http-client/client/src/main/java/io/avaje/http/client/HttpClientRequest.java b/http-client/client/src/main/java/io/avaje/http/client/HttpClientRequest.java index 2b8935537..16da844eb 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/HttpClientRequest.java +++ b/http-client/client/src/main/java/io/avaje/http/client/HttpClientRequest.java @@ -307,46 +307,6 @@ public interface HttpClientRequest { */ HttpClientRequest body(HttpRequest.BodyPublisher body); - /** - * Deprecated migrate to GET(). - */ - @Deprecated - default HttpClientResponse get() { - return GET(); - } - - /** - * Deprecated migrate to POST(). - */ - @Deprecated - default HttpClientResponse post() { - return POST(); - } - - /** - * Deprecated migrate to PUT(). - */ - @Deprecated - default HttpClientResponse put() { - return PUT(); - } - - /** - * Deprecated migrate to PATCH(). - */ - @Deprecated - default HttpClientResponse patch() { - return PATCH(); - } - - /** - * Deprecated migrate to DELETE(). - */ - @Deprecated - default HttpClientResponse delete() { - return DELETE(); - } - /** * Execute the request as a GET. */ diff --git a/http-client/client/src/main/java/io/avaje/http/client/HttpClientResponse.java b/http-client/client/src/main/java/io/avaje/http/client/HttpClientResponse.java index 30b9db9ea..afc8ff5aa 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/HttpClientResponse.java +++ b/http-client/client/src/main/java/io/avaje/http/client/HttpClientResponse.java @@ -146,12 +146,4 @@ public interface HttpClientResponse { */ HttpResponse withHandler(HttpResponse.BodyHandler responseHandler); - /** - * Deprecated migrate to {@link #withHandler(HttpResponse.BodyHandler)} - */ - @Deprecated - default HttpResponse withResponseHandler(HttpResponse.BodyHandler responseHandler) { - return withHandler(responseHandler); - } - } diff --git a/http-client/client/src/main/java/io/avaje/http/client/HttpException.java b/http-client/client/src/main/java/io/avaje/http/client/HttpException.java index ff81d25c7..89cc96728 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/HttpException.java +++ b/http-client/client/src/main/java/io/avaje/http/client/HttpException.java @@ -124,14 +124,6 @@ public int statusCode() { return statusCode; } - /** - * Deprecated migrate to statusCode() - */ - @Deprecated - public int getStatusCode() { - return statusCode(); - } - /** * Return the underlying HttpResponse. */ @@ -139,12 +131,4 @@ public HttpResponse httpResponse() { return httpResponse; } - /** - * Deprecated migrate to httpResponse(). - */ - @Deprecated - public HttpResponse getHttpResponse() { - return httpResponse(); - } - } diff --git a/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java b/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java index e21262430..9eaaefd96 100644 --- a/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java +++ b/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java @@ -722,7 +722,7 @@ void async_whenComplete_throwingHttpException() { final HttpException httpException = (HttpException) throwable.getCause(); causeRef.set(httpException); - assertThat(httpException.getStatusCode()).isEqualTo(422); + assertThat(httpException.statusCode()).isEqualTo(422); // convert json error response body to a bean final ErrorResponse errorResponse = httpException.bean(ErrorResponse.class); @@ -903,7 +903,7 @@ void postForm_asVoid_invokesValidation_expect_badRequest_extractError() { } catch (HttpException e) { assertEquals(422, e.statusCode()); - final HttpResponse httpResponse = e.getHttpResponse(); + final HttpResponse httpResponse = e.httpResponse(); assertNotNull(httpResponse); assertEquals(422, httpResponse.statusCode()); diff --git a/http-client/test/pom.xml b/http-client/test/pom.xml index 03e3ce51e..5c1816b93 100644 --- a/http-client/test/pom.xml +++ b/http-client/test/pom.xml @@ -16,19 +16,19 @@ io.avaje avaje-http-client - 1.3 + 1.9-SNAPSHOT io.avaje avaje-http-client-gson - 1.3 + 1.8 io.avaje avaje-http-api - 1.2 + 1.7 diff --git a/http-client/test/src/main/java/example/github/SimpleHttpClient.java b/http-client/test/src/main/java/example/github/SimpleHttpClient.java index ad2d33c88..4eb3210b1 100644 --- a/http-client/test/src/main/java/example/github/SimpleHttpClient.java +++ b/http-client/test/src/main/java/example/github/SimpleHttpClient.java @@ -37,7 +37,7 @@ public List listRepos(String user, String other) throws HttpException { return context.request() .path("users").path(user).path("repos") .queryParam("other", other) - .get().list(Repo.class); + .GET().list(Repo.class); } } diff --git a/http-client/test/src/test/java/example/github/GithubTest.java b/http-client/test/src/test/java/example/github/GithubTest.java index 9610be6e1..ff1e44f32 100644 --- a/http-client/test/src/test/java/example/github/GithubTest.java +++ b/http-client/test/src/test/java/example/github/GithubTest.java @@ -4,7 +4,6 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.google.gson.Gson; import io.avaje.http.client.BodyAdapter; -import io.avaje.http.client.HttpApi; import io.avaje.http.client.HttpClientContext; import io.avaje.http.client.JacksonBodyAdapter; import io.avaje.http.client.RequestLogger; @@ -34,7 +33,7 @@ private void assertListRepos(BodyAdapter bodyAdapter) { .withRequestListener(new RequestLogger()) .build(); - final Simple simple = HttpApi.provide(Simple.class, clientContext); + final Simple simple = clientContext.create(Simple.class); final List repos = simple.listRepos("rbygrave", "junk"); assertThat(repos).isNotEmpty(); From 6edef86e8db2f218d7b5cc5ef2bd1c1b866a4cd3 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Wed, 7 Jul 2021 15:09:07 +1200 Subject: [PATCH 0176/1323] #29 - Rename methods on HttpClientContext to be consistent with underlying HttpClient --- .../client/DHttpClientContextBuilder.java | 34 +++++------ .../avaje/http/client/HttpClientContext.java | 58 +++++++++---------- .../avaje/http/client/HttpClientRequest.java | 2 +- .../avaje/http/client/JacksonBodyAdapter.java | 7 +-- .../io/avaje/http/client/package-info.java | 4 +- .../io/avaje/http/client/AuthTokenTest.java | 8 +-- .../io/avaje/http/client/BaseWebTest.java | 6 +- .../http/client/BasicAuthInterceptTest.java | 2 +- .../io/avaje/http/client/DHttpApiTest.java | 4 +- .../http/client/DHttpClientContextTest.java | 8 +-- .../avaje/http/client/HelloBasicAuthTest.java | 8 +-- .../http/client/RequestListenerTest.java | 8 +-- .../java/io/avaje/http/client/RetryTest.java | 10 ++-- .../java/org/example/github/GithubTest.java | 6 +- .../test/java/example/github/GithubTest.java | 6 +- 15 files changed, 85 insertions(+), 86 deletions(-) diff --git a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContextBuilder.java b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContextBuilder.java index afd3a17a5..1eba92994 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContextBuilder.java +++ b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContextBuilder.java @@ -40,103 +40,103 @@ class DHttpClientContextBuilder implements HttpClientContext.Builder { } @Override - public HttpClientContext.Builder with(HttpClient client) { + public HttpClientContext.Builder client(HttpClient client) { this.client = client; return this; } @Override - public HttpClientContext.Builder withBaseUrl(String baseUrl) { + public HttpClientContext.Builder baseUrl(String baseUrl) { this.baseUrl = baseUrl; return this; } @Override - public HttpClientContext.Builder withRequestTimeout(Duration requestTimeout) { + public HttpClientContext.Builder requestTimeout(Duration requestTimeout) { this.requestTimeout = requestTimeout; return this; } @Override - public HttpClientContext.Builder withBodyAdapter(BodyAdapter adapter) { + public HttpClientContext.Builder bodyAdapter(BodyAdapter adapter) { this.bodyAdapter = adapter; return this; } @Override - public HttpClientContext.Builder withRetryHandler(RetryHandler retryHandler) { + public HttpClientContext.Builder retryHandler(RetryHandler retryHandler) { this.retryHandler = retryHandler; return this; } @Override - public HttpClientContext.Builder withRequestListener(RequestListener requestListener) { + public HttpClientContext.Builder requestListener(RequestListener requestListener) { this.listeners.add(requestListener); return this; } @Override - public HttpClientContext.Builder withRequestIntercept(RequestIntercept requestIntercept) { + public HttpClientContext.Builder requestIntercept(RequestIntercept requestIntercept) { this.interceptors.add(requestIntercept); return this; } @Override - public HttpClientContext.Builder withAuthTokenProvider(AuthTokenProvider authTokenProvider) { + public HttpClientContext.Builder authTokenProvider(AuthTokenProvider authTokenProvider) { this.authTokenProvider = authTokenProvider; return this; } @Override - public HttpClientContext.Builder withCookieHandler(CookieHandler cookieHandler) { + public HttpClientContext.Builder cookieHandler(CookieHandler cookieHandler) { this.cookieHandler = cookieHandler; return this; } @Override - public HttpClientContext.Builder withRedirect(HttpClient.Redirect redirect) { + public HttpClientContext.Builder redirect(HttpClient.Redirect redirect) { this.redirect = redirect; return this; } @Override - public HttpClientContext.Builder withVersion(HttpClient.Version version) { + public HttpClientContext.Builder version(HttpClient.Version version) { this.version = version; return this; } @Override - public HttpClientContext.Builder withExecutor(Executor executor) { + public HttpClientContext.Builder executor(Executor executor) { this.executor = executor; return this; } @Override - public HttpClientContext.Builder withProxy(ProxySelector proxySelector) { + public HttpClientContext.Builder proxy(ProxySelector proxySelector) { this.proxy = proxySelector; return this; } @Override - public HttpClientContext.Builder withSSLContext(SSLContext sslContext) { + public HttpClientContext.Builder sslContext(SSLContext sslContext) { this.sslContext = sslContext; return this; } @Override - public HttpClientContext.Builder withSSLParameters(SSLParameters sslParameters) { + public HttpClientContext.Builder sslParameters(SSLParameters sslParameters) { this.sslParameters = sslParameters; return this; } @Override - public HttpClientContext.Builder withAuthenticator(Authenticator authenticator) { + public HttpClientContext.Builder authenticator(Authenticator authenticator) { this.authenticator = authenticator; return this; } @Override - public HttpClientContext.Builder withPriority(int priority) { + public HttpClientContext.Builder priority(int priority) { this.priority = priority; return this; } diff --git a/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java b/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java index 914744d6f..c6daea55d 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java +++ b/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java @@ -16,9 +16,9 @@ *

{@code
  *
  *   HttpClientContext ctx = HttpClientContext.newBuilder()
- *       .withBaseUrl("http://localhost:8080")
- *       .withRequestListener(new RequestLogger())
- *       .withBodyAdapter(new JacksonBodyAdapter(new ObjectMapper()))
+ *       .baseUrl("http://localhost:8080")
+ *       .requestListener(new RequestLogger())
+ *       .bodyAdapter(new JacksonBodyAdapter(new ObjectMapper()))
  *       .build();
  *
  *  HelloDto dto = ctx.request()
@@ -38,9 +38,9 @@ public interface HttpClientContext {
    * 
{@code
    *
    *   HttpClientContext ctx = HttpClientContext.newBuilder()
-   *       .withBaseUrl("http://localhost:8080")
-   *       .withRequestListener(new RequestLogger())
-   *       .withBodyAdapter(new JacksonBodyAdapter(new ObjectMapper()))
+   *       .baseUrl("http://localhost:8080")
+   *       .requestListener(new RequestLogger())
+   *       .bodyAdapter(new JacksonBodyAdapter(new ObjectMapper()))
    *       .build();
    *
    *  HttpResponse res = ctx.request()
@@ -123,9 +123,9 @@ static HttpClientContext.Builder newBuilder() {
    * 
{@code
    *
    *   HttpClientContext ctx = HttpClientContext.newBuilder()
-   *       .withBaseUrl("http://localhost:8080")
-   *       .withRequestListener(new RequestLogger())
-   *       .withBodyAdapter(new JacksonBodyAdapter(new ObjectMapper()))
+   *       .baseUrl("http://localhost:8080")
+   *       .requestListener(new RequestLogger())
+   *       .bodyAdapter(new JacksonBodyAdapter(new ObjectMapper()))
    *       .build();
    *
    *  HelloDto dto = ctx.request()
@@ -144,32 +144,32 @@ interface Builder {
      * 

* Used when we wish to control all options of the HttpClient. */ - Builder with(HttpClient client); + Builder client(HttpClient client); /** * Set the base URL to use for requests created from the context. *

* Note that the base url can be replaced via {@link HttpClientRequest#url(String)}. */ - Builder withBaseUrl(String baseUrl); + Builder baseUrl(String baseUrl); /** * Set the default request timeout. * * @see java.net.http.HttpRequest.Builder#timeout(Duration) */ - Builder withRequestTimeout(Duration requestTimeout); + Builder requestTimeout(Duration requestTimeout); /** * Set the body adapter to use to convert beans to body content * and response content back to beans. */ - Builder withBodyAdapter(BodyAdapter adapter); + Builder bodyAdapter(BodyAdapter adapter); /** * Set a RetryHandler to use to retry requests. */ - Builder withRetryHandler(RetryHandler retryHandler); + Builder retryHandler(RetryHandler retryHandler); /** * Add a request listener. Multiple listeners may be added, when @@ -179,12 +179,12 @@ interface Builder { * implementation for debug logging request/response headers and * content. */ - Builder withRequestListener(RequestListener requestListener); + Builder requestListener(RequestListener requestListener); /** * Add a request interceptor. Multiple interceptors may be added. */ - Builder withRequestIntercept(RequestIntercept requestIntercept); + Builder requestIntercept(RequestIntercept requestIntercept); /** * Add a Authorization token provider. @@ -196,28 +196,28 @@ interface Builder { * is automatically called as needed and the Authorization Bearer header set * on all requests (not marked with skipAuthToken()). */ - Builder withAuthTokenProvider(AuthTokenProvider authTokenProvider); + Builder authTokenProvider(AuthTokenProvider authTokenProvider); /** * Specify a cookie handler to use on the HttpClient. This would override the default cookie handler. * * @see HttpClient.Builder#cookieHandler(CookieHandler) */ - Builder withCookieHandler(CookieHandler cookieHandler); + Builder cookieHandler(CookieHandler cookieHandler); /** * Specify the redirect policy. Defaults to HttpClient.Redirect.NORMAL. * * @see HttpClient.Builder#followRedirects(HttpClient.Redirect) */ - Builder withRedirect(HttpClient.Redirect redirect); + Builder redirect(HttpClient.Redirect redirect); /** * Specify the HTTP version. Defaults to not set. * * @see HttpClient.Builder#version(HttpClient.Version) */ - Builder withVersion(HttpClient.Version version); + Builder version(HttpClient.Version version); /** * Specify the Executor to use for asynchronous tasks. @@ -225,42 +225,42 @@ interface Builder { * * @see HttpClient.Builder#executor(Executor) */ - Builder withExecutor(Executor executor); + Builder executor(Executor executor); /** * Set the proxy to the underlying {@link HttpClient}. * * @see HttpClient.Builder#proxy(ProxySelector) */ - Builder withProxy(ProxySelector proxySelector); + Builder proxy(ProxySelector proxySelector); /** * Set the sslContext to the underlying {@link HttpClient}. * * @see HttpClient.Builder#sslContext(SSLContext) */ - Builder withSSLContext(SSLContext sslContext); + Builder sslContext(SSLContext sslContext); /** * Set the sslParameters to the underlying {@link HttpClient}. * * @see HttpClient.Builder#sslParameters(SSLParameters) */ - Builder withSSLParameters(SSLParameters sslParameters); + Builder sslParameters(SSLParameters sslParameters); /** * Set a HttpClient authenticator to the underlying {@link HttpClient}. * * @see HttpClient.Builder#authenticator(Authenticator) */ - Builder withAuthenticator(Authenticator authenticator); + Builder authenticator(Authenticator authenticator); /** * Set the priority for HTTP/2 requests to the underlying {@link HttpClient}. * * @see HttpClient.Builder#priority(int) */ - Builder withPriority(int priority); + Builder priority(int priority); /** * Build and return the context. @@ -268,9 +268,9 @@ interface Builder { *

{@code
      *
      *   HttpClientContext ctx = HttpClientContext.newBuilder()
-     *       .withBaseUrl("http://localhost:8080")
-     *       .withRequestListener(new RequestLogger())
-     *       .withBodyAdapter(new JacksonBodyAdapter(new ObjectMapper()))
+     *       .baseUrl("http://localhost:8080")
+     *       .requestListener(new RequestLogger())
+     *       .bodyAdapter(new JacksonBodyAdapter(new ObjectMapper()))
      *       .build();
      *
      *  HelloDto dto = ctx.request()
diff --git a/http-client/client/src/main/java/io/avaje/http/client/HttpClientRequest.java b/http-client/client/src/main/java/io/avaje/http/client/HttpClientRequest.java
index 16da844eb..3a61fe773 100644
--- a/http-client/client/src/main/java/io/avaje/http/client/HttpClientRequest.java
+++ b/http-client/client/src/main/java/io/avaje/http/client/HttpClientRequest.java
@@ -145,7 +145,7 @@ public interface HttpClientRequest {
    *
    * @param url The url effectively replacing the base url.
    * @return The request being built
-   * @see HttpClientContext.Builder#withBaseUrl(String)
+   * @see HttpClientContext.Builder#baseUrl(String)
    */
   HttpClientRequest url(String url);
 
diff --git a/http-client/client/src/main/java/io/avaje/http/client/JacksonBodyAdapter.java b/http-client/client/src/main/java/io/avaje/http/client/JacksonBodyAdapter.java
index 049aee16d..b45119002 100644
--- a/http-client/client/src/main/java/io/avaje/http/client/JacksonBodyAdapter.java
+++ b/http-client/client/src/main/java/io/avaje/http/client/JacksonBodyAdapter.java
@@ -16,10 +16,9 @@
  * 
{@code
  *
  *   HttpClientContext.newBuilder()
- *       .withBaseUrl(baseUrl)
- *       .withRequestListener(new RequestLogger())
- *       .withBodyAdapter(new JacksonBodyAdapter(new ObjectMapper()))
- *       //.withBodyAdapter(new GsonBodyAdapter(new Gson()))
+ *       .baseUrl(baseUrl)
+ *       .bodyAdapter(new JacksonBodyAdapter(new ObjectMapper()))
+ *       //.bodyAdapter(new GsonBodyAdapter(new Gson()))
  *       .build();
  *
  * }
diff --git a/http-client/client/src/main/java/io/avaje/http/client/package-info.java b/http-client/client/src/main/java/io/avaje/http/client/package-info.java index 02f86d631..4acea8f16 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/package-info.java +++ b/http-client/client/src/main/java/io/avaje/http/client/package-info.java @@ -7,8 +7,8 @@ *
{@code
  *
  *   HttpClientContext ctx = HttpClientContext.newBuilder()
- *       .withBaseUrl("http://localhost:8080")
- *       .withBodyAdapter(new JacksonBodyAdapter(new ObjectMapper()))
+ *       .baseUrl("http://localhost:8080")
+ *       .bodyAdapter(new JacksonBodyAdapter(new ObjectMapper()))
  *       .build();
  *
  *  HelloDto dto = ctx.request()
diff --git a/http-client/client/src/test/java/io/avaje/http/client/AuthTokenTest.java b/http-client/client/src/test/java/io/avaje/http/client/AuthTokenTest.java
index de59da4b9..409d67b0c 100644
--- a/http-client/client/src/test/java/io/avaje/http/client/AuthTokenTest.java
+++ b/http-client/client/src/test/java/io/avaje/http/client/AuthTokenTest.java
@@ -46,10 +46,10 @@ public AuthToken obtainToken(HttpClientRequest tokenRequest) {
   void sendEmail() {
 
     HttpClientContext ctx = HttpClientContext.newBuilder()
-      .withBaseUrl("https://foo")
-      .withBodyAdapter(new JacksonBodyAdapter(objectMapper))
-      .withRequestListener(new RequestLogger())
-      .withAuthTokenProvider(new MyAuthTokenProvider())
+      .baseUrl("https://foo")
+      .bodyAdapter(new JacksonBodyAdapter(objectMapper))
+      .requestListener(new RequestLogger())
+      .authTokenProvider(new MyAuthTokenProvider())
       .build();
 
     String path = "bar";
diff --git a/http-client/client/src/test/java/io/avaje/http/client/BaseWebTest.java b/http-client/client/src/test/java/io/avaje/http/client/BaseWebTest.java
index c2a8eb07b..c7125066f 100644
--- a/http-client/client/src/test/java/io/avaje/http/client/BaseWebTest.java
+++ b/http-client/client/src/test/java/io/avaje/http/client/BaseWebTest.java
@@ -25,9 +25,9 @@ public static void shutdown() {
 
   public static HttpClientContext client() {
     return HttpClientContext.newBuilder()
-      .withBaseUrl(baseUrl)
-      .withRequestListener(new RequestLogger())
-      .withBodyAdapter(new JacksonBodyAdapter(new ObjectMapper()))
+      .baseUrl(baseUrl)
+      .requestListener(new RequestLogger())
+      .bodyAdapter(new JacksonBodyAdapter(new ObjectMapper()))
 //      .withBodyAdapter(new GsonBodyAdapter(new Gson()))
       .build();
   }
diff --git a/http-client/client/src/test/java/io/avaje/http/client/BasicAuthInterceptTest.java b/http-client/client/src/test/java/io/avaje/http/client/BasicAuthInterceptTest.java
index a2df5cd59..95147d22a 100644
--- a/http-client/client/src/test/java/io/avaje/http/client/BasicAuthInterceptTest.java
+++ b/http-client/client/src/test/java/io/avaje/http/client/BasicAuthInterceptTest.java
@@ -18,7 +18,7 @@ void encode() {
   void beforeRequest() {
     // setup
     final BasicAuthIntercept intercept = new BasicAuthIntercept("Aladdin", "open sesame");
-    final HttpClientContext ctx = HttpClientContext.newBuilder().withBaseUrl("junk").build();
+    final HttpClientContext ctx = HttpClientContext.newBuilder().baseUrl("junk").build();
 
     // act
     final HttpClientRequest request = ctx.request();
diff --git a/http-client/client/src/test/java/io/avaje/http/client/DHttpApiTest.java b/http-client/client/src/test/java/io/avaje/http/client/DHttpApiTest.java
index 06c6dc3b5..eca285bb3 100644
--- a/http-client/client/src/test/java/io/avaje/http/client/DHttpApiTest.java
+++ b/http-client/client/src/test/java/io/avaje/http/client/DHttpApiTest.java
@@ -20,8 +20,8 @@ void test_github_listRepos() {
       .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false));
 
     final HttpClientContext clientContext = HttpClientContext.newBuilder()
-      .withBaseUrl("https://api.github.com")
-      .withBodyAdapter(bodyAdapter)
+      .baseUrl("https://api.github.com")
+      .bodyAdapter(bodyAdapter)
       .build();
 
     DHttpApi httpApi = new DHttpApi();
diff --git a/http-client/client/src/test/java/io/avaje/http/client/DHttpClientContextTest.java b/http-client/client/src/test/java/io/avaje/http/client/DHttpClientContextTest.java
index beae2c81d..abd57b92a 100644
--- a/http-client/client/src/test/java/io/avaje/http/client/DHttpClientContextTest.java
+++ b/http-client/client/src/test/java/io/avaje/http/client/DHttpClientContextTest.java
@@ -42,7 +42,7 @@ void build_basic() {
 
     final HttpClientContext context =
       HttpClientContext.newBuilder()
-      .withBaseUrl("http://localhost")
+      .baseUrl("http://localhost")
       .build();
 
     // has default client created
@@ -61,9 +61,9 @@ void build_noCookieHandler() {
 
     final HttpClientContext context =
       HttpClientContext.newBuilder()
-        .withBaseUrl("http://localhost")
-        .withCookieHandler(null)
-        .withRedirect(HttpClient.Redirect.ALWAYS)
+        .baseUrl("http://localhost")
+        .cookieHandler(null)
+        .redirect(HttpClient.Redirect.ALWAYS)
         .build();
 
     // has default client created
diff --git a/http-client/client/src/test/java/io/avaje/http/client/HelloBasicAuthTest.java b/http-client/client/src/test/java/io/avaje/http/client/HelloBasicAuthTest.java
index edfe57d92..55960fa35 100644
--- a/http-client/client/src/test/java/io/avaje/http/client/HelloBasicAuthTest.java
+++ b/http-client/client/src/test/java/io/avaje/http/client/HelloBasicAuthTest.java
@@ -13,10 +13,10 @@ class HelloBasicAuthTest extends BaseWebTest {
 
   public static HttpClientContext client() {
     return HttpClientContext.newBuilder()
-      .withBaseUrl(baseUrl)
-      .withRequestListener(new RequestLogger())
-      .withBodyAdapter(new JacksonBodyAdapter(new ObjectMapper()))
-      .withRequestIntercept(new BasicAuthIntercept("rob", "bot"))
+      .baseUrl(baseUrl)
+      .requestListener(new RequestLogger())
+      .bodyAdapter(new JacksonBodyAdapter(new ObjectMapper()))
+      .requestIntercept(new BasicAuthIntercept("rob", "bot"))
       .build();
   }
 
diff --git a/http-client/client/src/test/java/io/avaje/http/client/RequestListenerTest.java b/http-client/client/src/test/java/io/avaje/http/client/RequestListenerTest.java
index a6806c032..ed4e4fd0a 100644
--- a/http-client/client/src/test/java/io/avaje/http/client/RequestListenerTest.java
+++ b/http-client/client/src/test/java/io/avaje/http/client/RequestListenerTest.java
@@ -35,10 +35,10 @@ public void response(Event event) {
 
   private HttpClientContext createClient(TDRequestListener tdRequestListener) {
     return HttpClientContext.newBuilder()
-      .withBaseUrl(baseUrl)
-      .withRequestListener(new RequestLogger())
-      .withBodyAdapter(new JacksonBodyAdapter(new ObjectMapper()))
-      .withRequestListener(tdRequestListener)
+      .baseUrl(baseUrl)
+      .requestListener(new RequestLogger())
+      .bodyAdapter(new JacksonBodyAdapter(new ObjectMapper()))
+      .requestListener(tdRequestListener)
       .build();
   }
 
diff --git a/http-client/client/src/test/java/io/avaje/http/client/RetryTest.java b/http-client/client/src/test/java/io/avaje/http/client/RetryTest.java
index 794431125..765f38a90 100644
--- a/http-client/client/src/test/java/io/avaje/http/client/RetryTest.java
+++ b/http-client/client/src/test/java/io/avaje/http/client/RetryTest.java
@@ -14,11 +14,11 @@ public class RetryTest extends BaseWebTest {
 
   HttpClientContext initClientWithRetry() {
     return HttpClientContext.newBuilder()
-      .withBaseUrl("http://localhost:8887")
-      .withBodyAdapter(new JacksonBodyAdapter(new ObjectMapper()))
-      .withRequestListener(new RequestLogger())
-      .withRetryHandler(new SimpleRetryHandler(4, 1))
-      .withRequestIntercept(myIntercept)
+      .baseUrl("http://localhost:8887")
+      .bodyAdapter(new JacksonBodyAdapter(new ObjectMapper()))
+      .requestListener(new RequestLogger())
+      .retryHandler(new SimpleRetryHandler(4, 1))
+      .requestIntercept(myIntercept)
       .build();
   }
 
diff --git a/http-client/client/src/test/java/org/example/github/GithubTest.java b/http-client/client/src/test/java/org/example/github/GithubTest.java
index 238fb28fa..b20ee1713 100644
--- a/http-client/client/src/test/java/org/example/github/GithubTest.java
+++ b/http-client/client/src/test/java/org/example/github/GithubTest.java
@@ -22,9 +22,9 @@ public class GithubTest {
   void test() throws InterruptedException {
 
     final HttpClientContext clientContext = HttpClientContext.newBuilder()
-      .withBaseUrl("https://api.github.com")
-      .withBodyAdapter(bodyAdapter)
-      .withRequestListener(new RequestLogger())
+      .baseUrl("https://api.github.com")
+      .bodyAdapter(bodyAdapter)
+      .requestListener(new RequestLogger())
       .build();
 
     clientContext.request()
diff --git a/http-client/test/src/test/java/example/github/GithubTest.java b/http-client/test/src/test/java/example/github/GithubTest.java
index ff1e44f32..b89462644 100644
--- a/http-client/test/src/test/java/example/github/GithubTest.java
+++ b/http-client/test/src/test/java/example/github/GithubTest.java
@@ -28,9 +28,9 @@ void test_with_gson() {
 
   private void assertListRepos(BodyAdapter bodyAdapter) {
     final HttpClientContext clientContext = HttpClientContext.newBuilder()
-      .withBaseUrl("https://api.github.com")
-      .withBodyAdapter(bodyAdapter)
-      .withRequestListener(new RequestLogger())
+      .baseUrl("https://api.github.com")
+      .bodyAdapter(bodyAdapter)
+      .requestListener(new RequestLogger())
       .build();
 
     final Simple simple = clientContext.create(Simple.class);

From 537d22e6c2e18918cdd5fef01a6e6534dc4e897f Mon Sep 17 00:00:00 2001
From: rbygrave 
Date: Wed, 7 Jul 2021 15:16:03 +1200
Subject: [PATCH 0177/1323] #30 - ENH: Add default constructor option for
 JacksonBodyAdapter() with reasonable defaults

---
 .../avaje/http/client/JacksonBodyAdapter.java | 20 +++++++++++++++----
 .../io/avaje/http/client/DHttpApiTest.java    |  5 +----
 .../http/client/RequestListenerTest.java      |  2 +-
 .../java/io/avaje/http/client/RetryTest.java  |  2 +-
 .../java/org/example/github/GithubTest.java   |  7 +------
 .../test/java/example/github/GithubTest.java  |  5 +----
 6 files changed, 21 insertions(+), 20 deletions(-)

diff --git a/http-client/client/src/main/java/io/avaje/http/client/JacksonBodyAdapter.java b/http-client/client/src/main/java/io/avaje/http/client/JacksonBodyAdapter.java
index b45119002..fc03882c4 100644
--- a/http-client/client/src/main/java/io/avaje/http/client/JacksonBodyAdapter.java
+++ b/http-client/client/src/main/java/io/avaje/http/client/JacksonBodyAdapter.java
@@ -1,9 +1,8 @@
 package io.avaje.http.client;
 
+import com.fasterxml.jackson.annotation.JsonInclude;
 import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.ObjectReader;
-import com.fasterxml.jackson.databind.ObjectWriter;
+import com.fasterxml.jackson.databind.*;
 import com.fasterxml.jackson.databind.type.CollectionType;
 
 import java.io.IOException;
@@ -18,7 +17,6 @@
  *   HttpClientContext.newBuilder()
  *       .baseUrl(baseUrl)
  *       .bodyAdapter(new JacksonBodyAdapter(new ObjectMapper()))
- *       //.bodyAdapter(new GsonBodyAdapter(new Gson()))
  *       .build();
  *
  * }
@@ -33,10 +31,24 @@ public class JacksonBodyAdapter implements BodyAdapter { private final ConcurrentHashMap, BodyReader> listReaderCache = new ConcurrentHashMap<>(); + /** + * Create passing the ObjectMapper to use. + */ public JacksonBodyAdapter(ObjectMapper mapper) { this.mapper = mapper; } + /** + * Create with a ObjectMapper that allows unknown properties and inclusion non empty. + */ + public JacksonBodyAdapter() { + this.mapper = new ObjectMapper() + .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) + .configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false) + .configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false) + .setSerializationInclusion(JsonInclude.Include.NON_EMPTY); + } + @Override public BodyWriter beanWriter(Class cls) { return beanWriterCache.computeIfAbsent(cls, aClass -> { diff --git a/http-client/client/src/test/java/io/avaje/http/client/DHttpApiTest.java b/http-client/client/src/test/java/io/avaje/http/client/DHttpApiTest.java index eca285bb3..b075dee8e 100644 --- a/http-client/client/src/test/java/io/avaje/http/client/DHttpApiTest.java +++ b/http-client/client/src/test/java/io/avaje/http/client/DHttpApiTest.java @@ -16,12 +16,9 @@ public class DHttpApiTest { @Test void test_github_listRepos() { - JacksonBodyAdapter bodyAdapter = new JacksonBodyAdapter(new ObjectMapper() - .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)); - final HttpClientContext clientContext = HttpClientContext.newBuilder() .baseUrl("https://api.github.com") - .bodyAdapter(bodyAdapter) + .bodyAdapter(new JacksonBodyAdapter()) .build(); DHttpApi httpApi = new DHttpApi(); diff --git a/http-client/client/src/test/java/io/avaje/http/client/RequestListenerTest.java b/http-client/client/src/test/java/io/avaje/http/client/RequestListenerTest.java index ed4e4fd0a..fb8d9dbca 100644 --- a/http-client/client/src/test/java/io/avaje/http/client/RequestListenerTest.java +++ b/http-client/client/src/test/java/io/avaje/http/client/RequestListenerTest.java @@ -37,7 +37,7 @@ private HttpClientContext createClient(TDRequestListener tdRequestListener) { return HttpClientContext.newBuilder() .baseUrl(baseUrl) .requestListener(new RequestLogger()) - .bodyAdapter(new JacksonBodyAdapter(new ObjectMapper())) + .bodyAdapter(new JacksonBodyAdapter()) .requestListener(tdRequestListener) .build(); } diff --git a/http-client/client/src/test/java/io/avaje/http/client/RetryTest.java b/http-client/client/src/test/java/io/avaje/http/client/RetryTest.java index 765f38a90..94c33689c 100644 --- a/http-client/client/src/test/java/io/avaje/http/client/RetryTest.java +++ b/http-client/client/src/test/java/io/avaje/http/client/RetryTest.java @@ -15,7 +15,7 @@ public class RetryTest extends BaseWebTest { HttpClientContext initClientWithRetry() { return HttpClientContext.newBuilder() .baseUrl("http://localhost:8887") - .bodyAdapter(new JacksonBodyAdapter(new ObjectMapper())) + .bodyAdapter(new JacksonBodyAdapter()) .requestListener(new RequestLogger()) .retryHandler(new SimpleRetryHandler(4, 1)) .requestIntercept(myIntercept) diff --git a/http-client/client/src/test/java/org/example/github/GithubTest.java b/http-client/client/src/test/java/org/example/github/GithubTest.java index b20ee1713..4fe1ff38f 100644 --- a/http-client/client/src/test/java/org/example/github/GithubTest.java +++ b/http-client/client/src/test/java/org/example/github/GithubTest.java @@ -1,7 +1,5 @@ package org.example.github; -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.ObjectMapper; import io.avaje.http.client.HttpClientContext; import io.avaje.http.client.JacksonBodyAdapter; import io.avaje.http.client.RequestLogger; @@ -14,16 +12,13 @@ public class GithubTest { - private final JacksonBodyAdapter bodyAdapter = new JacksonBodyAdapter(new ObjectMapper() - .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)); - @Test @Disabled void test() throws InterruptedException { final HttpClientContext clientContext = HttpClientContext.newBuilder() .baseUrl("https://api.github.com") - .bodyAdapter(bodyAdapter) + .bodyAdapter(new JacksonBodyAdapter()) .requestListener(new RequestLogger()) .build(); diff --git a/http-client/test/src/test/java/example/github/GithubTest.java b/http-client/test/src/test/java/example/github/GithubTest.java index b89462644..d99d13190 100644 --- a/http-client/test/src/test/java/example/github/GithubTest.java +++ b/http-client/test/src/test/java/example/github/GithubTest.java @@ -1,7 +1,5 @@ package example.github; -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.ObjectMapper; import com.google.gson.Gson; import io.avaje.http.client.BodyAdapter; import io.avaje.http.client.HttpClientContext; @@ -40,8 +38,7 @@ private void assertListRepos(BodyAdapter bodyAdapter) { } private BodyAdapter jacksonBodyAdapter() { - return new JacksonBodyAdapter(new ObjectMapper() - .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)); + return new JacksonBodyAdapter(); } private BodyAdapter gsonBodyAdapter() { From 5af42e62230cbbdbbb7d2e6db8c3b914ec4a2f46 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Wed, 7 Jul 2021 15:50:01 +1200 Subject: [PATCH 0178/1323] #31 - By default register RequestLogger - add HttpClientContext.requestLogging(boolean) to enable disable --- .../client/DHttpClientContextBuilder.java | 15 ++++++-- .../avaje/http/client/HttpClientContext.java | 35 +++++++++++++++++-- .../io/avaje/http/client/AuthTokenTest.java | 1 - .../io/avaje/http/client/BaseWebTest.java | 2 -- .../io/avaje/http/client/DHttpApiTest.java | 6 ++-- .../avaje/http/client/HelloBasicAuthTest.java | 1 - .../http/client/RequestListenerTest.java | 1 + .../java/io/avaje/http/client/RetryTest.java | 1 - .../java/org/example/github/GithubTest.java | 2 +- .../org/example/github/SimpleProvider.java | 3 +- .../Simple$HttpClient.java} | 10 +++--- .../test/java/example/github/GithubTest.java | 4 +-- 12 files changed, 59 insertions(+), 22 deletions(-) rename http-client/client/src/test/java/org/example/github/{SimpleHttpClient.java => httpclient/Simple$HttpClient.java} (88%) diff --git a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContextBuilder.java b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContextBuilder.java index 1eba92994..e81a1e5ca 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContextBuilder.java +++ b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContextBuilder.java @@ -18,6 +18,7 @@ class DHttpClientContextBuilder implements HttpClientContext.Builder { private HttpClient client; private String baseUrl; + private boolean requestLogging = true; private Duration requestTimeout = Duration.ofSeconds(20); private BodyAdapter bodyAdapter; private RetryHandler retryHandler; @@ -69,6 +70,12 @@ public HttpClientContext.Builder retryHandler(RetryHandler retryHandler) { return this; } + @Override + public HttpClientContext.Builder requestLogging(boolean requestLogging) { + this.requestLogging = requestLogging; + return this; + } + @Override public HttpClientContext.Builder requestListener(RequestListener requestListener) { this.listeners.add(requestListener); @@ -148,6 +155,10 @@ public HttpClientContext build() { if (client == null) { client = defaultClient(); } + if (requestLogging) { + // register the built in request/response logging + requestListener(new RequestLogger()); + } return new DHttpClientContext(client, baseUrl, requestTimeout, bodyAdapter, retryHandler, buildListener(), authTokenProvider, buildIntercept()); } @@ -173,8 +184,8 @@ private RequestIntercept buildIntercept() { private HttpClient defaultClient() { final HttpClient.Builder builder = HttpClient.newBuilder() - .followRedirects(redirect) - .connectTimeout(Duration.ofSeconds(20)); + .followRedirects(redirect) + .connectTimeout(Duration.ofSeconds(20)); if (cookieHandler != null) { builder.cookieHandler(cookieHandler); } diff --git a/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java b/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java index c6daea55d..9d16c57df 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java +++ b/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java @@ -171,13 +171,42 @@ interface Builder { */ Builder retryHandler(RetryHandler retryHandler); + /** + * Disable or enable built in request and response logging. + *

+ * By default request logging is enabled. Set this to false to stop + * the default {@link RequestLogger} being registered to log + * request and response headers and bodies etc. + *

+ * With logging level set to {@code DEBUG} for + * {@code io.avaje.http.client.RequestLogger} the request and + * response are logged with headers only. + *

+ * Set the logging level to {@code TRACE} to include the request + * and response body payloads (with truncation for large bodies). + * + *

Suppression

+ *

+ * We can also use {@link HttpClientRequest#suppressLogging()} to suppress + * logging on specific requests. + *

+ * Logging of Authorization headers is suppressed. + * {@link AuthTokenProvider} requests are suppressed. + * + * @param requestLogging To turn disable/enable the registration of the default logger + * @see RequestLogger + */ + Builder requestLogging(boolean requestLogging); + /** * Add a request listener. Multiple listeners may be added, when * do so they will process events in the order they were added. *

- * Note that {@link RequestLogger} is an - * implementation for debug logging request/response headers and - * content. + * Note that {@link RequestLogger} is an implementation for debug + * logging request/response headers and content which is registered + * by default depending on {@link #requestLogging(boolean)}. + * + * @see RequestLogger */ Builder requestListener(RequestListener requestListener); diff --git a/http-client/client/src/test/java/io/avaje/http/client/AuthTokenTest.java b/http-client/client/src/test/java/io/avaje/http/client/AuthTokenTest.java index 409d67b0c..d32969b56 100644 --- a/http-client/client/src/test/java/io/avaje/http/client/AuthTokenTest.java +++ b/http-client/client/src/test/java/io/avaje/http/client/AuthTokenTest.java @@ -48,7 +48,6 @@ void sendEmail() { HttpClientContext ctx = HttpClientContext.newBuilder() .baseUrl("https://foo") .bodyAdapter(new JacksonBodyAdapter(objectMapper)) - .requestListener(new RequestLogger()) .authTokenProvider(new MyAuthTokenProvider()) .build(); diff --git a/http-client/client/src/test/java/io/avaje/http/client/BaseWebTest.java b/http-client/client/src/test/java/io/avaje/http/client/BaseWebTest.java index c7125066f..bb37e64c5 100644 --- a/http-client/client/src/test/java/io/avaje/http/client/BaseWebTest.java +++ b/http-client/client/src/test/java/io/avaje/http/client/BaseWebTest.java @@ -26,9 +26,7 @@ public static void shutdown() { public static HttpClientContext client() { return HttpClientContext.newBuilder() .baseUrl(baseUrl) - .requestListener(new RequestLogger()) .bodyAdapter(new JacksonBodyAdapter(new ObjectMapper())) -// .withBodyAdapter(new GsonBodyAdapter(new Gson())) .build(); } } diff --git a/http-client/client/src/test/java/io/avaje/http/client/DHttpApiTest.java b/http-client/client/src/test/java/io/avaje/http/client/DHttpApiTest.java index b075dee8e..cee2051e3 100644 --- a/http-client/client/src/test/java/io/avaje/http/client/DHttpApiTest.java +++ b/http-client/client/src/test/java/io/avaje/http/client/DHttpApiTest.java @@ -1,10 +1,8 @@ package io.avaje.http.client; -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.ObjectMapper; import org.example.github.Repo; import org.example.github.Simple; -import org.example.github.SimpleHttpClient; +import org.example.github.httpclient.Simple$HttpClient; import org.junit.jupiter.api.Test; import java.util.List; @@ -22,7 +20,7 @@ void test_github_listRepos() { .build(); DHttpApi httpApi = new DHttpApi(); - httpApi.addProvider(new SimpleHttpClient.Provider()); + httpApi.addProvider(new Simple$HttpClient.Provider()); final Simple simple = httpApi.provideFor(Simple.class, clientContext); final List repos = simple.listRepos("rbygrave", "junk"); diff --git a/http-client/client/src/test/java/io/avaje/http/client/HelloBasicAuthTest.java b/http-client/client/src/test/java/io/avaje/http/client/HelloBasicAuthTest.java index 55960fa35..a56332cf2 100644 --- a/http-client/client/src/test/java/io/avaje/http/client/HelloBasicAuthTest.java +++ b/http-client/client/src/test/java/io/avaje/http/client/HelloBasicAuthTest.java @@ -14,7 +14,6 @@ class HelloBasicAuthTest extends BaseWebTest { public static HttpClientContext client() { return HttpClientContext.newBuilder() .baseUrl(baseUrl) - .requestListener(new RequestLogger()) .bodyAdapter(new JacksonBodyAdapter(new ObjectMapper())) .requestIntercept(new BasicAuthIntercept("rob", "bot")) .build(); diff --git a/http-client/client/src/test/java/io/avaje/http/client/RequestListenerTest.java b/http-client/client/src/test/java/io/avaje/http/client/RequestListenerTest.java index fb8d9dbca..04773e105 100644 --- a/http-client/client/src/test/java/io/avaje/http/client/RequestListenerTest.java +++ b/http-client/client/src/test/java/io/avaje/http/client/RequestListenerTest.java @@ -36,6 +36,7 @@ public void response(Event event) { private HttpClientContext createClient(TDRequestListener tdRequestListener) { return HttpClientContext.newBuilder() .baseUrl(baseUrl) + .requestLogging(false) .requestListener(new RequestLogger()) .bodyAdapter(new JacksonBodyAdapter()) .requestListener(tdRequestListener) diff --git a/http-client/client/src/test/java/io/avaje/http/client/RetryTest.java b/http-client/client/src/test/java/io/avaje/http/client/RetryTest.java index 94c33689c..745416043 100644 --- a/http-client/client/src/test/java/io/avaje/http/client/RetryTest.java +++ b/http-client/client/src/test/java/io/avaje/http/client/RetryTest.java @@ -16,7 +16,6 @@ HttpClientContext initClientWithRetry() { return HttpClientContext.newBuilder() .baseUrl("http://localhost:8887") .bodyAdapter(new JacksonBodyAdapter()) - .requestListener(new RequestLogger()) .retryHandler(new SimpleRetryHandler(4, 1)) .requestIntercept(myIntercept) .build(); diff --git a/http-client/client/src/test/java/org/example/github/GithubTest.java b/http-client/client/src/test/java/org/example/github/GithubTest.java index 4fe1ff38f..bb9521eb3 100644 --- a/http-client/client/src/test/java/org/example/github/GithubTest.java +++ b/http-client/client/src/test/java/org/example/github/GithubTest.java @@ -19,7 +19,7 @@ void test() throws InterruptedException { final HttpClientContext clientContext = HttpClientContext.newBuilder() .baseUrl("https://api.github.com") .bodyAdapter(new JacksonBodyAdapter()) - .requestListener(new RequestLogger()) + .requestLogging(false) .build(); clientContext.request() diff --git a/http-client/client/src/test/java/org/example/github/SimpleProvider.java b/http-client/client/src/test/java/org/example/github/SimpleProvider.java index cf362b481..58bd5a339 100644 --- a/http-client/client/src/test/java/org/example/github/SimpleProvider.java +++ b/http-client/client/src/test/java/org/example/github/SimpleProvider.java @@ -2,6 +2,7 @@ import io.avaje.http.client.HttpApiProvider; import io.avaje.http.client.HttpClientContext; +import org.example.github.httpclient.Simple$HttpClient; public class SimpleProvider implements HttpApiProvider { @@ -12,6 +13,6 @@ public Class type() { @Override public Simple provide(HttpClientContext client) { - return new SimpleHttpClient(client); + return new Simple$HttpClient(client); } } diff --git a/http-client/client/src/test/java/org/example/github/SimpleHttpClient.java b/http-client/client/src/test/java/org/example/github/httpclient/Simple$HttpClient.java similarity index 88% rename from http-client/client/src/test/java/org/example/github/SimpleHttpClient.java rename to http-client/client/src/test/java/org/example/github/httpclient/Simple$HttpClient.java index ec2f8bd14..5dbf79b84 100644 --- a/http-client/client/src/test/java/org/example/github/SimpleHttpClient.java +++ b/http-client/client/src/test/java/org/example/github/httpclient/Simple$HttpClient.java @@ -1,22 +1,24 @@ -package org.example.github; +package org.example.github.httpclient; import io.avaje.http.api.Get; import io.avaje.http.api.Post; import io.avaje.http.client.*; +import org.example.github.Repo; +import org.example.github.Simple; import java.io.InputStream; import java.net.http.HttpResponse; import java.util.List; -public class SimpleHttpClient implements Simple { +public class Simple$HttpClient implements Simple { private final HttpClientContext context; private final BodyReader readRepo; private final BodyWriter writeRepo; // private final BodyConverter, String> toListOfRepo; - SimpleHttpClient(HttpClientContext context) { + public Simple$HttpClient(HttpClientContext context) { this.context = context; this.readRepo = context.converters().beanReader(Repo.class); this.writeRepo = context.converters().beanWriter(Repo.class); @@ -74,7 +76,7 @@ public Class type() { @Override public Simple provide(HttpClientContext client) { - return new SimpleHttpClient(client); + return new Simple$HttpClient(client); } } diff --git a/http-client/test/src/test/java/example/github/GithubTest.java b/http-client/test/src/test/java/example/github/GithubTest.java index d99d13190..8e912648a 100644 --- a/http-client/test/src/test/java/example/github/GithubTest.java +++ b/http-client/test/src/test/java/example/github/GithubTest.java @@ -4,7 +4,6 @@ import io.avaje.http.client.BodyAdapter; import io.avaje.http.client.HttpClientContext; import io.avaje.http.client.JacksonBodyAdapter; -import io.avaje.http.client.RequestLogger; import io.avaje.http.client.gson.GsonBodyAdapter; import org.junit.jupiter.api.Test; @@ -28,7 +27,8 @@ private void assertListRepos(BodyAdapter bodyAdapter) { final HttpClientContext clientContext = HttpClientContext.newBuilder() .baseUrl("https://api.github.com") .bodyAdapter(bodyAdapter) - .requestListener(new RequestLogger()) +// .requestLogging(false) +// .requestListener(new RequestLogger()) .build(); final Simple simple = clientContext.create(Simple.class); From 903f3705e0f73f66c63efa1cb7ad08f1b80e5693 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Wed, 7 Jul 2021 15:53:23 +1200 Subject: [PATCH 0179/1323] #31 - Tidy related javadoc --- .../java/io/avaje/http/client/HttpClientContext.java | 12 ++++-------- .../io/avaje/http/client/JacksonBodyAdapter.java | 2 +- .../main/java/io/avaje/http/client/package-info.java | 2 +- 3 files changed, 6 insertions(+), 10 deletions(-) diff --git a/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java b/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java index 9d16c57df..70224b5f8 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java +++ b/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java @@ -17,8 +17,7 @@ * * HttpClientContext ctx = HttpClientContext.newBuilder() * .baseUrl("http://localhost:8080") - * .requestListener(new RequestLogger()) - * .bodyAdapter(new JacksonBodyAdapter(new ObjectMapper())) + * .bodyAdapter(new JacksonBodyAdapter()) * .build(); * * HelloDto dto = ctx.request() @@ -39,8 +38,7 @@ public interface HttpClientContext { * * HttpClientContext ctx = HttpClientContext.newBuilder() * .baseUrl("http://localhost:8080") - * .requestListener(new RequestLogger()) - * .bodyAdapter(new JacksonBodyAdapter(new ObjectMapper())) + * .bodyAdapter(new JacksonBodyAdapter()) * .build(); * * HttpResponse res = ctx.request() @@ -124,8 +122,7 @@ static HttpClientContext.Builder newBuilder() { * * HttpClientContext ctx = HttpClientContext.newBuilder() * .baseUrl("http://localhost:8080") - * .requestListener(new RequestLogger()) - * .bodyAdapter(new JacksonBodyAdapter(new ObjectMapper())) + * .bodyAdapter(new JacksonBodyAdapter()) * .build(); * * HelloDto dto = ctx.request() @@ -298,8 +295,7 @@ interface Builder { * * HttpClientContext ctx = HttpClientContext.newBuilder() * .baseUrl("http://localhost:8080") - * .requestListener(new RequestLogger()) - * .bodyAdapter(new JacksonBodyAdapter(new ObjectMapper())) + * .bodyAdapter(new JacksonBodyAdapter()) * .build(); * * HelloDto dto = ctx.request() diff --git a/http-client/client/src/main/java/io/avaje/http/client/JacksonBodyAdapter.java b/http-client/client/src/main/java/io/avaje/http/client/JacksonBodyAdapter.java index fc03882c4..a6c959dac 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/JacksonBodyAdapter.java +++ b/http-client/client/src/main/java/io/avaje/http/client/JacksonBodyAdapter.java @@ -16,7 +16,7 @@ * * HttpClientContext.newBuilder() * .baseUrl(baseUrl) - * .bodyAdapter(new JacksonBodyAdapter(new ObjectMapper())) + * .bodyAdapter(new JacksonBodyAdapter()) * .build(); * * }

diff --git a/http-client/client/src/main/java/io/avaje/http/client/package-info.java b/http-client/client/src/main/java/io/avaje/http/client/package-info.java index 4acea8f16..466ded249 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/package-info.java +++ b/http-client/client/src/main/java/io/avaje/http/client/package-info.java @@ -8,7 +8,7 @@ * * HttpClientContext ctx = HttpClientContext.newBuilder() * .baseUrl("http://localhost:8080") - * .bodyAdapter(new JacksonBodyAdapter(new ObjectMapper())) + * .bodyAdapter(new JacksonBodyAdapter()) * .build(); * * HelloDto dto = ctx.request() From 11b669598761c95b75662220cd13584077050e8c Mon Sep 17 00:00:00 2001 From: rbygrave Date: Wed, 7 Jul 2021 16:05:33 +1200 Subject: [PATCH 0180/1323] #31 - Tidy related javadoc --- .../io/avaje/http/client/HttpClientContext.java | 13 +++++++------ .../java/io/avaje/http/client/RequestLogger.java | 8 ++++++++ 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java b/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java index 70224b5f8..6ef3a27e7 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java +++ b/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java @@ -172,15 +172,16 @@ interface Builder { * Disable or enable built in request and response logging. *

* By default request logging is enabled. Set this to false to stop - * the default {@link RequestLogger} being registered to log - * request and response headers and bodies etc. + * the default {@link RequestLogger} being registered to log request + * and response headers and bodies etc. *

* With logging level set to {@code DEBUG} for - * {@code io.avaje.http.client.RequestLogger} the request and - * response are logged with headers only. + * {@code io.avaje.http.client.RequestLogger} the request and response + * are logged as a summary with response status and time. *

* Set the logging level to {@code TRACE} to include the request - * and response body payloads (with truncation for large bodies). + * and response headers and body payloads with truncation for large + * bodies. * *

Suppression

*

@@ -190,7 +191,7 @@ interface Builder { * Logging of Authorization headers is suppressed. * {@link AuthTokenProvider} requests are suppressed. * - * @param requestLogging To turn disable/enable the registration of the default logger + * @param requestLogging Disable/enable the registration of the default logger * @see RequestLogger */ Builder requestLogging(boolean requestLogging); diff --git a/http-client/client/src/main/java/io/avaje/http/client/RequestLogger.java b/http-client/client/src/main/java/io/avaje/http/client/RequestLogger.java index 31bc8deef..48b8a53b9 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/RequestLogger.java +++ b/http-client/client/src/main/java/io/avaje/http/client/RequestLogger.java @@ -16,6 +16,14 @@ * This implementation logs the request and response with the same * single logging entry rather than separate logging of the request * and response. + *

+ * With logging level set to {@code DEBUG} for + * {@code io.avaje.http.client.RequestLogger} the request and response + * are logged as a summary with response status and time. + *

+ * Set the logging level to {@code TRACE} to include the request + * and response headers and body payloads with truncation for large + * bodies. */ public class RequestLogger implements RequestListener { From 4ed546e9bd455c37de1f5cdcfcc858fbe3bc99f4 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Wed, 7 Jul 2021 16:57:34 +1200 Subject: [PATCH 0181/1323] Update javadoc to use 2XX range terminology --- .../io/avaje/http/client/HttpAsyncResponse.java | 15 ++++++--------- .../io/avaje/http/client/HttpCallResponse.java | 15 ++++++--------- .../io/avaje/http/client/HttpClientResponse.java | 15 ++++++--------- 3 files changed, 18 insertions(+), 27 deletions(-) diff --git a/http-client/client/src/main/java/io/avaje/http/client/HttpAsyncResponse.java b/http-client/client/src/main/java/io/avaje/http/client/HttpAsyncResponse.java index ebf4159f9..2d4de6852 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/HttpAsyncResponse.java +++ b/http-client/client/src/main/java/io/avaje/http/client/HttpAsyncResponse.java @@ -177,9 +177,8 @@ public interface HttpAsyncResponse { /** * Process expecting a bean response body (typically from json content). *

- * If the HTTP statusCode is 300 or above a HttpException is throw which contains - * the HttpResponse. This is the cause in the CompletionException. Redirects are - * by default followed apart from HTTPS to HTTP. + * If the HTTP statusCode is not in the 2XX range a HttpException is throw which contains + * the HttpResponse. This is the cause in the CompletionException. * *

{@code
    *
@@ -212,9 +211,8 @@ public interface HttpAsyncResponse {
   /**
    * Process expecting a list of beans response body (typically from json content).
    * 

- * If the HTTP statusCode is 300 or above a HttpException is throw which contains - * the HttpResponse. This is the cause in the CompletionException. Redirects are - * by default followed apart from HTTPS to HTTP. + * If the HTTP statusCode is not in the 2XX range a HttpException is throw which contains + * the HttpResponse. This is the cause in the CompletionException. * *

{@code
    *
@@ -252,9 +250,8 @@ public interface HttpAsyncResponse {
    * may not be available at the time of the callback. As such {@link RequestLogger}
    * will not include response content in logging stream request/response.
    * 

- * If the HTTP statusCode is 300 or above a HttpException is throw which contains - * the HttpResponse. This is the cause in the CompletionException. Redirects are - * by default followed apart from HTTPS to HTTP. + * If the HTTP statusCode is not in the 2XX range a HttpException is throw which contains + * the HttpResponse. This is the cause in the CompletionException. * *

{@code
    *
diff --git a/http-client/client/src/main/java/io/avaje/http/client/HttpCallResponse.java b/http-client/client/src/main/java/io/avaje/http/client/HttpCallResponse.java
index dec31adb4..840c952f4 100644
--- a/http-client/client/src/main/java/io/avaje/http/client/HttpCallResponse.java
+++ b/http-client/client/src/main/java/io/avaje/http/client/HttpCallResponse.java
@@ -120,9 +120,8 @@ public interface HttpCallResponse {
   /**
    * A bean response to execute async or sync.
    * 

- * If the HTTP statusCode is 300 or above a HttpException is throw which contains - * the HttpResponse. This is the cause in the CompletionException. Redirects are - * by default followed apart from HTTPS to HTTP. + * If the HTTP statusCode is not in the 2XX range a HttpException is throw which contains + * the HttpResponse. This is the cause in the CompletionException. * *

{@code
    *
@@ -142,9 +141,8 @@ public interface HttpCallResponse {
   /**
    * Process expecting a list of beans response body (typically from json content).
    * 

- * If the HTTP statusCode is 300 or above a HttpException is throw which contains - * the HttpResponse. This is the cause in the CompletionException. Redirects are - * by default followed apart from HTTPS to HTTP. + * If the HTTP statusCode is not in the 2XX range a HttpException is throw which contains + * the HttpResponse. This is the cause in the CompletionException. * *

{@code
    *
@@ -163,9 +161,8 @@ public interface HttpCallResponse {
   /**
    * Process expecting a stream of beans response body (typically from json content).
    * 

- * If the HTTP statusCode is 300 or above a HttpException is throw which contains - * the HttpResponse. This is the cause in the CompletionException. Redirects are - * by default followed apart from HTTPS to HTTP. + * If the HTTP statusCode is not in the 2XX range a HttpException is throw which contains + * the HttpResponse. This is the cause in the CompletionException. * *

{@code
    *
diff --git a/http-client/client/src/main/java/io/avaje/http/client/HttpClientResponse.java b/http-client/client/src/main/java/io/avaje/http/client/HttpClientResponse.java
index afc8ff5aa..67e1ee8bd 100644
--- a/http-client/client/src/main/java/io/avaje/http/client/HttpClientResponse.java
+++ b/http-client/client/src/main/java/io/avaje/http/client/HttpClientResponse.java
@@ -36,9 +36,8 @@ public interface HttpClientResponse {
   /**
    * Return the response as a single bean.
    * 

- * If the HTTP statusCode is 300 or above a HttpException is throw which contains - * the HttpResponse. This is the cause in the CompletionException. Redirects are - * by default followed apart from HTTPS to HTTP. + * If the HTTP statusCode is not in the 2XX range a HttpException is throw which contains + * the HttpResponse. This is the cause in the CompletionException. * * @param type The type of the bean to convert the response content into. * @param The type that the content is converted to. @@ -50,9 +49,8 @@ public interface HttpClientResponse { /** * Return the response as a list of beans. *

- * If the HTTP statusCode is 300 or above a HttpException is throw which contains - * the HttpResponse. This is the cause in the CompletionException. Redirects are - * by default followed apart from HTTPS to HTTP. + * If the HTTP statusCode is not in the 2XX range a HttpException is throw which contains + * the HttpResponse. This is the cause in the CompletionException. * * @param type The type of the bean to convert the response content into. * @param The type that the content is converted to. @@ -72,9 +70,8 @@ public interface HttpClientResponse { * may not be available at the time of the callback. As such {@link RequestLogger} * will not include response content when logging stream request/response *

- * If the HTTP statusCode is 300 or above a HttpException is throw which contains - * the HttpResponse. This is the cause in the CompletionException. Redirects are - * by default followed apart from HTTPS to HTTP. + * If the HTTP statusCode is not in the 2XX range a HttpException is throw which contains + * the HttpResponse. This is the cause in the CompletionException. * * @param type The type of the bean to convert the response content into. * @param The type that the content is converted to. From 7cba19a4da2cf25221455e27c6f8c9027c652056 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Wed, 7 Jul 2021 19:19:09 +1200 Subject: [PATCH 0182/1323] javadoc fix getStatusCode() -> statusCode() --- .../main/java/io/avaje/http/client/HttpAsyncResponse.java | 6 +++--- .../src/main/java/io/avaje/http/client/HttpException.java | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/http-client/client/src/main/java/io/avaje/http/client/HttpAsyncResponse.java b/http-client/client/src/main/java/io/avaje/http/client/HttpAsyncResponse.java index 2d4de6852..8cfc213c4 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/HttpAsyncResponse.java +++ b/http-client/client/src/main/java/io/avaje/http/client/HttpAsyncResponse.java @@ -40,7 +40,7 @@ public interface HttpAsyncResponse { * * // if throwable.getCause() is a HttpException for status code >= 300 * HttpException httpException = (HttpException) throwable.getCause(); - * int status = httpException.getStatusCode(); + * int status = httpException.statusCode(); * * // convert json error response body to a bean * ErrorResponse errorResponse = httpException.bean(ErrorResponse.class); @@ -190,7 +190,7 @@ public interface HttpAsyncResponse { * * if (throwable != null) { * HttpException httpException = (HttpException) throwable.getCause(); - * int statusCode = httpException.getStatusCode(); + * int statusCode = httpException.statusCode(); * * // maybe convert json error response body to a bean (using Jackson/Gson) * MyErrorBean errorResponse = httpException.bean(MyErrorBean.class); @@ -224,7 +224,7 @@ public interface HttpAsyncResponse { * * if (throwable != null) { * HttpException httpException = (HttpException) throwable.getCause(); - * int statusCode = httpException.getStatusCode(); + * int statusCode = httpException.statusCode(); * ... * * } else { diff --git a/http-client/client/src/main/java/io/avaje/http/client/HttpException.java b/http-client/client/src/main/java/io/avaje/http/client/HttpException.java index 89cc96728..fe0fbdb39 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/HttpException.java +++ b/http-client/client/src/main/java/io/avaje/http/client/HttpException.java @@ -23,9 +23,9 @@ * } catch (HttpException e) { * * // obtain the statusCode from the exception ... - * int statusCode = e.getStatusCode()); + * int statusCode = e.statusCode()); * - * HttpResponse httpResponse = e.getHttpResponse(); + * HttpResponse httpResponse = e.httpResponse(); * * // obtain the statusCode from httpResponse ... * int statusCode = httpResponse.statusCode(); From c270842085ea562d7bbbbccf8ac2e6c3a112719e Mon Sep 17 00:00:00 2001 From: rbygrave Date: Wed, 7 Jul 2021 19:21:01 +1200 Subject: [PATCH 0183/1323] [maven-release-plugin] prepare release avaje-http-client-1.9 --- http-client/client/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/http-client/client/pom.xml b/http-client/client/pom.xml index 8dd48daab..440cb6d12 100644 --- a/http-client/client/pom.xml +++ b/http-client/client/pom.xml @@ -9,11 +9,11 @@ io.avaje avaje-http-client - 1.9-SNAPSHOT + 1.9 scm:git:git@github.com:avaje/avaje-http-client.git - HEAD + avaje-http-client-1.9 From c8489504cf9ab8214c10c5dbb87796d194503636 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Wed, 7 Jul 2021 19:21:11 +1200 Subject: [PATCH 0184/1323] [maven-release-plugin] prepare for next development iteration --- http-client/client/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/http-client/client/pom.xml b/http-client/client/pom.xml index 440cb6d12..264cdcdcc 100644 --- a/http-client/client/pom.xml +++ b/http-client/client/pom.xml @@ -9,11 +9,11 @@ io.avaje avaje-http-client - 1.9 + 1.10-SNAPSHOT scm:git:git@github.com:avaje/avaje-http-client.git - avaje-http-client-1.9 + HEAD From 85e19fa2721b7295b7a9944b4ba282e4d08c47a5 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Wed, 7 Jul 2021 19:27:23 +1200 Subject: [PATCH 0185/1323] bump gson-adapter to 1.9 --- http-client/gson-adapter/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/http-client/gson-adapter/pom.xml b/http-client/gson-adapter/pom.xml index ef02f24d4..10005a1dc 100644 --- a/http-client/gson-adapter/pom.xml +++ b/http-client/gson-adapter/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-client-gson - 1.8 + 1.9 scm:git:git@github.com:avaje/avaje-http-client.git @@ -27,7 +27,7 @@ io.avaje avaje-http-client - 1.8 + 1.9 provided From b50e035332996a072fd5627c099fbd81916055d4 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Wed, 7 Jul 2021 19:40:31 +1200 Subject: [PATCH 0186/1323] bump test pom versions --- .../main/java/io/avaje/http/client/HttpClientContext.java | 6 +++--- .../main/java/io/avaje/http/client/HttpClientRequest.java | 2 +- .../src/main/java/io/avaje/http/client/package-info.java | 2 +- http-client/test/pom.xml | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java b/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java index 6ef3a27e7..139c63b95 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java +++ b/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java @@ -23,7 +23,7 @@ * HelloDto dto = ctx.request() * .path("hello") * .queryParam("name", "Rob") - * .queryParam("say", "Ki ora") + * .queryParam("say", "Whats up") * .GET() * .bean(HelloDto.class); * @@ -128,7 +128,7 @@ static HttpClientContext.Builder newBuilder() { * HelloDto dto = ctx.request() * .path("hello") * .queryParam("name", "Rob") - * .queryParam("say", "Ki ora") + * .queryParam("say", "Whats up") * .GET() * .bean(HelloDto.class); * @@ -301,7 +301,7 @@ interface Builder { * * HelloDto dto = ctx.request() * .path("hello") - * .queryParam("say", "Ki ora") + * .queryParam("say", "Whats up") * .GET() * .bean(HelloDto.class); * diff --git a/http-client/client/src/main/java/io/avaje/http/client/HttpClientRequest.java b/http-client/client/src/main/java/io/avaje/http/client/HttpClientRequest.java index 3a61fe773..c837b7344 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/HttpClientRequest.java +++ b/http-client/client/src/main/java/io/avaje/http/client/HttpClientRequest.java @@ -19,7 +19,7 @@ *

{@code
  *
  *  HelloDto dto = clientContext.request()
- *       .path("hello").queryParam("name", "Rob").queryParam("say", "Ki ora")
+ *       .path("hello").queryParam("name", "Rob").queryParam("say", "Whats up")
  *       .GET()
  *       .bean(HelloDto.class);
  *
diff --git a/http-client/client/src/main/java/io/avaje/http/client/package-info.java b/http-client/client/src/main/java/io/avaje/http/client/package-info.java
index 466ded249..dd19ed7da 100644
--- a/http-client/client/src/main/java/io/avaje/http/client/package-info.java
+++ b/http-client/client/src/main/java/io/avaje/http/client/package-info.java
@@ -13,7 +13,7 @@
  *
  *  HelloDto dto = ctx.request()
  *       .path("hello")
- *       .queryParam("say", "Ki ora")
+ *       .queryParam("say", "Whats up")
  *       .GET()
  *       .bean(HelloDto.class);
  *
diff --git a/http-client/test/pom.xml b/http-client/test/pom.xml
index 5c1816b93..194f7a1ef 100644
--- a/http-client/test/pom.xml
+++ b/http-client/test/pom.xml
@@ -16,13 +16,13 @@
     
       io.avaje
       avaje-http-client
-      1.9-SNAPSHOT
+      1.10-SNAPSHOT
     
 
     
       io.avaje
       avaje-http-client-gson
-      1.8
+      1.9
     
 
     

From dcb4be3ec4fc68410c3749da7d5abd2878886dd8 Mon Sep 17 00:00:00 2001
From: rbygrave 
Date: Wed, 7 Jul 2021 19:43:35 +1200
Subject: [PATCH 0187/1323] Bump avaje-http-client to 1.9

---
 tests/test-client/pom.xml                         |  2 +-
 .../src/main/java/org/example/JunkApi.java        | 10 +++++++++-
 .../src/test/java/org/example/CommonApiTest.java  |  8 ++------
 .../src/test/java/org/example/SimpleTest.java     |  5 ++---
 tests/test-helidon/pom.xml                        |  2 +-
 .../src/test/java/org/example/BaseWebTest.java    |  6 ++----
 tests/test-javalin/pom.xml                        |  2 +-
 .../test/java/org/example/myapp/BaseWebTest.java  |  6 ++----
 .../org/example/myapp/HelloControllerTest.java    | 15 ++++-----------
 tests/test-jex/pom.xml                            |  2 +-
 .../test/java/org/example/web/BaseWebTest.java    |  7 +++----
 tests/test-spark/pom.xml                          |  2 +-
 12 files changed, 29 insertions(+), 38 deletions(-)

diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml
index 09d42e655..83a7c12da 100644
--- a/tests/test-client/pom.xml
+++ b/tests/test-client/pom.xml
@@ -30,7 +30,7 @@
     
       io.avaje
       avaje-http-client
-      1.9-SNAPSHOT
+      1.9
     
 
     
diff --git a/tests/test-client/src/main/java/org/example/JunkApi.java b/tests/test-client/src/main/java/org/example/JunkApi.java
index bcc41e58b..bfdf1990b 100644
--- a/tests/test-client/src/main/java/org/example/JunkApi.java
+++ b/tests/test-client/src/main/java/org/example/JunkApi.java
@@ -121,6 +121,14 @@ public interface JunkApi {
   HttpCall> callWithHandPath(HttpResponse.BodyHandler handler);
 
   @Post("/{id}/foo/{name}")
-  HttpResponse reqBodyResHand2(HttpResponse.BodyHandler handler, HttpRequest.BodyPublisher body, String id, String name, String other);
+  HttpResponse postWithBody(String id, String name, HttpRequest.BodyPublisher body, String other);
+
+  @Get("/{id}")
+  HttpResponse getWithHandler(String id, HttpResponse.BodyHandler myHandler, String other);
+
+  @Get("/{id}")
+   HttpResponse getWithGeneralHandler(String id, HttpResponse.BodyHandler myHandler);
 
+  @Post("/{id}/foo/{name}")
+  HttpResponse reqBodyResHand2(HttpResponse.BodyHandler handler, HttpRequest.BodyPublisher body, String id, String name, String other);
 }
diff --git a/tests/test-client/src/test/java/org/example/CommonApiTest.java b/tests/test-client/src/test/java/org/example/CommonApiTest.java
index 511169977..c51eaa0b9 100644
--- a/tests/test-client/src/test/java/org/example/CommonApiTest.java
+++ b/tests/test-client/src/test/java/org/example/CommonApiTest.java
@@ -24,13 +24,9 @@ static void start() {
     final int port = new Random().nextInt(1000) + 10_000;
     Main.start(port);
 
-    ObjectMapper objectMapper = new ObjectMapper()
-      .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
-
     final HttpClientContext clientContext = HttpClientContext.newBuilder()
-      .withBaseUrl("http://localhost:" + port)
-      .withRequestListener(new RequestLogger())
-      .withBodyAdapter(new JacksonBodyAdapter(objectMapper))
+      .baseUrl("http://localhost:" + port)
+      .bodyAdapter(new JacksonBodyAdapter())
       .build();
 
     client = clientContext.create(CommonApi.class);
diff --git a/tests/test-client/src/test/java/org/example/SimpleTest.java b/tests/test-client/src/test/java/org/example/SimpleTest.java
index 98e916fca..d3e4d7575 100644
--- a/tests/test-client/src/test/java/org/example/SimpleTest.java
+++ b/tests/test-client/src/test/java/org/example/SimpleTest.java
@@ -25,9 +25,8 @@ void listRepos() {
 
     final HttpClientContext clientContext =
       HttpClientContext.newBuilder()
-        .withBaseUrl("https://api.github.com")
-        .withRequestListener(new RequestLogger())
-        .withBodyAdapter(new JacksonBodyAdapter(objectMapper))
+        .baseUrl("https://api.github.com")
+        .bodyAdapter(new JacksonBodyAdapter(objectMapper))
         .build();
 
     GitHubUsers simple = clientContext.create(GitHubUsers.class);
diff --git a/tests/test-helidon/pom.xml b/tests/test-helidon/pom.xml
index c1979432c..33408e246 100644
--- a/tests/test-helidon/pom.xml
+++ b/tests/test-helidon/pom.xml
@@ -115,7 +115,7 @@
     
       io.avaje
       avaje-http-client
-      1.7
+      1.9
       test
     
 
diff --git a/tests/test-helidon/src/test/java/org/example/BaseWebTest.java b/tests/test-helidon/src/test/java/org/example/BaseWebTest.java
index 3a62075c9..fdbad0eea 100644
--- a/tests/test-helidon/src/test/java/org/example/BaseWebTest.java
+++ b/tests/test-helidon/src/test/java/org/example/BaseWebTest.java
@@ -27,10 +27,8 @@ public static void shutdown() {
 
   public static HttpClientContext client() {
     return HttpClientContext.newBuilder()
-      .withBaseUrl(baseUrl)
-      .withRequestListener(new RequestLogger())
-      .withBodyAdapter(new JacksonBodyAdapter(new ObjectMapper()))
-      //.with(httpClient)
+      .baseUrl(baseUrl)
+      .bodyAdapter(new JacksonBodyAdapter())
       .build();
   }
 }
diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml
index f2749b232..52e2d6057 100644
--- a/tests/test-javalin/pom.xml
+++ b/tests/test-javalin/pom.xml
@@ -108,7 +108,7 @@
     
       io.avaje
       avaje-http-client
-      1.7
+      1.9
       test
     
 
diff --git a/tests/test-javalin/src/test/java/org/example/myapp/BaseWebTest.java b/tests/test-javalin/src/test/java/org/example/myapp/BaseWebTest.java
index 020a5e4a6..263662051 100644
--- a/tests/test-javalin/src/test/java/org/example/myapp/BaseWebTest.java
+++ b/tests/test-javalin/src/test/java/org/example/myapp/BaseWebTest.java
@@ -27,10 +27,8 @@ public static void shutdown() {
 
   public static HttpClientContext client() {
     return HttpClientContext.newBuilder()
-      .withBaseUrl(baseUrl)
-      .withRequestListener(new RequestLogger())
-      .withBodyAdapter(new JacksonBodyAdapter(new ObjectMapper()))
-      //.with(httpClient)
+      .baseUrl(baseUrl)
+      .bodyAdapter(new JacksonBodyAdapter())
       .build();
   }
 }
diff --git a/tests/test-javalin/src/test/java/org/example/myapp/HelloControllerTest.java b/tests/test-javalin/src/test/java/org/example/myapp/HelloControllerTest.java
index 32ce0754c..2bf6ae1c7 100644
--- a/tests/test-javalin/src/test/java/org/example/myapp/HelloControllerTest.java
+++ b/tests/test-javalin/src/test/java/org/example/myapp/HelloControllerTest.java
@@ -1,12 +1,6 @@
 package org.example.myapp;
 
-import com.fasterxml.jackson.databind.ObjectMapper;
-import io.avaje.http.client.BodyReader;
-import io.avaje.http.client.BodyWriter;
-import io.avaje.http.client.HttpClientContext;
-import io.avaje.http.client.HttpException;
-import io.avaje.http.client.JacksonBodyAdapter;
-import io.avaje.http.client.RequestLogger;
+import io.avaje.http.client.*;
 import io.restassured.common.mapper.TypeRef;
 import io.restassured.http.ContentType;
 import io.restassured.response.Response;
@@ -35,10 +29,9 @@ class HelloControllerTest extends BaseWebTest {
       .build();
 
     this.clientContext = HttpClientContext.newBuilder()
-      .withBaseUrl(baseUrl)
-      .withRequestListener(new RequestLogger())
-      .withBodyAdapter(new JacksonBodyAdapter(new ObjectMapper()))
-      .with(httpClient)
+      .baseUrl(baseUrl)
+      .bodyAdapter(new JacksonBodyAdapter())
+      .client(httpClient)
       .build();
   }
 
diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml
index 326dc2d3f..2934429ae 100644
--- a/tests/test-jex/pom.xml
+++ b/tests/test-jex/pom.xml
@@ -95,7 +95,7 @@
     
       io.avaje
       avaje-http-client
-      1.7
+      1.9
       test
     
 
diff --git a/tests/test-jex/src/test/java/org/example/web/BaseWebTest.java b/tests/test-jex/src/test/java/org/example/web/BaseWebTest.java
index 79ef6e747..c3c4c1b35 100644
--- a/tests/test-jex/src/test/java/org/example/web/BaseWebTest.java
+++ b/tests/test-jex/src/test/java/org/example/web/BaseWebTest.java
@@ -30,10 +30,9 @@ public static void shutdown() {
 
   public static HttpClientContext client() {
     return HttpClientContext.newBuilder()
-      .withBaseUrl(baseUrl)
-      .withRequestTimeout(Duration.ofMinutes(2))
-      .withRequestListener(new RequestLogger())
-      .withBodyAdapter(new JacksonBodyAdapter(new ObjectMapper()))
+      .baseUrl(baseUrl)
+      .requestTimeout(Duration.ofMinutes(2))
+      .bodyAdapter(new JacksonBodyAdapter())
       .build();
   }
 }
diff --git a/tests/test-spark/pom.xml b/tests/test-spark/pom.xml
index 8a2146642..fbf89db3e 100644
--- a/tests/test-spark/pom.xml
+++ b/tests/test-spark/pom.xml
@@ -93,7 +93,7 @@
     
       io.avaje
       avaje-http-client
-      1.7
+      1.9
       test
     
 

From 2a91857d3bf7509c59b7106a0bad1bec35fe1ef7 Mon Sep 17 00:00:00 2001
From: rbygrave 
Date: Wed, 7 Jul 2021 20:48:46 +1200
Subject: [PATCH 0188/1323] #64 - [client generation] Generate services file
 and HttpApiProvider inner class

---
 .../generator/client/ClientProcessor.java     | 32 +++++++++++++++----
 .../http/generator/client/ClientWriter.java   | 20 +++++++++++-
 .../generator/core/ProcessingContext.java     | 10 +++++-
 3 files changed, 54 insertions(+), 8 deletions(-)

diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java
index 9419e9784..376e7af94 100644
--- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java
+++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java
@@ -12,13 +12,19 @@
 import javax.lang.model.element.AnnotationValue;
 import javax.lang.model.element.Element;
 import javax.lang.model.element.TypeElement;
+import javax.tools.FileObject;
 import java.io.IOException;
+import java.io.Writer;
 import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Set;
 
 public class ClientProcessor extends AbstractProcessor {
 
+  private static final String METAINF_SERVICES_PROVIDER = "META-INF/services/io.avaje.http.client.HttpApiProvider";
+
+  private final Set generatedClients = new LinkedHashSet<>();
+
   protected ProcessingContext ctx;
 
   @Override
@@ -49,15 +55,30 @@ public boolean process(Set annotations, RoundEnvironment
     for (Element importedElement : round.getElementsAnnotatedWith(Client.Import.class)) {
       writeForImported(importedElement);
     }
+    if (round.processingOver()) {
+      writeServicesFile();
+    }
     return false;
   }
 
+  private void writeServicesFile() {
+    try {
+      final FileObject metaInfWriter = ctx.createMetaInfWriter(METAINF_SERVICES_PROVIDER);
+      final Writer writer = metaInfWriter.openWriter();
+      for (String generatedClient : generatedClients) {
+        writer.append(generatedClient).append("$Provider\n");
+      }
+      writer.close();
+    } catch (IOException e) {
+      ctx.logError(null, "Error writing services file " + e, e);
+    }
+  }
+
   private void writeForImported(Element importedElement) {
     for (AnnotationMirror annotationMirror : importedElement.getAnnotationMirrors()) {
       for (AnnotationValue value : annotationMirror.getElementValues().values()) {
         for (Object apiClassDef : (List) value.getValue()) {
-          String fullName = apiClassDef.toString();
-          writeImported(fullName);
+          writeImported(apiClassDef.toString());
         }
       }
     }
@@ -66,7 +87,6 @@ private void writeForImported(Element importedElement) {
   private void writeImported(String fullName) {
     // trim .class suffix
     String apiClassName = fullName.substring(0, fullName.length() - 6);
-    //ctx.logError(null, "build import:" + apiClassName);
     TypeElement typeElement = ctx.getTypeElement(apiClassName);
     if (typeElement != null) {
       writeClient(typeElement);
@@ -78,7 +98,7 @@ private void writeClient(Element controller) {
       ControllerReader reader = new ControllerReader((TypeElement) controller, ctx);
       reader.read(false);
       try {
-        writeClientAdapter(ctx, reader);
+        generatedClients.add(writeClientAdapter(ctx, reader));
       } catch (Throwable e) {
         e.printStackTrace();
         ctx.logError(reader.getBeanType(), "Failed to write client class " + e);
@@ -86,8 +106,8 @@ private void writeClient(Element controller) {
     }
   }
 
-  protected void writeClientAdapter(ProcessingContext ctx, ControllerReader reader) throws IOException {
-    new ClientWriter(reader, ctx).write();
+  protected String writeClientAdapter(ProcessingContext ctx, ControllerReader reader) throws IOException {
+    return new ClientWriter(reader, ctx).write();
   }
 
 }
diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientWriter.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientWriter.java
index 5af21ed7f..ba701f598 100644
--- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientWriter.java
+++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientWriter.java
@@ -15,6 +15,8 @@
 class ClientWriter extends BaseControllerWriter {
 
   private static final String HTTP_CLIENT_CONTEXT = "io.avaje.http.client.HttpClientContext";
+  private static final String HTTP_API_PROVIDER = "io.avaje.http.client.HttpApiProvider";
+
   private static final String AT_GENERATED = "@Generated(\"avaje-http-client-generator\")";
   private static final String SUFFIX = "$HttpClient";
 
@@ -23,6 +25,7 @@ class ClientWriter extends BaseControllerWriter {
   ClientWriter(ControllerReader reader, ProcessingContext ctx) throws IOException {
     super(reader, ctx, SUFFIX);
     reader.addImportType(HTTP_CLIENT_CONTEXT);
+    reader.addImportType(HTTP_API_PROVIDER);
     readMethods();
   }
 
@@ -42,12 +45,27 @@ private void readMethods() {
     }
   }
 
-  void write() {
+  String write() {
     writePackage();
     writeImports();
     writeClassStart();
     writeMethods();
+    writeProvider();
     writeClassEnd();
+    return fullName;
+  }
+
+  private void writeProvider() {
+    writer.append("  public static class Provider implements HttpApiProvider<%s> {", shortName).eol();
+    writer.append("    @Override").eol();
+    writer.append("    public Class<%s> type() {", shortName).eol();
+    writer.append("      return %s.class;", shortName).eol();
+    writer.append("    }").eol();
+    writer.append("    @Override").eol();
+    writer.append("    public %s provide(HttpClientContext client) {", shortName).eol();
+    writer.append("      return new %s$HttpClient(client);", shortName).eol();
+    writer.append("    }").eol();
+    writer.append("  }").eol();
   }
 
   private void writeMethods() {
diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java
index 99bd6f646..f00175337 100644
--- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java
+++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java
@@ -5,7 +5,6 @@
 import javax.annotation.processing.Filer;
 import javax.annotation.processing.Messager;
 import javax.annotation.processing.ProcessingEnvironment;
-import javax.lang.model.SourceVersion;
 import javax.lang.model.element.Element;
 import javax.lang.model.element.TypeElement;
 import javax.lang.model.type.DeclaredType;
@@ -13,7 +12,9 @@
 import javax.lang.model.util.Elements;
 import javax.lang.model.util.Types;
 import javax.tools.Diagnostic;
+import javax.tools.FileObject;
 import javax.tools.JavaFileObject;
+import javax.tools.StandardLocation;
 import java.io.IOException;
 
 public class ProcessingContext {
@@ -59,6 +60,13 @@ public JavaFileObject createWriter(String cls, Element origin) throws IOExceptio
     return filer.createSourceFile(cls, origin);
   }
 
+  /**
+   * Create a file writer for the META-INF services file.
+   */
+  public FileObject createMetaInfWriter(String target) throws IOException {
+    return filer.createResource(StandardLocation.CLASS_OUTPUT, "", target);
+  }
+
   public String getDocComment(Element param) {
     return elements.getDocComment(param);
   }

From 1d1f55ce1a45f8dc3fc82f4e3506eb4def09e274 Mon Sep 17 00:00:00 2001
From: rbygrave 
Date: Wed, 7 Jul 2021 23:01:19 +1200
Subject: [PATCH 0189/1323] Bump to 1.9-SNAPSHOT to align to avaje-http-client

---
 http-api/pom.xml               | 2 +-
 http-generator-client/pom.xml  | 2 +-
 http-generator-core/pom.xml    | 4 ++--
 http-generator-helidon/pom.xml | 2 +-
 http-generator-javalin/pom.xml | 2 +-
 http-generator-jex/pom.xml     | 2 +-
 pom.xml                        | 2 +-
 tests/test-client/pom.xml      | 6 +++---
 tests/test-helidon/pom.xml     | 2 +-
 tests/test-javalin/pom.xml     | 2 +-
 tests/test-jex/pom.xml         | 2 +-
 tests/test-spark/pom.xml       | 4 ++--
 12 files changed, 16 insertions(+), 16 deletions(-)

diff --git a/http-api/pom.xml b/http-api/pom.xml
index f9ad932de..ee6332a4a 100644
--- a/http-api/pom.xml
+++ b/http-api/pom.xml
@@ -4,7 +4,7 @@
   
     io.avaje
     avaje-http-generator-parent
-    1.8-SNAPSHOT
+    1.9-SNAPSHOT
     ..
   
 
diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml
index 436bf80e6..de2d06259 100644
--- a/http-generator-client/pom.xml
+++ b/http-generator-client/pom.xml
@@ -5,7 +5,7 @@
   
     io.avaje
     avaje-http-generator-parent
-    1.8-SNAPSHOT
+    1.9-SNAPSHOT
     ..
   
 
diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml
index 9a2f929c9..8ef9c23a0 100644
--- a/http-generator-core/pom.xml
+++ b/http-generator-core/pom.xml
@@ -7,7 +7,7 @@
   
     io.avaje
     avaje-http-generator-parent
-    1.8-SNAPSHOT
+    1.9-SNAPSHOT
     ..
   
 
@@ -33,7 +33,7 @@
     
       io.avaje
       avaje-http-api
-      1.8-SNAPSHOT
+      1.9-SNAPSHOT
     
 
     
diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml
index 1e506a1b2..f27d9b2f4 100644
--- a/http-generator-helidon/pom.xml
+++ b/http-generator-helidon/pom.xml
@@ -7,7 +7,7 @@
   
     io.avaje
     avaje-http-generator-parent
-    1.8-SNAPSHOT
+    1.9-SNAPSHOT
     ..
   
 
diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml
index b9ef12c6c..332eddb0a 100644
--- a/http-generator-javalin/pom.xml
+++ b/http-generator-javalin/pom.xml
@@ -7,7 +7,7 @@
   
     io.avaje
     avaje-http-generator-parent
-    1.8-SNAPSHOT
+    1.9-SNAPSHOT
     ..
   
 
diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml
index 4c03d0c9b..2226ed944 100644
--- a/http-generator-jex/pom.xml
+++ b/http-generator-jex/pom.xml
@@ -7,7 +7,7 @@
   
     io.avaje
     avaje-http-generator-parent
-    1.8-SNAPSHOT
+    1.9-SNAPSHOT
     ..
   
 
diff --git a/pom.xml b/pom.xml
index ef7354e27..01b201ee7 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
 
   io.avaje
   avaje-http-generator-parent
-  1.8-SNAPSHOT
+  1.9-SNAPSHOT
   pom
 
   
diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml
index 83a7c12da..61a914e9f 100644
--- a/tests/test-client/pom.xml
+++ b/tests/test-client/pom.xml
@@ -36,7 +36,7 @@
     
       io.avaje
       avaje-http-api
-      1.8-SNAPSHOT
+      1.9-SNAPSHOT
     
 
     
@@ -108,12 +108,12 @@
             
               io.avaje
               avaje-http-client-generator
-              1.8-SNAPSHOT
+              1.9-SNAPSHOT
             
             
               io.avaje
               avaje-http-jex-generator
-              1.8-SNAPSHOT
+              1.9-SNAPSHOT
             
             
               io.avaje
diff --git a/tests/test-helidon/pom.xml b/tests/test-helidon/pom.xml
index 33408e246..6ad43b369 100644
--- a/tests/test-helidon/pom.xml
+++ b/tests/test-helidon/pom.xml
@@ -17,7 +17,7 @@
   
     org.example.Main
     2.3.0
-    1.8-SNAPSHOT
+    1.9-SNAPSHOT
   
 
   
diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml
index 52e2d6057..68842139f 100644
--- a/tests/test-javalin/pom.xml
+++ b/tests/test-javalin/pom.xml
@@ -20,7 +20,7 @@
     2.0.8
     1.3.71
     2.12.3
-    1.8-SNAPSHOT
+    1.9-SNAPSHOT
   
 
   
diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml
index 2934429ae..45750fa3f 100644
--- a/tests/test-jex/pom.xml
+++ b/tests/test-jex/pom.xml
@@ -20,7 +20,7 @@
     2.0.8
     2.12.3
     6.1
-    1.8-SNAPSHOT
+    1.9-SNAPSHOT
   
 
   
diff --git a/tests/test-spark/pom.xml b/tests/test-spark/pom.xml
index fbf89db3e..3015d6eaf 100644
--- a/tests/test-spark/pom.xml
+++ b/tests/test-spark/pom.xml
@@ -17,7 +17,7 @@
   
     org.example.myapp.Main
     2.0.8
-    1.8-SNAPSHOT
+    1.9-SNAPSHOT
   
 
   
@@ -76,7 +76,7 @@
     
       io.avaje
       avaje-http-spark-generator
-      1.8-SNAPSHOT
+      1.9-SNAPSHOT
       provided
     
 

From 89c7defda7bf5c6aa21a39f99a259e0a7a310d5d Mon Sep 17 00:00:00 2001
From: rbygrave 
Date: Wed, 7 Jul 2021 23:03:48 +1200
Subject: [PATCH 0190/1323] Update pom to autoReleaseAfterClose true and bump
 parent pom

---
 pom.xml | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/pom.xml b/pom.xml
index 01b201ee7..4d9069268 100644
--- a/pom.xml
+++ b/pom.xml
@@ -10,7 +10,7 @@
   
     org.avaje
     java8-oss
-    2.3
+    3.1
   
 
   
@@ -19,7 +19,7 @@
   
 
   
-    false
+    true
   
 
   
@@ -39,7 +39,7 @@
     http-generator-jex
     http-generator-helidon
     http-generator-client
-    tests
+
   
 
 

From da094f47b3bd6d9023cca94f8e0e08421f4da8af Mon Sep 17 00:00:00 2001
From: rbygrave 
Date: Wed, 7 Jul 2021 23:04:50 +1200
Subject: [PATCH 0191/1323] [maven-release-plugin] prepare release
 avaje-http-generator-parent-1.9

---
 http-api/pom.xml               | 4 ++--
 http-generator-client/pom.xml  | 2 +-
 http-generator-core/pom.xml    | 4 ++--
 http-generator-helidon/pom.xml | 2 +-
 http-generator-javalin/pom.xml | 2 +-
 http-generator-jex/pom.xml     | 2 +-
 pom.xml                        | 4 ++--
 7 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/http-api/pom.xml b/http-api/pom.xml
index ee6332a4a..1ff3bb930 100644
--- a/http-api/pom.xml
+++ b/http-api/pom.xml
@@ -4,7 +4,7 @@
   
     io.avaje
     avaje-http-generator-parent
-    1.9-SNAPSHOT
+    1.9
     ..
   
 
@@ -20,7 +20,7 @@
 
   
     scm:git:git@github.com:avaje/avaje-http.git
-    HEAD
+    avaje-http-generator-parent-1.9
   
 
   
diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml
index de2d06259..b031d57e8 100644
--- a/http-generator-client/pom.xml
+++ b/http-generator-client/pom.xml
@@ -5,7 +5,7 @@
   
     io.avaje
     avaje-http-generator-parent
-    1.9-SNAPSHOT
+    1.9
     ..
   
 
diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml
index 8ef9c23a0..c1cd95405 100644
--- a/http-generator-core/pom.xml
+++ b/http-generator-core/pom.xml
@@ -7,7 +7,7 @@
   
     io.avaje
     avaje-http-generator-parent
-    1.9-SNAPSHOT
+    1.9
     ..
   
 
@@ -33,7 +33,7 @@
     
       io.avaje
       avaje-http-api
-      1.9-SNAPSHOT
+      1.9
     
 
     
diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml
index f27d9b2f4..bd20358bd 100644
--- a/http-generator-helidon/pom.xml
+++ b/http-generator-helidon/pom.xml
@@ -7,7 +7,7 @@
   
     io.avaje
     avaje-http-generator-parent
-    1.9-SNAPSHOT
+    1.9
     ..
   
 
diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml
index 332eddb0a..293655461 100644
--- a/http-generator-javalin/pom.xml
+++ b/http-generator-javalin/pom.xml
@@ -7,7 +7,7 @@
   
     io.avaje
     avaje-http-generator-parent
-    1.9-SNAPSHOT
+    1.9
     ..
   
 
diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml
index 2226ed944..e847590dc 100644
--- a/http-generator-jex/pom.xml
+++ b/http-generator-jex/pom.xml
@@ -7,7 +7,7 @@
   
     io.avaje
     avaje-http-generator-parent
-    1.9-SNAPSHOT
+    1.9
     ..
   
 
diff --git a/pom.xml b/pom.xml
index 4d9069268..135b8d172 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
 
   io.avaje
   avaje-http-generator-parent
-  1.9-SNAPSHOT
+  1.9
   pom
 
   
@@ -15,7 +15,7 @@
 
   
     scm:git:git@github.com:avaje/avaje-http.git
-    HEAD
+    avaje-http-generator-parent-1.9
   
 
   

From e3c8d23191320e9a44cf186e336f6a5b1d47f7f7 Mon Sep 17 00:00:00 2001
From: rbygrave 
Date: Wed, 7 Jul 2021 23:04:59 +1200
Subject: [PATCH 0192/1323] [maven-release-plugin] prepare for next development
 iteration

---
 http-api/pom.xml               | 4 ++--
 http-generator-client/pom.xml  | 2 +-
 http-generator-core/pom.xml    | 4 ++--
 http-generator-helidon/pom.xml | 2 +-
 http-generator-javalin/pom.xml | 2 +-
 http-generator-jex/pom.xml     | 2 +-
 pom.xml                        | 4 ++--
 7 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/http-api/pom.xml b/http-api/pom.xml
index 1ff3bb930..b6adfeb6b 100644
--- a/http-api/pom.xml
+++ b/http-api/pom.xml
@@ -4,7 +4,7 @@
   
     io.avaje
     avaje-http-generator-parent
-    1.9
+    1.10-SNAPSHOT
     ..
   
 
@@ -20,7 +20,7 @@
 
   
     scm:git:git@github.com:avaje/avaje-http.git
-    avaje-http-generator-parent-1.9
+    HEAD
   
 
   
diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml
index b031d57e8..07dee7b9a 100644
--- a/http-generator-client/pom.xml
+++ b/http-generator-client/pom.xml
@@ -5,7 +5,7 @@
   
     io.avaje
     avaje-http-generator-parent
-    1.9
+    1.10-SNAPSHOT
     ..
   
 
diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml
index c1cd95405..911c7e969 100644
--- a/http-generator-core/pom.xml
+++ b/http-generator-core/pom.xml
@@ -7,7 +7,7 @@
   
     io.avaje
     avaje-http-generator-parent
-    1.9
+    1.10-SNAPSHOT
     ..
   
 
@@ -33,7 +33,7 @@
     
       io.avaje
       avaje-http-api
-      1.9
+      1.10-SNAPSHOT
     
 
     
diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml
index bd20358bd..e1d96854f 100644
--- a/http-generator-helidon/pom.xml
+++ b/http-generator-helidon/pom.xml
@@ -7,7 +7,7 @@
   
     io.avaje
     avaje-http-generator-parent
-    1.9
+    1.10-SNAPSHOT
     ..
   
 
diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml
index 293655461..3e3ff1fc3 100644
--- a/http-generator-javalin/pom.xml
+++ b/http-generator-javalin/pom.xml
@@ -7,7 +7,7 @@
   
     io.avaje
     avaje-http-generator-parent
-    1.9
+    1.10-SNAPSHOT
     ..
   
 
diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml
index e847590dc..f70279b66 100644
--- a/http-generator-jex/pom.xml
+++ b/http-generator-jex/pom.xml
@@ -7,7 +7,7 @@
   
     io.avaje
     avaje-http-generator-parent
-    1.9
+    1.10-SNAPSHOT
     ..
   
 
diff --git a/pom.xml b/pom.xml
index 135b8d172..c877128d4 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
 
   io.avaje
   avaje-http-generator-parent
-  1.9
+  1.10-SNAPSHOT
   pom
 
   
@@ -15,7 +15,7 @@
 
   
     scm:git:git@github.com:avaje/avaje-http.git
-    avaje-http-generator-parent-1.9
+    HEAD
   
 
   

From 39c9cdc7a4390084371990f05d075eb5a4cb30e7 Mon Sep 17 00:00:00 2001
From: rbygrave 
Date: Wed, 7 Jul 2021 23:11:29 +1200
Subject: [PATCH 0193/1323] Update test dependencies after release

---
 pom.xml                    | 2 +-
 tests/test-client/pom.xml  | 6 +++---
 tests/test-helidon/pom.xml | 2 +-
 tests/test-javalin/pom.xml | 2 +-
 tests/test-jex/pom.xml     | 2 +-
 tests/test-spark/pom.xml   | 4 ++--
 6 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/pom.xml b/pom.xml
index c877128d4..75d9f4cf0 100644
--- a/pom.xml
+++ b/pom.xml
@@ -39,7 +39,7 @@
     http-generator-jex
     http-generator-helidon
     http-generator-client
-
+    tests
   
 
 
diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml
index 61a914e9f..a9a5e1d40 100644
--- a/tests/test-client/pom.xml
+++ b/tests/test-client/pom.xml
@@ -36,7 +36,7 @@
     
       io.avaje
       avaje-http-api
-      1.9-SNAPSHOT
+      1.10-SNAPSHOT
     
 
     
@@ -108,12 +108,12 @@
             
               io.avaje
               avaje-http-client-generator
-              1.9-SNAPSHOT
+              1.10-SNAPSHOT
             
             
               io.avaje
               avaje-http-jex-generator
-              1.9-SNAPSHOT
+              1.10-SNAPSHOT
             
             
               io.avaje
diff --git a/tests/test-helidon/pom.xml b/tests/test-helidon/pom.xml
index 6ad43b369..a02f6a47e 100644
--- a/tests/test-helidon/pom.xml
+++ b/tests/test-helidon/pom.xml
@@ -17,7 +17,7 @@
   
     org.example.Main
     2.3.0
-    1.9-SNAPSHOT
+    1.10-SNAPSHOT
   
 
   
diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml
index 68842139f..374edb112 100644
--- a/tests/test-javalin/pom.xml
+++ b/tests/test-javalin/pom.xml
@@ -20,7 +20,7 @@
     2.0.8
     1.3.71
     2.12.3
-    1.9-SNAPSHOT
+    1.10-SNAPSHOT
   
 
   
diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml
index 45750fa3f..2c24219a6 100644
--- a/tests/test-jex/pom.xml
+++ b/tests/test-jex/pom.xml
@@ -20,7 +20,7 @@
     2.0.8
     2.12.3
     6.1
-    1.9-SNAPSHOT
+    1.10-SNAPSHOT
   
 
   
diff --git a/tests/test-spark/pom.xml b/tests/test-spark/pom.xml
index 3015d6eaf..0e9325f4f 100644
--- a/tests/test-spark/pom.xml
+++ b/tests/test-spark/pom.xml
@@ -17,7 +17,7 @@
   
     org.example.myapp.Main
     2.0.8
-    1.9-SNAPSHOT
+    1.10-SNAPSHOT
   
 
   
@@ -76,7 +76,7 @@
     
       io.avaje
       avaje-http-spark-generator
-      1.9-SNAPSHOT
+      1.10-SNAPSHOT
       provided
     
 

From 06af18a67209f900e5a66da249c961b925678402 Mon Sep 17 00:00:00 2001
From: rbygrave 
Date: Thu, 8 Jul 2021 11:51:12 +1200
Subject: [PATCH 0194/1323] #65 - [client api] Bug with @Form @Post with path
 parameter included as formParam()

---
 .../generator/client/ClientMethodWriter.java  | 33 ++++++++++++-------
 .../src/main/java/org/example/JunkApi.java    |  5 +++
 2 files changed, 26 insertions(+), 12 deletions(-)

diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java
index 214466841..3212622b9 100644
--- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java
+++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java
@@ -81,7 +81,7 @@ void write() {
     writeHeaders();
     writePaths(segments);
     writeQueryParams(pathSegments);
-    writeFormParams();
+    writeFormParams(pathSegments);
     writeBody();
 
     WebMethod webMethod = method.getWebMethod();
@@ -174,20 +174,29 @@ private void writeHeaders() {
     }
   }
 
-  private void writeFormParams() {
+  private void writeFormParams(PathSegments segments) {
     for (MethodParam param : method.getParams()) {
+      final String varName = param.getName();
       ParamType paramType = param.getParamType();
-      if (paramType == ParamType.FORMPARAM) {
-        if (isMap(param)) {
-          writer.append("      .formParam(%s)", param.getName()).eol();
-        } else {
-          writer.append("      .formParam(\"%s\", %s)", param.getParamName(), param.getName()).eol();
-        }
-      } else if (paramType == ParamType.FORM) {
-        TypeElement formBeanType = ctx.getTypeElement(param.getRawType());
-        BeanParamReader form = new BeanParamReader(ctx, formBeanType, param.getName(), param.getShortType(), ParamType.FORMPARAM);
-        form.writeFormParams(writer);
+      PathSegments.Segment segment = segments.segment(varName);
+      if (segment == null) {
+        // not a path or matrix parameter
+        writeFormParam(param, paramType);
+      }
+    }
+  }
+
+  private void writeFormParam(MethodParam param, ParamType paramType) {
+    if (paramType == ParamType.FORMPARAM) {
+      if (isMap(param)) {
+        writer.append("      .formParam(%s)", param.getName()).eol();
+      } else {
+        writer.append("      .formParam(\"%s\", %s)", param.getParamName(), param.getName()).eol();
       }
+    } else if (paramType == ParamType.FORM) {
+      TypeElement formBeanType = ctx.getTypeElement(param.getRawType());
+      BeanParamReader form = new BeanParamReader(ctx, formBeanType, param.getName(), param.getShortType(), ParamType.FORMPARAM);
+      form.writeFormParams(writer);
     }
   }
 
diff --git a/tests/test-client/src/main/java/org/example/JunkApi.java b/tests/test-client/src/main/java/org/example/JunkApi.java
index bfdf1990b..5e7037b73 100644
--- a/tests/test-client/src/main/java/org/example/JunkApi.java
+++ b/tests/test-client/src/main/java/org/example/JunkApi.java
@@ -1,6 +1,7 @@
 package org.example;
 
 import io.avaje.http.api.Client;
+import io.avaje.http.api.Form;
 import io.avaje.http.api.Get;
 import io.avaje.http.api.Post;
 import io.avaje.http.client.HttpCall;
@@ -131,4 +132,8 @@ public interface JunkApi {
 
   @Post("/{id}/foo/{name}")
   HttpResponse reqBodyResHand2(HttpResponse.BodyHandler handler, HttpRequest.BodyPublisher body, String id, String name, String other);
+
+  @Form
+  @Post("foo/{email}")
+  void postFormWithPath(String email, String name, String other);
 }

From 0393c9a86aa7a7d7c160be30ceaa34f42ad737ef Mon Sep 17 00:00:00 2001
From: rbygrave 
Date: Thu, 8 Jul 2021 16:31:48 +1200
Subject: [PATCH 0195/1323] #66 - [client api] Support use of @BeanParam

---
 .../generator/client/ClientMethodWriter.java  | 17 ++++++++++++++
 .../main/java/org/example/CommonParams.java   | 23 +++++++++++++++++++
 .../src/main/java/org/example/JunkApi.java    | 13 +++++++----
 .../src/main/java/org/example/MyForm.java     | 19 +++++++++++++++
 4 files changed, 68 insertions(+), 4 deletions(-)
 create mode 100644 tests/test-client/src/main/java/org/example/CommonParams.java
 create mode 100644 tests/test-client/src/main/java/org/example/MyForm.java

diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java
index 3212622b9..ae5f284bd 100644
--- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java
+++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java
@@ -81,9 +81,13 @@ void write() {
     writeHeaders();
     writePaths(segments);
     writeQueryParams(pathSegments);
+    writeBeanParams(pathSegments);
     writeFormParams(pathSegments);
     writeBody();
+    writeEnd();
+  }
 
+  private void writeEnd() {
     WebMethod webMethod = method.getWebMethod();
     writer.append("      .%s()", webMethod.name()).eol();
     if (returnType == UType.VOID) {
@@ -174,6 +178,19 @@ private void writeHeaders() {
     }
   }
 
+  private void writeBeanParams(PathSegments segments) {
+    for (MethodParam param : method.getParams()) {
+      final String varName = param.getName();
+      ParamType paramType = param.getParamType();
+      PathSegments.Segment segment = segments.segment(varName);
+      if (segment == null && paramType == ParamType.BEANPARAM) {
+        TypeElement formBeanType = ctx.getTypeElement(param.getRawType());
+        BeanParamReader form = new BeanParamReader(ctx, formBeanType, param.getName(), param.getShortType(), ParamType.QUERYPARAM);
+        form.writeFormParams(writer);
+      }
+    }
+  }
+
   private void writeFormParams(PathSegments segments) {
     for (MethodParam param : method.getParams()) {
       final String varName = param.getName();
diff --git a/tests/test-client/src/main/java/org/example/CommonParams.java b/tests/test-client/src/main/java/org/example/CommonParams.java
new file mode 100644
index 000000000..2563f1c62
--- /dev/null
+++ b/tests/test-client/src/main/java/org/example/CommonParams.java
@@ -0,0 +1,23 @@
+package org.example;
+
+import io.avaje.http.api.Header;
+import io.avaje.http.api.QueryParam;
+
+public class CommonParams {
+
+  public Long firstRow;
+  public Long maxRows;
+  public String sortBy;
+  @QueryParam("X-Xtr")
+  private String extra;
+  @Header
+  public String filter;
+
+  public Long firstRow() {
+    return firstRow;
+  }
+
+  public String getExtra() {
+    return extra;
+  }
+}
diff --git a/tests/test-client/src/main/java/org/example/JunkApi.java b/tests/test-client/src/main/java/org/example/JunkApi.java
index 5e7037b73..a446a8c78 100644
--- a/tests/test-client/src/main/java/org/example/JunkApi.java
+++ b/tests/test-client/src/main/java/org/example/JunkApi.java
@@ -1,9 +1,6 @@
 package org.example;
 
-import io.avaje.http.api.Client;
-import io.avaje.http.api.Form;
-import io.avaje.http.api.Get;
-import io.avaje.http.api.Post;
+import io.avaje.http.api.*;
 import io.avaje.http.client.HttpCall;
 
 import java.io.InputStream;
@@ -11,6 +8,7 @@
 import java.net.http.HttpResponse;
 import java.nio.file.Path;
 import java.util.List;
+import java.util.UUID;
 import java.util.concurrent.CompletableFuture;
 import java.util.stream.Stream;
 
@@ -136,4 +134,11 @@ public interface JunkApi {
   @Form
   @Post("foo/{email}")
   void postFormWithPath(String email, String name, String other);
+
+  @Post("withBeanParam/{id}")
+  void postWithBeanParam(UUID id, @BeanParam CommonParams commonParams);
+
+  @Form @Post("withFormParam/{id}")
+  void postWithFormParam(UUID id, MyForm theForm, @BeanParam CommonParams commonParams);
+
 }
diff --git a/tests/test-client/src/main/java/org/example/MyForm.java b/tests/test-client/src/main/java/org/example/MyForm.java
new file mode 100644
index 000000000..e830df38d
--- /dev/null
+++ b/tests/test-client/src/main/java/org/example/MyForm.java
@@ -0,0 +1,19 @@
+package org.example;
+
+import io.avaje.http.api.Header;
+
+import java.time.LocalDate;
+
+public class MyForm {
+
+  public String name;
+  public String email;
+  public LocalDate started;
+
+  @Header("MFoo")
+  public String fooHead;
+
+  public String email() {
+    return email;
+  }
+}

From ef572d6de996e12f55110de0508b079e22e99400 Mon Sep 17 00:00:00 2001
From: rbygrave 
Date: Thu, 8 Jul 2021 22:05:33 +1200
Subject: [PATCH 0196/1323] [maven-release-plugin] prepare release
 avaje-http-client-1.10

---
 http-client/client/pom.xml | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/http-client/client/pom.xml b/http-client/client/pom.xml
index 264cdcdcc..eabfa1f6f 100644
--- a/http-client/client/pom.xml
+++ b/http-client/client/pom.xml
@@ -9,11 +9,11 @@
 
   io.avaje
   avaje-http-client
-  1.10-SNAPSHOT
+  1.10
 
   
     scm:git:git@github.com:avaje/avaje-http-client.git
-    HEAD
+    avaje-http-client-1.10
   
 
   

From d0f0fe8fd50dd37b1541f33a90df67227ac4eb05 Mon Sep 17 00:00:00 2001
From: rbygrave 
Date: Thu, 8 Jul 2021 22:05:42 +1200
Subject: [PATCH 0197/1323] [maven-release-plugin] prepare for next development
 iteration

---
 http-client/client/pom.xml | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/http-client/client/pom.xml b/http-client/client/pom.xml
index eabfa1f6f..ed1e84887 100644
--- a/http-client/client/pom.xml
+++ b/http-client/client/pom.xml
@@ -9,11 +9,11 @@
 
   io.avaje
   avaje-http-client
-  1.10
+  1.11-SNAPSHOT
 
   
     scm:git:git@github.com:avaje/avaje-http-client.git
-    avaje-http-client-1.10
+    HEAD
   
 
   

From e2cadac6ba8d22037af1d55e2dbce286479dea7c Mon Sep 17 00:00:00 2001
From: rbygrave 
Date: Thu, 8 Jul 2021 22:15:24 +1200
Subject: [PATCH 0198/1323] bump test api version

---
 http-client/client/pom.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/http-client/client/pom.xml b/http-client/client/pom.xml
index ed1e84887..039159e55 100644
--- a/http-client/client/pom.xml
+++ b/http-client/client/pom.xml
@@ -57,7 +57,7 @@
     
       io.avaje
       avaje-http-api
-      1.2
+      1.9
       test
     
 

From 5bd6cdb008330da748de609e8aaa2cabc74250ba Mon Sep 17 00:00:00 2001
From: rbygrave 
Date: Thu, 8 Jul 2021 22:16:11 +1200
Subject: [PATCH 0199/1323] [maven-release-plugin] prepare release
 avaje-http-client-1.11

---
 http-client/client/pom.xml | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/http-client/client/pom.xml b/http-client/client/pom.xml
index 039159e55..8d088a68d 100644
--- a/http-client/client/pom.xml
+++ b/http-client/client/pom.xml
@@ -9,11 +9,11 @@
 
   io.avaje
   avaje-http-client
-  1.11-SNAPSHOT
+  1.11
 
   
     scm:git:git@github.com:avaje/avaje-http-client.git
-    HEAD
+    avaje-http-client-1.11
   
 
   

From ef9e52e987cbcd9b825e5b5593a21b86553b66b2 Mon Sep 17 00:00:00 2001
From: rbygrave 
Date: Thu, 8 Jul 2021 22:16:22 +1200
Subject: [PATCH 0200/1323] [maven-release-plugin] prepare for next development
 iteration

---
 http-client/client/pom.xml | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/http-client/client/pom.xml b/http-client/client/pom.xml
index 8d088a68d..3c40e91cc 100644
--- a/http-client/client/pom.xml
+++ b/http-client/client/pom.xml
@@ -9,11 +9,11 @@
 
   io.avaje
   avaje-http-client
-  1.11
+  1.12-SNAPSHOT
 
   
     scm:git:git@github.com:avaje/avaje-http-client.git
-    avaje-http-client-1.11
+    HEAD
   
 
   

From 66761f8b867551f096d565d80acfe535188cfb87 Mon Sep 17 00:00:00 2001
From: rbygrave 
Date: Thu, 8 Jul 2021 22:19:43 +1200
Subject: [PATCH 0201/1323] bump avaje-http-client-gson to 1.11

---
 http-client/gson-adapter/pom.xml | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/http-client/gson-adapter/pom.xml b/http-client/gson-adapter/pom.xml
index 10005a1dc..f9722ab44 100644
--- a/http-client/gson-adapter/pom.xml
+++ b/http-client/gson-adapter/pom.xml
@@ -9,7 +9,7 @@
 
   io.avaje
   avaje-http-client-gson
-  1.9
+  1.11
 
   
     scm:git:git@github.com:avaje/avaje-http-client.git
@@ -27,7 +27,7 @@
     
       io.avaje
       avaje-http-client
-      1.9
+      1.11
       provided
     
 

From 9525287fb593e4eeaebf8273c75c4d044f0f77e4 Mon Sep 17 00:00:00 2001
From: rbygrave 
Date: Thu, 8 Jul 2021 22:23:45 +1200
Subject: [PATCH 0202/1323] update test versions after release

---
 http-client/test/pom.xml | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/http-client/test/pom.xml b/http-client/test/pom.xml
index 194f7a1ef..c5a9aaf16 100644
--- a/http-client/test/pom.xml
+++ b/http-client/test/pom.xml
@@ -16,13 +16,13 @@
     
       io.avaje
       avaje-http-client
-      1.10-SNAPSHOT
+      1.12-SNAPSHOT
     
 
     
       io.avaje
       avaje-http-client-gson
-      1.9
+      1.11
     
 
     

From 1af13f4f36f61493710f02af5e1217a5567cfba6 Mon Sep 17 00:00:00 2001
From: rbygrave 
Date: Thu, 8 Jul 2021 22:26:40 +1200
Subject: [PATCH 0203/1323] bump avaje-http-client to 1.11

---
 tests/test-client/pom.xml  | 2 +-
 tests/test-helidon/pom.xml | 2 +-
 tests/test-javalin/pom.xml | 2 +-
 tests/test-jex/pom.xml     | 2 +-
 tests/test-spark/pom.xml   | 2 +-
 5 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml
index a9a5e1d40..6f71e51f3 100644
--- a/tests/test-client/pom.xml
+++ b/tests/test-client/pom.xml
@@ -30,7 +30,7 @@
     
       io.avaje
       avaje-http-client
-      1.9
+      1.11
     
 
     
diff --git a/tests/test-helidon/pom.xml b/tests/test-helidon/pom.xml
index a02f6a47e..689ab7580 100644
--- a/tests/test-helidon/pom.xml
+++ b/tests/test-helidon/pom.xml
@@ -115,7 +115,7 @@
     
       io.avaje
       avaje-http-client
-      1.9
+      1.11
       test
     
 
diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml
index 374edb112..796e8a040 100644
--- a/tests/test-javalin/pom.xml
+++ b/tests/test-javalin/pom.xml
@@ -108,7 +108,7 @@
     
       io.avaje
       avaje-http-client
-      1.9
+      1.11
       test
     
 
diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml
index 2c24219a6..c30f4f2ca 100644
--- a/tests/test-jex/pom.xml
+++ b/tests/test-jex/pom.xml
@@ -95,7 +95,7 @@
     
       io.avaje
       avaje-http-client
-      1.9
+      1.11
       test
     
 
diff --git a/tests/test-spark/pom.xml b/tests/test-spark/pom.xml
index 0e9325f4f..dd0e68108 100644
--- a/tests/test-spark/pom.xml
+++ b/tests/test-spark/pom.xml
@@ -93,7 +93,7 @@
     
       io.avaje
       avaje-http-client
-      1.9
+      1.11
       test
     
 

From 509f3ffd14a779deb0198c0cf1ff5ec3552c3bcd Mon Sep 17 00:00:00 2001
From: rbygrave 
Date: Thu, 8 Jul 2021 22:28:00 +1200
Subject: [PATCH 0204/1323] bump to 1.11-SNAPSHOT

---
 http-api/pom.xml               | 2 +-
 http-generator-client/pom.xml  | 2 +-
 http-generator-core/pom.xml    | 4 ++--
 http-generator-helidon/pom.xml | 2 +-
 http-generator-javalin/pom.xml | 2 +-
 http-generator-jex/pom.xml     | 2 +-
 pom.xml                        | 2 +-
 tests/test-client/pom.xml      | 6 +++---
 tests/test-helidon/pom.xml     | 2 +-
 tests/test-javalin/pom.xml     | 2 +-
 tests/test-jex/pom.xml         | 2 +-
 tests/test-spark/pom.xml       | 4 ++--
 12 files changed, 16 insertions(+), 16 deletions(-)

diff --git a/http-api/pom.xml b/http-api/pom.xml
index b6adfeb6b..225a6eef6 100644
--- a/http-api/pom.xml
+++ b/http-api/pom.xml
@@ -4,7 +4,7 @@
   
     io.avaje
     avaje-http-generator-parent
-    1.10-SNAPSHOT
+    1.11-SNAPSHOT
     ..
   
 
diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml
index 07dee7b9a..8cac8250b 100644
--- a/http-generator-client/pom.xml
+++ b/http-generator-client/pom.xml
@@ -5,7 +5,7 @@
   
     io.avaje
     avaje-http-generator-parent
-    1.10-SNAPSHOT
+    1.11-SNAPSHOT
     ..
   
 
diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml
index 911c7e969..e067f7e94 100644
--- a/http-generator-core/pom.xml
+++ b/http-generator-core/pom.xml
@@ -7,7 +7,7 @@
   
     io.avaje
     avaje-http-generator-parent
-    1.10-SNAPSHOT
+    1.11-SNAPSHOT
     ..
   
 
@@ -33,7 +33,7 @@
     
       io.avaje
       avaje-http-api
-      1.10-SNAPSHOT
+      1.11-SNAPSHOT
     
 
     
diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml
index e1d96854f..667820d31 100644
--- a/http-generator-helidon/pom.xml
+++ b/http-generator-helidon/pom.xml
@@ -7,7 +7,7 @@
   
     io.avaje
     avaje-http-generator-parent
-    1.10-SNAPSHOT
+    1.11-SNAPSHOT
     ..
   
 
diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml
index 3e3ff1fc3..40736d2a1 100644
--- a/http-generator-javalin/pom.xml
+++ b/http-generator-javalin/pom.xml
@@ -7,7 +7,7 @@
   
     io.avaje
     avaje-http-generator-parent
-    1.10-SNAPSHOT
+    1.11-SNAPSHOT
     ..
   
 
diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml
index f70279b66..afa638f58 100644
--- a/http-generator-jex/pom.xml
+++ b/http-generator-jex/pom.xml
@@ -7,7 +7,7 @@
   
     io.avaje
     avaje-http-generator-parent
-    1.10-SNAPSHOT
+    1.11-SNAPSHOT
     ..
   
 
diff --git a/pom.xml b/pom.xml
index 75d9f4cf0..b14aea012 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
 
   io.avaje
   avaje-http-generator-parent
-  1.10-SNAPSHOT
+  1.11-SNAPSHOT
   pom
 
   
diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml
index 6f71e51f3..61fd80f31 100644
--- a/tests/test-client/pom.xml
+++ b/tests/test-client/pom.xml
@@ -36,7 +36,7 @@
     
       io.avaje
       avaje-http-api
-      1.10-SNAPSHOT
+      1.11-SNAPSHOT
     
 
     
@@ -108,12 +108,12 @@
             
               io.avaje
               avaje-http-client-generator
-              1.10-SNAPSHOT
+              1.11-SNAPSHOT
             
             
               io.avaje
               avaje-http-jex-generator
-              1.10-SNAPSHOT
+              1.11-SNAPSHOT
             
             
               io.avaje
diff --git a/tests/test-helidon/pom.xml b/tests/test-helidon/pom.xml
index 689ab7580..cbcc6b397 100644
--- a/tests/test-helidon/pom.xml
+++ b/tests/test-helidon/pom.xml
@@ -17,7 +17,7 @@
   
     org.example.Main
     2.3.0
-    1.10-SNAPSHOT
+    1.11-SNAPSHOT
   
 
   
diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml
index 796e8a040..4a06586ff 100644
--- a/tests/test-javalin/pom.xml
+++ b/tests/test-javalin/pom.xml
@@ -20,7 +20,7 @@
     2.0.8
     1.3.71
     2.12.3
-    1.10-SNAPSHOT
+    1.11-SNAPSHOT
   
 
   
diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml
index c30f4f2ca..83f7490fc 100644
--- a/tests/test-jex/pom.xml
+++ b/tests/test-jex/pom.xml
@@ -20,7 +20,7 @@
     2.0.8
     2.12.3
     6.1
-    1.10-SNAPSHOT
+    1.11-SNAPSHOT
   
 
   
diff --git a/tests/test-spark/pom.xml b/tests/test-spark/pom.xml
index dd0e68108..6e3ce9894 100644
--- a/tests/test-spark/pom.xml
+++ b/tests/test-spark/pom.xml
@@ -17,7 +17,7 @@
   
     org.example.myapp.Main
     2.0.8
-    1.10-SNAPSHOT
+    1.11-SNAPSHOT
   
 
   
@@ -76,7 +76,7 @@
     
       io.avaje
       avaje-http-spark-generator
-      1.10-SNAPSHOT
+      1.11-SNAPSHOT
       provided
     
 

From 0b9c7361f45a88a7f3274eedb47bbaaf2ad89434 Mon Sep 17 00:00:00 2001
From: rbygrave 
Date: Thu, 8 Jul 2021 22:30:10 +1200
Subject: [PATCH 0205/1323] Temp disable tests modules

---
 pom.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/pom.xml b/pom.xml
index b14aea012..b1f8f37cc 100644
--- a/pom.xml
+++ b/pom.xml
@@ -39,7 +39,7 @@
     http-generator-jex
     http-generator-helidon
     http-generator-client
-    tests
+
   
 
 

From c772fdc0486c88e0827477e86fb12d2999335d7c Mon Sep 17 00:00:00 2001
From: rbygrave 
Date: Thu, 8 Jul 2021 22:31:04 +1200
Subject: [PATCH 0206/1323] [maven-release-plugin] prepare release
 avaje-http-generator-parent-1.11

---
 http-api/pom.xml               | 4 ++--
 http-generator-client/pom.xml  | 2 +-
 http-generator-core/pom.xml    | 4 ++--
 http-generator-helidon/pom.xml | 2 +-
 http-generator-javalin/pom.xml | 2 +-
 http-generator-jex/pom.xml     | 2 +-
 pom.xml                        | 4 ++--
 7 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/http-api/pom.xml b/http-api/pom.xml
index 225a6eef6..29be6010f 100644
--- a/http-api/pom.xml
+++ b/http-api/pom.xml
@@ -4,7 +4,7 @@
   
     io.avaje
     avaje-http-generator-parent
-    1.11-SNAPSHOT
+    1.11
     ..
   
 
@@ -20,7 +20,7 @@
 
   
     scm:git:git@github.com:avaje/avaje-http.git
-    HEAD
+    avaje-http-generator-parent-1.11
   
 
   
diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml
index 8cac8250b..ae3132857 100644
--- a/http-generator-client/pom.xml
+++ b/http-generator-client/pom.xml
@@ -5,7 +5,7 @@
   
     io.avaje
     avaje-http-generator-parent
-    1.11-SNAPSHOT
+    1.11
     ..
   
 
diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml
index e067f7e94..64eb118e8 100644
--- a/http-generator-core/pom.xml
+++ b/http-generator-core/pom.xml
@@ -7,7 +7,7 @@
   
     io.avaje
     avaje-http-generator-parent
-    1.11-SNAPSHOT
+    1.11
     ..
   
 
@@ -33,7 +33,7 @@
     
       io.avaje
       avaje-http-api
-      1.11-SNAPSHOT
+      1.11
     
 
     
diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml
index 667820d31..d7c674153 100644
--- a/http-generator-helidon/pom.xml
+++ b/http-generator-helidon/pom.xml
@@ -7,7 +7,7 @@
   
     io.avaje
     avaje-http-generator-parent
-    1.11-SNAPSHOT
+    1.11
     ..
   
 
diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml
index 40736d2a1..ac1e8fdeb 100644
--- a/http-generator-javalin/pom.xml
+++ b/http-generator-javalin/pom.xml
@@ -7,7 +7,7 @@
   
     io.avaje
     avaje-http-generator-parent
-    1.11-SNAPSHOT
+    1.11
     ..
   
 
diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml
index afa638f58..36fba1c39 100644
--- a/http-generator-jex/pom.xml
+++ b/http-generator-jex/pom.xml
@@ -7,7 +7,7 @@
   
     io.avaje
     avaje-http-generator-parent
-    1.11-SNAPSHOT
+    1.11
     ..
   
 
diff --git a/pom.xml b/pom.xml
index b1f8f37cc..81a6783d1 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
 
   io.avaje
   avaje-http-generator-parent
-  1.11-SNAPSHOT
+  1.11
   pom
 
   
@@ -15,7 +15,7 @@
 
   
     scm:git:git@github.com:avaje/avaje-http.git
-    HEAD
+    avaje-http-generator-parent-1.11
   
 
   

From 94ebb53e10a4f3d8124a2e21401a5c14c717adfa Mon Sep 17 00:00:00 2001
From: rbygrave 
Date: Thu, 8 Jul 2021 22:31:14 +1200
Subject: [PATCH 0207/1323] [maven-release-plugin] prepare for next development
 iteration

---
 http-api/pom.xml               | 4 ++--
 http-generator-client/pom.xml  | 2 +-
 http-generator-core/pom.xml    | 4 ++--
 http-generator-helidon/pom.xml | 2 +-
 http-generator-javalin/pom.xml | 2 +-
 http-generator-jex/pom.xml     | 2 +-
 pom.xml                        | 4 ++--
 7 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/http-api/pom.xml b/http-api/pom.xml
index 29be6010f..7a0222c10 100644
--- a/http-api/pom.xml
+++ b/http-api/pom.xml
@@ -4,7 +4,7 @@
   
     io.avaje
     avaje-http-generator-parent
-    1.11
+    1.12-SNAPSHOT
     ..
   
 
@@ -20,7 +20,7 @@
 
   
     scm:git:git@github.com:avaje/avaje-http.git
-    avaje-http-generator-parent-1.11
+    HEAD
   
 
   
diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml
index ae3132857..9b602b49f 100644
--- a/http-generator-client/pom.xml
+++ b/http-generator-client/pom.xml
@@ -5,7 +5,7 @@
   
     io.avaje
     avaje-http-generator-parent
-    1.11
+    1.12-SNAPSHOT
     ..
   
 
diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml
index 64eb118e8..786d97b7d 100644
--- a/http-generator-core/pom.xml
+++ b/http-generator-core/pom.xml
@@ -7,7 +7,7 @@
   
     io.avaje
     avaje-http-generator-parent
-    1.11
+    1.12-SNAPSHOT
     ..
   
 
@@ -33,7 +33,7 @@
     
       io.avaje
       avaje-http-api
-      1.11
+      1.12-SNAPSHOT
     
 
     
diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml
index d7c674153..77c5b653c 100644
--- a/http-generator-helidon/pom.xml
+++ b/http-generator-helidon/pom.xml
@@ -7,7 +7,7 @@
   
     io.avaje
     avaje-http-generator-parent
-    1.11
+    1.12-SNAPSHOT
     ..
   
 
diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml
index ac1e8fdeb..62158eed1 100644
--- a/http-generator-javalin/pom.xml
+++ b/http-generator-javalin/pom.xml
@@ -7,7 +7,7 @@
   
     io.avaje
     avaje-http-generator-parent
-    1.11
+    1.12-SNAPSHOT
     ..
   
 
diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml
index 36fba1c39..b77cb7527 100644
--- a/http-generator-jex/pom.xml
+++ b/http-generator-jex/pom.xml
@@ -7,7 +7,7 @@
   
     io.avaje
     avaje-http-generator-parent
-    1.11
+    1.12-SNAPSHOT
     ..
   
 
diff --git a/pom.xml b/pom.xml
index 81a6783d1..d6067e8de 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
 
   io.avaje
   avaje-http-generator-parent
-  1.11
+  1.12-SNAPSHOT
   pom
 
   
@@ -15,7 +15,7 @@
 
   
     scm:git:git@github.com:avaje/avaje-http.git
-    avaje-http-generator-parent-1.11
+    HEAD
   
 
   

From ae08664365ade16e40eb3596e23aed981474f11d Mon Sep 17 00:00:00 2001
From: rbygrave 
Date: Thu, 8 Jul 2021 22:37:42 +1200
Subject: [PATCH 0208/1323] Bump test versions after release

---
 pom.xml                    | 2 +-
 tests/test-client/pom.xml  | 6 +++---
 tests/test-helidon/pom.xml | 2 +-
 tests/test-javalin/pom.xml | 2 +-
 tests/test-jex/pom.xml     | 2 +-
 tests/test-spark/pom.xml   | 4 ++--
 6 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/pom.xml b/pom.xml
index d6067e8de..e3bed8c2d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -39,7 +39,7 @@
     http-generator-jex
     http-generator-helidon
     http-generator-client
-
+    tests
   
 
 
diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml
index 61fd80f31..ec965828c 100644
--- a/tests/test-client/pom.xml
+++ b/tests/test-client/pom.xml
@@ -36,7 +36,7 @@
     
       io.avaje
       avaje-http-api
-      1.11-SNAPSHOT
+      1.12-SNAPSHOT
     
 
     
@@ -108,12 +108,12 @@
             
               io.avaje
               avaje-http-client-generator
-              1.11-SNAPSHOT
+              1.12-SNAPSHOT
             
             
               io.avaje
               avaje-http-jex-generator
-              1.11-SNAPSHOT
+              1.12-SNAPSHOT
             
             
               io.avaje
diff --git a/tests/test-helidon/pom.xml b/tests/test-helidon/pom.xml
index cbcc6b397..a25b18fae 100644
--- a/tests/test-helidon/pom.xml
+++ b/tests/test-helidon/pom.xml
@@ -17,7 +17,7 @@
   
     org.example.Main
     2.3.0
-    1.11-SNAPSHOT
+    1.12-SNAPSHOT
   
 
   
diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml
index 4a06586ff..b35106e26 100644
--- a/tests/test-javalin/pom.xml
+++ b/tests/test-javalin/pom.xml
@@ -20,7 +20,7 @@
     2.0.8
     1.3.71
     2.12.3
-    1.11-SNAPSHOT
+    1.12-SNAPSHOT
   
 
   
diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml
index 83f7490fc..7d0afe03c 100644
--- a/tests/test-jex/pom.xml
+++ b/tests/test-jex/pom.xml
@@ -20,7 +20,7 @@
     2.0.8
     2.12.3
     6.1
-    1.11-SNAPSHOT
+    1.12-SNAPSHOT
   
 
   
diff --git a/tests/test-spark/pom.xml b/tests/test-spark/pom.xml
index 6e3ce9894..cd8024b65 100644
--- a/tests/test-spark/pom.xml
+++ b/tests/test-spark/pom.xml
@@ -17,7 +17,7 @@
   
     org.example.myapp.Main
     2.0.8
-    1.11-SNAPSHOT
+    1.12-SNAPSHOT
   
 
   
@@ -76,7 +76,7 @@
     
       io.avaje
       avaje-http-spark-generator
-      1.11-SNAPSHOT
+      1.12-SNAPSHOT
       provided
     
 

From 2f26ebbe5d35c23dc3cdd19bcf3bce09c97632b0 Mon Sep 17 00:00:00 2001
From: Rob Bygrave 
Date: Fri, 9 Jul 2021 11:50:52 +1200
Subject: [PATCH 0209/1323] Update README.md

---
 http-client/README.md | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/http-client/README.md b/http-client/README.md
index cc55b62c6..ae42f261f 100644
--- a/http-client/README.md
+++ b/http-client/README.md
@@ -1,5 +1,7 @@
 # avaje-http-client
 
+Documentation at [avaje.io/http-client](https://avaje.io/http-client/)
+
 A lightweight wrapper to the [JDK 11+ Java Http Client](http://openjdk.java.net/groups/net/httpclient/intro.html)
 
 - Use Java 11.0.8 or higher (some SSL related bugs prior to 11.0.8 with JDK HttpClient)
@@ -18,7 +20,7 @@ A lightweight wrapper to the [JDK 11+ Java Http Client](http://openjdk.java.net/
 
   io.avaje
   avaje-http-client
-  1.8
+  1.11
 
 ```
 

From 8b4b56fd8d27e424a16cd6b1502ca145d8ede37a Mon Sep 17 00:00:00 2001
From: ponyjoy 
Date: Sun, 24 Oct 2021 11:44:42 +0800
Subject: [PATCH 0210/1323] Update ControllerMethodWriter.java

Javalin 4 path variable switched from ':param' to '{param}'
---
 .../io/avaje/http/generator/javalin/ControllerMethodWriter.java | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java
index 224b210cc..7bfc352a6 100644
--- a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java
+++ b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java
@@ -31,7 +31,7 @@ class ControllerMethodWriter {
   void write(boolean requestScoped) {
 
     final PathSegments segments = method.getPathSegments();
-    final String fullPath = segments.fullPathColon();
+    final String fullPath = segments.fullPath();
 
     writer.append("    ApiBuilder.%s(\"%s\", ctx -> {", webMethod.name().toLowerCase(), fullPath).eol();
     writer.append("      ctx.status(%s);", method.getStatusCode()).eol();

From bb8e0d929b1d96d0b4e146c0929c6e8a4a3c36d9 Mon Sep 17 00:00:00 2001
From: Rob Bygrave 
Date: Tue, 26 Oct 2021 12:17:35 +1300
Subject: [PATCH 0211/1323] Support for Javalin 4.x API

---
 .../io/avaje/http/api/PathTypeConversion.java |  17 ++-
 .../http/api/PathTypeConversionTest.java      | 127 +++++++++---------
 .../javalin/ControllerMethodWriter.java       |   3 +-
 .../generator/javalin/JavalinAdapter.java     |   4 +-
 tests/test-javalin/pom.xml                    |   2 +-
 .../src/main/java/org/example/myapp/Main.java |   1 -
 .../java/org/example/myapp/web/AppRoles.java  |   4 +-
 7 files changed, 84 insertions(+), 74 deletions(-)

diff --git a/http-api/src/main/java/io/avaje/http/api/PathTypeConversion.java b/http-api/src/main/java/io/avaje/http/api/PathTypeConversion.java
index fda99c81a..b99c853f1 100644
--- a/http-api/src/main/java/io/avaje/http/api/PathTypeConversion.java
+++ b/http-api/src/main/java/io/avaje/http/api/PathTypeConversion.java
@@ -1,11 +1,7 @@
 package io.avaje.http.api;
 
 import java.math.BigDecimal;
-import java.time.Instant;
-import java.time.LocalDate;
-import java.time.LocalDateTime;
-import java.time.LocalTime;
-import java.time.OffsetDateTime;
+import java.time.*;
 import java.util.UUID;
 
 /**
@@ -15,6 +11,17 @@
  */
 public class PathTypeConversion {
 
+  /**
+   * Return the value if non-null and otherwise the default value.
+   *
+   * @param value        The value to return if non-null
+   * @param defaultValue The default value to return
+   * @return The value if non-null and otherwise the default value.
+   */
+  public static String withDefault(String value, String defaultValue) {
+    return value != null ? value : defaultValue;
+  }
+
   /**
    * Check for null for a required property throwing RequiredArgumentException
    * if the value is null.
diff --git a/http-api/src/test/java/io/avaje/http/api/PathTypeConversionTest.java b/http-api/src/test/java/io/avaje/http/api/PathTypeConversionTest.java
index 53ba01f0a..a4b0b6cf1 100644
--- a/http-api/src/test/java/io/avaje/http/api/PathTypeConversionTest.java
+++ b/http-api/src/test/java/io/avaje/http/api/PathTypeConversionTest.java
@@ -13,85 +13,92 @@
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertThrows;
 
-public class PathTypeConversionTest {
+class PathTypeConversionTest {
 
   @Test
-  public void checkNull_when_null() {
+  void withDefault() {
+    assertEquals("a", PathTypeConversion.withDefault("a", "myVal"));
+    assertEquals("", PathTypeConversion.withDefault("", "myVal"));
+    assertEquals("myVal", PathTypeConversion.withDefault(null, "myVal"));
+  }
+
+  @Test
+  void checkNull_when_null() {
     assertThrows(RequiredArgumentException.class, () -> PathTypeConversion.checkNull(null, "id"));
   }
 
   @Test
-  public void checkNull_when_valid() {
+  void checkNull_when_valid() {
     assertEquals("42", PathTypeConversion.checkNull("42", "id"));
   }
 
   @Test
-  public void asInt() {
+  void asInt() {
     assertEquals(42, PathTypeConversion.asInt("42"));
   }
 
   @Test
-  public void asInt_when_null() {
+  void asInt_when_null() {
     assertThrows(InvalidPathArgumentException.class, () -> PathTypeConversion.asInt(null));
   }
 
   @Test
-  public void asInt_when_invalid() {
+  void asInt_when_invalid() {
     assertThrows(InvalidPathArgumentException.class, () -> PathTypeConversion.asInt("junk"));
   }
 
   @Test
-  public void asLong() {
+  void asLong() {
     assertEquals(42L, PathTypeConversion.asLong("42"));
   }
 
   @Test
-  public void asLong_when_invalid() {
+  void asLong_when_invalid() {
     assertThrows(InvalidPathArgumentException.class, () -> PathTypeConversion.asLong("junk"));
   }
 
   @Test
-  public void asLong_when_null() {
+  void asLong_when_null() {
     assertThrows(InvalidPathArgumentException.class, () -> PathTypeConversion.asLong(null));
   }
 
   @Test
-  public void asDouble() {
+  void asDouble() {
     assertThat(PathTypeConversion.asDouble("42")).isEqualTo(42d);
   }
 
   @Test
-  public void asDouble_when_invalid() {
+  void asDouble_when_invalid() {
     assertThrows(InvalidPathArgumentException.class, () -> PathTypeConversion.asDouble("jukn"));
   }
 
   @Test
-  public void asDouble_when_null() {
+  void asDouble_when_null() {
     assertThrows(InvalidPathArgumentException.class, () -> PathTypeConversion.asDouble(null));
   }
 
   @Test
-  public void asFloat() {
+  void asFloat() {
     assertThat(PathTypeConversion.asFloat("42")).isEqualTo(42f);
   }
 
   @Test
-  public void asFloat_when_null() {
+  void asFloat_when_null() {
     assertThrows(InvalidPathArgumentException.class, () -> PathTypeConversion.asFloat(null));
   }
 
   @Test
-  public void asFloat_when_invalid() {
+  void asFloat_when_invalid() {
     assertThrows(InvalidPathArgumentException.class, () -> PathTypeConversion.asFloat("junk"));
   }
 
   @Test
-  public void asBool_when_null() {
+  void asBool_when_null() {
     assertThrows(InvalidPathArgumentException.class, () -> PathTypeConversion.asBool(null));
   }
 
   @Test
-  public void asBool() {
+  void asBool() {
     assertThat(PathTypeConversion.asBool("true")).isTrue();
     assertThat(PathTypeConversion.asBool("True")).isTrue();
     assertThat(PathTypeConversion.asBool("TRUE")).isTrue();
@@ -100,164 +107,164 @@ public void asBool() {
   }
 
   @Test
-  public void asBigDecimal() {
+  void asBigDecimal() {
     assertThat(PathTypeConversion.asBigDecimal("42.3")).isEqualByComparingTo("42.3");
   }
 
   @Test
-  public void asBigDecimal_when_null() {
+  void asBigDecimal_when_null() {
     assertThrows(InvalidPathArgumentException.class, () -> PathTypeConversion.asBigDecimal(null));
   }
 
   @Test
-  public void asBigDecimal_when_invalid() {
+  void asBigDecimal_when_invalid() {
     assertThrows(InvalidPathArgumentException.class, () -> PathTypeConversion.asBigDecimal("junk"));
   }
 
   @Test
-  public void asLocalDate() {
+  void asLocalDate() {
     assertThat(PathTypeConversion.asLocalDate("2018-06-03")).isEqualTo(LocalDate.of(2018, 6, 3));
   }
 
   @Test
-  public void asLocalDate_when_null() {
+  void asLocalDate_when_null() {
     assertThrows(InvalidPathArgumentException.class, () -> PathTypeConversion.asLocalDate(null));
   }
 
   @Test
-  public void asLocalDate_when_invalid() {
+  void asLocalDate_when_invalid() {
     assertThrows(InvalidPathArgumentException.class, () -> PathTypeConversion.asLocalDate("junk"));
   }
 
   @Test
-  public void asLocalTime_when_invalid() {
+  void asLocalTime_when_invalid() {
     assertThrows(InvalidPathArgumentException.class, () -> PathTypeConversion.asLocalTime("junk"));
   }
 
   @Test
-  public void asLocalTime_when_null() {
+  void asLocalTime_when_null() {
     assertThrows(InvalidPathArgumentException.class, () -> PathTypeConversion.asLocalTime(null));
   }
 
   @Test
-  public void asLocalTime() {
+  void asLocalTime() {
     assertThat(PathTypeConversion.asLocalTime("23:34:09")).isEqualTo(LocalTime.of(23, 34, 9));
   }
 
   @Test
-  public void asInstant_when_null() {
+  void asInstant_when_null() {
     assertThrows(InvalidPathArgumentException.class, () -> PathTypeConversion.asInstant(null));
   }
 
   @Test
-  public void asOffsetDateTime_when_null() {
+  void asOffsetDateTime_when_null() {
     assertThrows(InvalidPathArgumentException.class, () -> PathTypeConversion.asOffsetDateTime(null));
   }
 
   @Test
-  public void asLocalDateTime_when_null() {
+  void asLocalDateTime_when_null() {
     assertThrows(InvalidPathArgumentException.class, () -> PathTypeConversion.asLocalDateTime(null));
   }
 
   @Test
-  public void asInstant_when_invalid() {
+  void asInstant_when_invalid() {
     assertThrows(InvalidPathArgumentException.class, () -> PathTypeConversion.asInstant("junk"));
   }
 
   @Test
-  public void asOffsetDateTime_when_invalid() {
+  void asOffsetDateTime_when_invalid() {
     assertThrows(InvalidPathArgumentException.class, () -> PathTypeConversion.asOffsetDateTime("junk"));
   }
 
   @Test
-  public void asLocalDateTime_when_invalid() {
+  void asLocalDateTime_when_invalid() {
     assertThrows(InvalidPathArgumentException.class, () -> PathTypeConversion.asLocalDateTime("junk"));
   }
 
   @Test
-  public void asInstant() {
+  void asInstant() {
     Instant instant = Instant.parse("2018-09-23T23:34:09Z");
     assertThat(PathTypeConversion.asInstant(instant.toString())).isEqualTo(instant);
   }
 
   @Test
-  public void asOffsetDateTime() {
+  void asOffsetDateTime() {
     OffsetDateTime instant = OffsetDateTime.parse("2018-09-23T23:34:09Z");
     assertThat(PathTypeConversion.asOffsetDateTime(instant.toString())).isEqualTo(instant);
   }
 
   @Test
-  public void asLocalDateTime() {
+  void asLocalDateTime() {
     LocalDateTime instant = LocalDateTime.parse("2018-09-23T23:34:09");
     assertThat(PathTypeConversion.asLocalDateTime(instant.toString())).isEqualTo(instant);
   }
 
   @Test
-  public void asUUID() {
+  void asUUID() {
     UUID uuid = UUID.randomUUID();
     assertThat(PathTypeConversion.asUUID(uuid.toString())).isEqualTo(uuid);
   }
 
   @Test
-  public void asUUID_when_null() {
+  void asUUID_when_null() {
     assertThrows(InvalidPathArgumentException.class, () -> PathTypeConversion.asUUID(null));
   }
 
   @Test
-  public void asUUID_when_invalid() {
+  void asUUID_when_invalid() {
     assertThrows(InvalidPathArgumentException.class, () -> PathTypeConversion.asUUID("junk"));
   }
 
   @Test
-  public void asInteger() {
+  void asInteger() {
     assertThat(PathTypeConversion.asInteger("42")).isEqualTo(42);
   }
 
   @Test
-  public void asInteger_null() {
+  void asInteger_null() {
     assertThrows(InvalidPathArgumentException.class, () -> PathTypeConversion.asInteger(null));
   }
 
   @Test
-  public void asInteger_invalid() {
+  void asInteger_invalid() {
     assertThrows(InvalidPathArgumentException.class, () -> PathTypeConversion.asInteger("junk"));
   }
 
   @Test
-  public void toInteger() {
+  void toInteger() {
     assertThat(PathTypeConversion.toInteger("42")).isEqualTo(42);
     assertThat(PathTypeConversion.toInteger(null)).isNull();
   }
 
   @Test
-  public void toInteger_invalid() {
+  void toInteger_invalid() {
     assertThrows(InvalidTypeArgumentException.class, () -> PathTypeConversion.toInteger("junk"));
   }
 
   @Test
-  public void toLong() {
+  void toLong() {
     assertThat(PathTypeConversion.toLong("42")).isEqualTo(42L);
     assertThat(PathTypeConversion.toLong(null)).isNull();
   }
 
   @Test
-  public void toLong_invalid() {
+  void toLong_invalid() {
     assertThrows(InvalidTypeArgumentException.class, () -> PathTypeConversion.toLong("junk"));
   }
 
   @Test
-  public void toBigDecimal() {
+  void toBigDecimal() {
     assertThat(PathTypeConversion.toBigDecimal("42.45")).isEqualByComparingTo("42.45");
     assertThat(PathTypeConversion.toBigDecimal(null)).isNull();
   }
 
   @Test
-  public void toBigDecimal_invalid() {
+  void toBigDecimal_invalid() {
     assertThrows(InvalidTypeArgumentException.class, () -> PathTypeConversion.toBigDecimal("junk"));
   }
 
   @Test
-  public void toBoolean() {
+  void toBoolean() {
     assertThat(PathTypeConversion.toBoolean("true")).isTrue();
     assertThat(PathTypeConversion.toBoolean("True")).isTrue();
     assertThat(PathTypeConversion.toBoolean("false")).isFalse();
@@ -265,66 +272,66 @@ public void toBoolean() {
   }
 
   @Test
-  public void toUUID() {
+  void toUUID() {
     UUID uuid = UUID.randomUUID();
     assertThat(PathTypeConversion.toUUID(uuid.toString())).isEqualTo(uuid);
   }
 
   @Test
-  public void toUUID_invalid() {
+  void toUUID_invalid() {
     assertThrows(InvalidTypeArgumentException.class, () -> PathTypeConversion.toUUID("junk"));
   }
 
   @Test
-  public void toLocalDate() {
+  void toLocalDate() {
     assertThat(PathTypeConversion.toLocalDate("2018-09-07")).isEqualTo(LocalDate.of(2018, 9, 7));
   }
 
   @Test
-  public void toLocalDate_invalid() {
+  void toLocalDate_invalid() {
     assertThrows(InvalidTypeArgumentException.class, () -> PathTypeConversion.toLocalDate("junk"));
   }
 
   @Test
-  public void toLocalTime() {
+  void toLocalTime() {
     assertThat(PathTypeConversion.toLocalTime("23:34:09")).isEqualTo(LocalTime.of(23, 34, 9));
   }
 
   @Test
-  public void toLocalTime_invalid() {
+  void toLocalTime_invalid() {
     assertThrows(InvalidTypeArgumentException.class, () -> PathTypeConversion.toLocalTime("junk"));
   }
 
   @Test
-  public void toInstant() {
+  void toInstant() {
     Instant instant = Instant.parse("2018-09-23T23:34:09Z");
     assertThat(PathTypeConversion.toInstant("2018-09-23T23:34:09Z")).isEqualTo(instant);
   }
 
   @Test
-  public void toInstant_invalid() {
+  void toInstant_invalid() {
     assertThrows(InvalidTypeArgumentException.class, () -> PathTypeConversion.toInstant("junk"));
   }
 
   @Test
-  public void toOffsetDateTime() {
+  void toOffsetDateTime() {
     OffsetDateTime instant = OffsetDateTime.parse("2018-09-23T23:34:09Z");
     assertThat(PathTypeConversion.toOffsetDateTime("2018-09-23T23:34:09Z")).isEqualTo(instant);
   }
 
   @Test
-  public void OffsetDateTime_invalid() {
+  void OffsetDateTime_invalid() {
     assertThrows(InvalidTypeArgumentException.class, () -> PathTypeConversion.toOffsetDateTime("junk"));
   }
 
   @Test
-  public void toLocalDateTime() {
+  void toLocalDateTime() {
     LocalDateTime instant = LocalDateTime.parse("2018-09-23T23:34:09");
     assertThat(PathTypeConversion.toLocalDateTime("2018-09-23T23:34:09")).isEqualTo(instant);
   }
 
   @Test
-  public void LocalDateTime_invalid() {
+  void LocalDateTime_invalid() {
     assertThrows(InvalidTypeArgumentException.class, () -> PathTypeConversion.toLocalDateTime("junk"));
   }
 }
diff --git a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java
index 224b210cc..28ef5a8e9 100644
--- a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java
+++ b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java
@@ -76,14 +76,13 @@ void write(boolean requestScoped) {
 
     List roles = method.roles();
     if (!roles.isEmpty()) {
-      writer.append(", roles(");
+      writer.append(", ");
       for (int i = 0; i < roles.size(); i++) {
         if (i > 0) {
           writer.append(", ");
         }
         writer.append(Util.shortName(roles.get(i)));
       }
-      writer.append(")");
     }
     writer.append(");").eol().eol();
   }
diff --git a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinAdapter.java b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinAdapter.java
index e9592e7e9..a3ede7f66 100644
--- a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinAdapter.java
+++ b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinAdapter.java
@@ -10,7 +10,6 @@
 class JavalinAdapter implements PlatformAdapter {
 
   static final String JAVALIN3_CONTEXT = "io.javalin.http.Context";
-  static final String JAVALIN3_ROLES = "io.javalin.core.security.SecurityUtil.roles";
 
   @Override
   public boolean isContextType(String rawType) {
@@ -48,7 +47,6 @@ public void methodRoles(List roles, ControllerReader controller) {
   }
 
   private void addRoleImports(List roles, ControllerReader controller) {
-    controller.addStaticImportType(JAVALIN3_ROLES);
     for (String role : roles) {
       controller.addStaticImportType(role);
     }
@@ -61,6 +59,6 @@ public void writeReadParameter(Append writer, ParamType paramType, String paramN
 
   @Override
   public void writeReadParameter(Append writer, ParamType paramType, String paramName, String paramDefault) {
-    writer.append("ctx.%s(\"%s\",\"%s\")", paramType, paramName, paramDefault);
+    writer.append("withDefault(ctx.%s(\"%s\"), \"%s\")", paramType, paramName, paramDefault);
   }
 }
diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml
index b35106e26..c977138ee 100644
--- a/tests/test-javalin/pom.xml
+++ b/tests/test-javalin/pom.xml
@@ -16,7 +16,7 @@
 
   
     org.example.myapp.Main
-    3.13.7
+    4.1.1
     2.0.8
     1.3.71
     2.12.3
diff --git a/tests/test-javalin/src/main/java/org/example/myapp/Main.java b/tests/test-javalin/src/main/java/org/example/myapp/Main.java
index 860ed77e7..e783363d1 100644
--- a/tests/test-javalin/src/main/java/org/example/myapp/Main.java
+++ b/tests/test-javalin/src/main/java/org/example/myapp/Main.java
@@ -28,7 +28,6 @@ public static Javalin start(int port) {
 
     Javalin app = Javalin.create(config -> {
       config.showJavalinBanner = false;
-      config.logIfServerNotStarted = false;
       config.addStaticFiles("public", Location.CLASSPATH);
       config.accessManager((handler, ctx, permittedRoles) -> {
         log.debug("allow access ...");
diff --git a/tests/test-javalin/src/main/java/org/example/myapp/web/AppRoles.java b/tests/test-javalin/src/main/java/org/example/myapp/web/AppRoles.java
index d58feb511..a1bdd6d1b 100644
--- a/tests/test-javalin/src/main/java/org/example/myapp/web/AppRoles.java
+++ b/tests/test-javalin/src/main/java/org/example/myapp/web/AppRoles.java
@@ -1,7 +1,7 @@
 package org.example.myapp.web;
 
-import io.javalin.core.security.Role;
+import io.javalin.core.security.RouteRole;
 
-public enum AppRoles implements Role {
+public enum AppRoles implements RouteRole {
   ANYONE, ADMIN, BASIC_USER, ORG_ADMIN
 }

From 1ee3bc45a6837d80d9e3d41985b7caffbbddc68b Mon Sep 17 00:00:00 2001
From: Rob Bygrave 
Date: Tue, 26 Oct 2021 12:23:18 +1300
Subject: [PATCH 0212/1323] Add maven.deploy.skip true on test modules

---
 pom.xml                    | 2 +-
 tests/pom.xml              | 4 ++++
 tests/test-client/pom.xml  | 1 +
 tests/test-helidon/pom.xml | 1 +
 tests/test-javalin/pom.xml | 1 +
 tests/test-jex/pom.xml     | 1 +
 6 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/pom.xml b/pom.xml
index e3bed8c2d..dfaadf0e3 100644
--- a/pom.xml
+++ b/pom.xml
@@ -19,7 +19,7 @@
   
 
   
-    true
+    false
   
 
   
diff --git a/tests/pom.xml b/tests/pom.xml
index 088bf86e6..aa1221f72 100644
--- a/tests/pom.xml
+++ b/tests/pom.xml
@@ -9,6 +9,10 @@
   1
   pom
 
+  
+    true
+  
+
   
     test-helidon
     test-javalin
diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml
index ec965828c..a7155debd 100644
--- a/tests/test-client/pom.xml
+++ b/tests/test-client/pom.xml
@@ -15,6 +15,7 @@
   1
 
   
+    true
     1.6
     6.1
   
diff --git a/tests/test-helidon/pom.xml b/tests/test-helidon/pom.xml
index a25b18fae..42b7140aa 100644
--- a/tests/test-helidon/pom.xml
+++ b/tests/test-helidon/pom.xml
@@ -15,6 +15,7 @@
   
 
   
+    true
     org.example.Main
     2.3.0
     1.12-SNAPSHOT
diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml
index c977138ee..e4e950c94 100644
--- a/tests/test-javalin/pom.xml
+++ b/tests/test-javalin/pom.xml
@@ -15,6 +15,7 @@
   
 
   
+    true
     org.example.myapp.Main
     4.1.1
     2.0.8
diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml
index 7d0afe03c..56a02c231 100644
--- a/tests/test-jex/pom.xml
+++ b/tests/test-jex/pom.xml
@@ -15,6 +15,7 @@
   
 
   
+    true
     org.example.myapp.Main
     1.6
     2.0.8

From ca9ab94623720f4be766944fb0ea6dfbad19c2e6 Mon Sep 17 00:00:00 2001
From: Rob Bygrave 
Date: Tue, 26 Oct 2021 13:41:29 +1300
Subject: [PATCH 0213/1323] Add support for Jex 2.0 with slash accepting named
 paths (rather than splat)

---
 .../http/generator/core/PathSegments.java     | 28 ++++++++----
 tests/test-jex/pom.xml                        |  8 +++-
 .../java/org/example/web/HelloController.java | 10 ++++-
 .../src/main/resources/public/openapi.json    | 43 ++++++++++++++++++-
 .../org/example/web/HelloControllerTest.java  |  6 +++
 5 files changed, 82 insertions(+), 13 deletions(-)

diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/PathSegments.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/PathSegments.java
index 270d1d709..c6c5036f0 100644
--- a/http-generator-core/src/main/java/io/avaje/http/generator/core/PathSegments.java
+++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/PathSegments.java
@@ -28,13 +28,13 @@ static PathSegments parse(String fullPath) {
             final String name = section.substring(1);
             Segment segment = createSegment(name);
             segments.add(segment);
-            chunks.named(segment.path(name));
+            chunks.named(segment.path(name), ':');
 
-          } else if ((section.startsWith("{") && (section.endsWith("}")))) {
+          } else if (isPathParameter(section)) {
             String name = section.substring(1, section.length() - 1);
             Segment segment = createSegment(name);
             segments.add(segment);
-            chunks.named(segment.path(name));
+            chunks.named(segment.path(name), section.charAt(0));
 
           } else {
             Segment segment = createLiteralSegment(section);
@@ -44,10 +44,14 @@ static PathSegments parse(String fullPath) {
         }
       }
     }
-
     return new PathSegments(chunks, segments);
   }
 
+  private static boolean isPathParameter(String section) {
+    return section.startsWith("{") && section.endsWith("}")
+      || section.startsWith("<") && section.endsWith(">");
+  }
+
   private static Segment createLiteralSegment(String section) {
     return new Segment(section, true);
   }
@@ -250,8 +254,8 @@ String path(String section) {
   private static class Chunks {
     private final List chunks = new ArrayList<>();
 
-    void named(String name) {
-      chunks.add(new Chunk(name));
+    void named(String name, char firstChar) {
+      chunks.add(new Chunk(name, firstChar));
     }
 
     void literal(String val) {
@@ -269,7 +273,7 @@ String fullPath(String prefix, String suffix) {
 
   private static class LiteralChunk extends Chunk {
     private LiteralChunk(String value) {
-      super(value);
+      super(value, ' ');
     }
 
     @Override
@@ -280,12 +284,18 @@ void append(StringBuilder fullPath, String prefix, String suffix) {
 
   private static class Chunk {
     final String value;
-    private Chunk(String value) {
+    final char firstChar;
+    private Chunk(String value, char firstChar) {
       this.value = value;
+      this.firstChar = firstChar;
     }
 
     void append(StringBuilder fullPath, String prefix, String suffix) {
-      fullPath.append(prefix).append(value).append(suffix);
+      if ('<' == firstChar) {
+        fullPath.append('<').append(value).append('>');
+      } else {
+        fullPath.append(prefix).append(value).append(suffix);
+      }
     }
   }
 
diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml
index 56a02c231..30b9c70a9 100644
--- a/tests/test-jex/pom.xml
+++ b/tests/test-jex/pom.xml
@@ -17,7 +17,7 @@
   
     true
     org.example.myapp.Main
-    1.6
+    2.0
     2.0.8
     2.12.3
     6.1
@@ -38,6 +38,12 @@
       ${jex.version}
     
 
+    
+      io.avaje
+      avaje-jex-jetty
+      ${jex.version}
+    
+
     
       com.fasterxml.jackson.core
       jackson-databind
diff --git a/tests/test-jex/src/main/java/org/example/web/HelloController.java b/tests/test-jex/src/main/java/org/example/web/HelloController.java
index b0b286e92..4677832a5 100644
--- a/tests/test-jex/src/main/java/org/example/web/HelloController.java
+++ b/tests/test-jex/src/main/java/org/example/web/HelloController.java
@@ -32,9 +32,15 @@ String name(String name) {
   }
 
   @Produces("text/plain")
-  @Get("splat/{name}/*/other/*")
+  @Get("splat/{name}//other/")
   String splat(String name, Context ctx) {
-    return "got name:" + name + " splat0:" + ctx.splat(0) + " splat1:" + ctx.splat(1);
+    return "got name:" + name + " splat0:" + ctx.pathParam("s0") + " splat1:" + ctx.pathParam("s1");
+  }
+
+  @Produces("text/plain")
+  @Get("splat2/{name}//other/")
+  String splat2(String name, String nam0, String nam1) {
+    return "got name:" + name + " splat0:" + nam0 + " splat1:" + nam1;
   }
 
   @Valid
diff --git a/tests/test-jex/src/main/resources/public/openapi.json b/tests/test-jex/src/main/resources/public/openapi.json
index 14774b6dc..1057626f9 100644
--- a/tests/test-jex/src/main/resources/public/openapi.json
+++ b/tests/test-jex/src/main/resources/public/openapi.json
@@ -90,7 +90,7 @@
         }
       }
     },
-    "/splat/{name}/*/other/*" : {
+    "/splat/{name}//other/" : {
       "get" : {
         "tags" : [ ],
         "summary" : "",
@@ -116,6 +116,47 @@
           }
         }
       }
+    },
+    "/splat2/{name}//other/" : {
+      "get" : {
+        "tags" : [ ],
+        "summary" : "",
+        "description" : "",
+        "parameters" : [ {
+          "name" : "name",
+          "in" : "path",
+          "required" : true,
+          "schema" : {
+            "type" : "string"
+          }
+        }, {
+          "name" : "nam0",
+          "in" : "path",
+          "required" : true,
+          "schema" : {
+            "type" : "string"
+          }
+        }, {
+          "name" : "nam1",
+          "in" : "path",
+          "required" : true,
+          "schema" : {
+            "type" : "string"
+          }
+        } ],
+        "responses" : {
+          "200" : {
+            "description" : "",
+            "content" : {
+              "text/plain" : {
+                "schema" : {
+                  "type" : "string"
+                }
+              }
+            }
+          }
+        }
+      }
     }
   },
   "components" : {
diff --git a/tests/test-jex/src/test/java/org/example/web/HelloControllerTest.java b/tests/test-jex/src/test/java/org/example/web/HelloControllerTest.java
index 62c20319e..8be6802c8 100644
--- a/tests/test-jex/src/test/java/org/example/web/HelloControllerTest.java
+++ b/tests/test-jex/src/test/java/org/example/web/HelloControllerTest.java
@@ -43,6 +43,12 @@ void splat() {
     assertEquals("got name:one splat0:a/b splat1:x/y/z", client.request().path("splat/one/a/b/other/x/y/z").GET().asString().body());
   }
 
+  @Test
+  void splat2() {
+    assertEquals("got name:one splat0:a/b splat1:x/y/z", client.request().path("splat2/one/a/b/other/x/y/z").GET().asString().body());
+  }
+
+
   @Test
   void validation() {
 

From da0faf605c86e7b2381d17625589cecc3b4e324a Mon Sep 17 00:00:00 2001
From: Rob Bygrave 
Date: Tue, 26 Oct 2021 13:49:13 +1300
Subject: [PATCH 0214/1323] #71 - Support Javalin 4.x slash accepting named
 paths (rather than splat)

---
 .../example/myapp/web/HelloController.java    |  6 +++
 .../src/main/resources/public/openapi.json    | 41 +++++++++++++++++++
 .../example/myapp/HelloControllerTest.java    | 12 ++++++
 3 files changed, 59 insertions(+)

diff --git a/tests/test-javalin/src/main/java/org/example/myapp/web/HelloController.java b/tests/test-javalin/src/main/java/org/example/myapp/web/HelloController.java
index e684d9c02..a6ba9a5f8 100644
--- a/tests/test-javalin/src/main/java/org/example/myapp/web/HelloController.java
+++ b/tests/test-javalin/src/main/java/org/example/myapp/web/HelloController.java
@@ -141,4 +141,10 @@ void deleteById(int id) {
   String getWithMatrixParam(int year, String author, String country, String other, String extra) {
     return "yr:" + year + " au:" + author + " co:" + country + " other:" + other + " extra:" + extra;
   }
+
+  @Produces("text/plain")
+  @Get("slash/{name}//other/")
+  String slashAccepting(String name, String nam0, String nam1) {
+    return "got name:" + name + " splat0:" + nam0 + " splat1:" + nam1;
+  }
 }
diff --git a/tests/test-javalin/src/main/resources/public/openapi.json b/tests/test-javalin/src/main/resources/public/openapi.json
index d7259d38d..3bc47760e 100644
--- a/tests/test-javalin/src/main/resources/public/openapi.json
+++ b/tests/test-javalin/src/main/resources/public/openapi.json
@@ -426,6 +426,47 @@
         }
       }
     },
+    "/hello/slash/{name}//other/" : {
+      "get" : {
+        "tags" : [ ],
+        "summary" : "",
+        "description" : "",
+        "parameters" : [ {
+          "name" : "name",
+          "in" : "path",
+          "required" : true,
+          "schema" : {
+            "type" : "string"
+          }
+        }, {
+          "name" : "nam0",
+          "in" : "path",
+          "required" : true,
+          "schema" : {
+            "type" : "string"
+          }
+        }, {
+          "name" : "nam1",
+          "in" : "path",
+          "required" : true,
+          "schema" : {
+            "type" : "string"
+          }
+        } ],
+        "responses" : {
+          "200" : {
+            "description" : "",
+            "content" : {
+              "text/plain" : {
+                "schema" : {
+                  "type" : "string"
+                }
+              }
+            }
+          }
+        }
+      }
+    },
     "/hello/withMatrix/{year_segment}/{other}" : {
       "get" : {
         "tags" : [ ],
diff --git a/tests/test-javalin/src/test/java/org/example/myapp/HelloControllerTest.java b/tests/test-javalin/src/test/java/org/example/myapp/HelloControllerTest.java
index 2bf6ae1c7..ab50eaa48 100644
--- a/tests/test-javalin/src/test/java/org/example/myapp/HelloControllerTest.java
+++ b/tests/test-javalin/src/test/java/org/example/myapp/HelloControllerTest.java
@@ -298,4 +298,16 @@ void getWithMatrixParam() {
     assertEquals(200, httpRes.statusCode());
     assertEquals("yr:2011 au:rob co:nz other:foo extra:banana", httpRes.body());
   }
+
+
+  @Test
+  void get_slashAcceptingPath_expect200() {
+    final HttpResponse hres = clientContext.request()
+      .path("hello/slash/one/a/b/other/x/y/z")
+      .GET()
+      .asString();
+
+    assertThat(hres.statusCode()).isEqualTo(200);
+    assertEquals("got name:one splat0:a/b splat1:x/y/z", hres.body());
+  }
 }

From a855390773ae86ee9e21de6eedc58a9c066f4ff4 Mon Sep 17 00:00:00 2001
From: Rob Bygrave 
Date: Tue, 26 Oct 2021 13:50:38 +1300
Subject: [PATCH 0215/1323] Bump java8-oss parent to 3.2

---
 pom.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/pom.xml b/pom.xml
index dfaadf0e3..cd7b15b42 100644
--- a/pom.xml
+++ b/pom.xml
@@ -10,7 +10,7 @@
   
     org.avaje
     java8-oss
-    3.1
+    3.2
   
 
   

From 1546a341000b45d93a4942056ce1dd498598c994 Mon Sep 17 00:00:00 2001
From: Rob Bygrave 
Date: Tue, 26 Oct 2021 13:56:08 +1300
Subject: [PATCH 0216/1323] Bump maven-compiler-plugin to 3.8.1

---
 http-generator-client/pom.xml  | 2 +-
 http-generator-core/pom.xml    | 2 +-
 http-generator-helidon/pom.xml | 2 +-
 http-generator-javalin/pom.xml | 2 +-
 http-generator-jex/pom.xml     | 2 +-
 http-generator-spark/pom.xml   | 2 +-
 6 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml
index 9b602b49f..2d155b387 100644
--- a/http-generator-client/pom.xml
+++ b/http-generator-client/pom.xml
@@ -30,7 +30,7 @@
       
         org.apache.maven.plugins
         maven-compiler-plugin
-        3.2
+        3.8.1
         
           11
           11
diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml
index 786d97b7d..03f4ea24b 100644
--- a/http-generator-core/pom.xml
+++ b/http-generator-core/pom.xml
@@ -61,7 +61,7 @@
       
         org.apache.maven.plugins
         maven-compiler-plugin
-        3.2
+        3.8.1
         
           1.8
           1.8
diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml
index 77c5b653c..7be19fe6e 100644
--- a/http-generator-helidon/pom.xml
+++ b/http-generator-helidon/pom.xml
@@ -27,7 +27,7 @@
       
         org.apache.maven.plugins
         maven-compiler-plugin
-        3.2
+        3.8.1
         
           1.8
           1.8
diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml
index 62158eed1..6f7c8fca0 100644
--- a/http-generator-javalin/pom.xml
+++ b/http-generator-javalin/pom.xml
@@ -27,7 +27,7 @@
       
         org.apache.maven.plugins
         maven-compiler-plugin
-        3.2
+        3.8.1
         
           1.8
           1.8
diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml
index b77cb7527..3b581c8c7 100644
--- a/http-generator-jex/pom.xml
+++ b/http-generator-jex/pom.xml
@@ -27,7 +27,7 @@
       
         org.apache.maven.plugins
         maven-compiler-plugin
-        3.2
+        3.8.1
         
           1.8
           1.8
diff --git a/http-generator-spark/pom.xml b/http-generator-spark/pom.xml
index 247215f54..6fe67ef38 100644
--- a/http-generator-spark/pom.xml
+++ b/http-generator-spark/pom.xml
@@ -28,7 +28,7 @@
       
         org.apache.maven.plugins
         maven-compiler-plugin
-        3.2
+        3.8.1
         
           1.8
           1.8

From 271248d1cac7fb5171ebbc49d740960b450a6faa Mon Sep 17 00:00:00 2001
From: Rob Bygrave 
Date: Tue, 26 Oct 2021 13:58:16 +1300
Subject: [PATCH 0217/1323] [maven-release-plugin] prepare release
 avaje-http-generator-parent-1.12

---
 http-api/pom.xml               |  4 ++--
 http-generator-client/pom.xml  |  2 +-
 http-generator-core/pom.xml    |  4 ++--
 http-generator-helidon/pom.xml |  2 +-
 http-generator-javalin/pom.xml |  2 +-
 http-generator-jex/pom.xml     |  2 +-
 pom.xml                        |  4 ++--
 tests/pom.xml                  |  6 ++----
 tests/test-client/pom.xml      | 12 +++++++-----
 tests/test-helidon/pom.xml     | 12 +++++++-----
 tests/test-javalin/pom.xml     | 12 +++++++-----
 tests/test-jex/pom.xml         | 12 +++++++-----
 12 files changed, 40 insertions(+), 34 deletions(-)

diff --git a/http-api/pom.xml b/http-api/pom.xml
index 7a0222c10..4dc6a60cc 100644
--- a/http-api/pom.xml
+++ b/http-api/pom.xml
@@ -4,7 +4,7 @@
   
     io.avaje
     avaje-http-generator-parent
-    1.12-SNAPSHOT
+    1.12
     ..
   
 
@@ -20,7 +20,7 @@
 
   
     scm:git:git@github.com:avaje/avaje-http.git
-    HEAD
+    avaje-http-generator-parent-1.12
   
 
   
diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml
index 2d155b387..d9e9690a0 100644
--- a/http-generator-client/pom.xml
+++ b/http-generator-client/pom.xml
@@ -5,7 +5,7 @@
   
     io.avaje
     avaje-http-generator-parent
-    1.12-SNAPSHOT
+    1.12
     ..
   
 
diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml
index 03f4ea24b..b8d75b74d 100644
--- a/http-generator-core/pom.xml
+++ b/http-generator-core/pom.xml
@@ -7,7 +7,7 @@
   
     io.avaje
     avaje-http-generator-parent
-    1.12-SNAPSHOT
+    1.12
     ..
   
 
@@ -33,7 +33,7 @@
     
       io.avaje
       avaje-http-api
-      1.12-SNAPSHOT
+      1.12
     
 
     
diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml
index 7be19fe6e..d5d03b766 100644
--- a/http-generator-helidon/pom.xml
+++ b/http-generator-helidon/pom.xml
@@ -7,7 +7,7 @@
   
     io.avaje
     avaje-http-generator-parent
-    1.12-SNAPSHOT
+    1.12
     ..
   
 
diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml
index 6f7c8fca0..2d51e0771 100644
--- a/http-generator-javalin/pom.xml
+++ b/http-generator-javalin/pom.xml
@@ -7,7 +7,7 @@
   
     io.avaje
     avaje-http-generator-parent
-    1.12-SNAPSHOT
+    1.12
     ..
   
 
diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml
index 3b581c8c7..5711e2bf9 100644
--- a/http-generator-jex/pom.xml
+++ b/http-generator-jex/pom.xml
@@ -7,7 +7,7 @@
   
     io.avaje
     avaje-http-generator-parent
-    1.12-SNAPSHOT
+    1.12
     ..
   
 
diff --git a/pom.xml b/pom.xml
index cd7b15b42..a11cf931f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
 
   io.avaje
   avaje-http-generator-parent
-  1.12-SNAPSHOT
+  1.12
   pom
 
   
@@ -15,7 +15,7 @@
 
   
     scm:git:git@github.com:avaje/avaje-http.git
-    HEAD
+    avaje-http-generator-parent-1.12
   
 
   
diff --git a/tests/pom.xml b/tests/pom.xml
index aa1221f72..c281c990a 100644
--- a/tests/pom.xml
+++ b/tests/pom.xml
@@ -1,12 +1,10 @@
 
-
+
   4.0.0
 
   io.dinject
   tests-reactor
-  1
+  1.12
   pom
 
   
diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml
index a7155debd..943e5389e 100644
--- a/tests/test-client/pom.xml
+++ b/tests/test-client/pom.xml
@@ -1,7 +1,5 @@
 
-
+
 
   
     java11-oss
@@ -12,7 +10,7 @@
   4.0.0
 
   test-client
-  1
+  1.12
 
   
     true
@@ -37,7 +35,7 @@
     
       io.avaje
       avaje-http-api
-      1.12-SNAPSHOT
+      1.12
     
 
     
@@ -126,4 +124,8 @@
       
     
   
+
+  
+    avaje-http-generator-parent-1.12
+  
 
diff --git a/tests/test-helidon/pom.xml b/tests/test-helidon/pom.xml
index 42b7140aa..c04af0434 100644
--- a/tests/test-helidon/pom.xml
+++ b/tests/test-helidon/pom.xml
@@ -1,12 +1,10 @@
 
-
+
   4.0.0
 
   org.example
   test-helidon
-  1
+  1.12
 
   
     org.avaje
@@ -18,7 +16,7 @@
     true
     org.example.Main
     2.3.0
-    1.12-SNAPSHOT
+    1.12
   
 
   
@@ -145,4 +143,8 @@
       
     
   
+
+  
+    avaje-http-generator-parent-1.12
+  
 
diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml
index e4e950c94..d86b18f73 100644
--- a/tests/test-javalin/pom.xml
+++ b/tests/test-javalin/pom.xml
@@ -1,12 +1,10 @@
 
-
+
   4.0.0
 
   org.example
   test-javalin
-  1
+  1.12
 
   
     org.avaje
@@ -21,7 +19,7 @@
     2.0.8
     1.3.71
     2.12.3
-    1.12-SNAPSHOT
+    1.12
   
 
   
@@ -149,4 +147,8 @@
     
   
 
+
+  
+    avaje-http-generator-parent-1.12
+  
 
diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml
index 30b9c70a9..1b9a1c37f 100644
--- a/tests/test-jex/pom.xml
+++ b/tests/test-jex/pom.xml
@@ -1,12 +1,10 @@
 
-
+
   4.0.0
 
   org.example
   test-jex
-  1
+  1.12
 
   
     org.avaje
@@ -21,7 +19,7 @@
     2.0.8
     2.12.3
     6.1
-    1.12-SNAPSHOT
+    1.12
   
 
   
@@ -142,4 +140,8 @@
     
   
 
+
+  
+    avaje-http-generator-parent-1.12
+  
 

From 853f082beda771b8512931cd109956dbb3e0ed22 Mon Sep 17 00:00:00 2001
From: Rob Bygrave 
Date: Tue, 26 Oct 2021 13:58:22 +1300
Subject: [PATCH 0218/1323] [maven-release-plugin] prepare for next development
 iteration

---
 http-api/pom.xml               | 4 ++--
 http-generator-client/pom.xml  | 2 +-
 http-generator-core/pom.xml    | 4 ++--
 http-generator-helidon/pom.xml | 2 +-
 http-generator-javalin/pom.xml | 2 +-
 http-generator-jex/pom.xml     | 2 +-
 pom.xml                        | 4 ++--
 tests/pom.xml                  | 2 +-
 tests/test-client/pom.xml      | 7 ++++---
 tests/test-helidon/pom.xml     | 7 ++++---
 tests/test-javalin/pom.xml     | 7 ++++---
 tests/test-jex/pom.xml         | 7 ++++---
 12 files changed, 27 insertions(+), 23 deletions(-)

diff --git a/http-api/pom.xml b/http-api/pom.xml
index 4dc6a60cc..ca61e13ad 100644
--- a/http-api/pom.xml
+++ b/http-api/pom.xml
@@ -4,7 +4,7 @@
   
     io.avaje
     avaje-http-generator-parent
-    1.12
+    1.13-SNAPSHOT
     ..
   
 
@@ -20,7 +20,7 @@
 
   
     scm:git:git@github.com:avaje/avaje-http.git
-    avaje-http-generator-parent-1.12
+    HEAD
   
 
   
diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml
index d9e9690a0..813bbd1a2 100644
--- a/http-generator-client/pom.xml
+++ b/http-generator-client/pom.xml
@@ -5,7 +5,7 @@
   
     io.avaje
     avaje-http-generator-parent
-    1.12
+    1.13-SNAPSHOT
     ..
   
 
diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml
index b8d75b74d..ebcf1e780 100644
--- a/http-generator-core/pom.xml
+++ b/http-generator-core/pom.xml
@@ -7,7 +7,7 @@
   
     io.avaje
     avaje-http-generator-parent
-    1.12
+    1.13-SNAPSHOT
     ..
   
 
@@ -33,7 +33,7 @@
     
       io.avaje
       avaje-http-api
-      1.12
+      1.13-SNAPSHOT
     
 
     
diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml
index d5d03b766..39c879ac6 100644
--- a/http-generator-helidon/pom.xml
+++ b/http-generator-helidon/pom.xml
@@ -7,7 +7,7 @@
   
     io.avaje
     avaje-http-generator-parent
-    1.12
+    1.13-SNAPSHOT
     ..
   
 
diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml
index 2d51e0771..d3ca0421f 100644
--- a/http-generator-javalin/pom.xml
+++ b/http-generator-javalin/pom.xml
@@ -7,7 +7,7 @@
   
     io.avaje
     avaje-http-generator-parent
-    1.12
+    1.13-SNAPSHOT
     ..
   
 
diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml
index 5711e2bf9..5e326c3f1 100644
--- a/http-generator-jex/pom.xml
+++ b/http-generator-jex/pom.xml
@@ -7,7 +7,7 @@
   
     io.avaje
     avaje-http-generator-parent
-    1.12
+    1.13-SNAPSHOT
     ..
   
 
diff --git a/pom.xml b/pom.xml
index a11cf931f..fd449ea6d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
 
   io.avaje
   avaje-http-generator-parent
-  1.12
+  1.13-SNAPSHOT
   pom
 
   
@@ -15,7 +15,7 @@
 
   
     scm:git:git@github.com:avaje/avaje-http.git
-    avaje-http-generator-parent-1.12
+    HEAD
   
 
   
diff --git a/tests/pom.xml b/tests/pom.xml
index c281c990a..6d4af8a3b 100644
--- a/tests/pom.xml
+++ b/tests/pom.xml
@@ -4,7 +4,7 @@
 
   io.dinject
   tests-reactor
-  1.12
+  1
   pom
 
   
diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml
index 943e5389e..771ed2e08 100644
--- a/tests/test-client/pom.xml
+++ b/tests/test-client/pom.xml
@@ -10,7 +10,7 @@
   4.0.0
 
   test-client
-  1.12
+  1
 
   
     true
@@ -35,7 +35,7 @@
     
       io.avaje
       avaje-http-api
-      1.12
+      1.13-SNAPSHOT
     
 
     
@@ -126,6 +126,7 @@
   
 
   
-    avaje-http-generator-parent-1.12
+    HEAD
+    scm:git:git@github.com:avaje/avaje-http.git
   
 
diff --git a/tests/test-helidon/pom.xml b/tests/test-helidon/pom.xml
index c04af0434..df2d4a578 100644
--- a/tests/test-helidon/pom.xml
+++ b/tests/test-helidon/pom.xml
@@ -4,7 +4,7 @@
 
   org.example
   test-helidon
-  1.12
+  1
 
   
     org.avaje
@@ -16,7 +16,7 @@
     true
     org.example.Main
     2.3.0
-    1.12
+    1.13-SNAPSHOT
   
 
   
@@ -145,6 +145,7 @@
   
 
   
-    avaje-http-generator-parent-1.12
+    HEAD
+    scm:git:git@github.com:avaje/avaje-http.git
   
 
diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml
index d86b18f73..f77e41876 100644
--- a/tests/test-javalin/pom.xml
+++ b/tests/test-javalin/pom.xml
@@ -4,7 +4,7 @@
 
   org.example
   test-javalin
-  1.12
+  1
 
   
     org.avaje
@@ -19,7 +19,7 @@
     2.0.8
     1.3.71
     2.12.3
-    1.12
+    1.13-SNAPSHOT
   
 
   
@@ -149,6 +149,7 @@
 
 
   
-    avaje-http-generator-parent-1.12
+    HEAD
+    scm:git:git@github.com:avaje/avaje-http.git
   
 
diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml
index 1b9a1c37f..528cfe888 100644
--- a/tests/test-jex/pom.xml
+++ b/tests/test-jex/pom.xml
@@ -4,7 +4,7 @@
 
   org.example
   test-jex
-  1.12
+  1
 
   
     org.avaje
@@ -19,7 +19,7 @@
     2.0.8
     2.12.3
     6.1
-    1.12
+    1.13-SNAPSHOT
   
 
   
@@ -142,6 +142,7 @@
 
 
   
-    avaje-http-generator-parent-1.12
+    HEAD
+    scm:git:git@github.com:avaje/avaje-http.git
   
 

From ffc4ef0c675f7a94662f6c14a87bdeb449d362a9 Mon Sep 17 00:00:00 2001
From: Rob Bygrave 
Date: Tue, 26 Oct 2021 14:25:50 +1300
Subject: [PATCH 0219/1323] Bump to latest avaje-inject

---
 http-hibernate-validator/pom.xml                       | 10 +++++-----
 .../avaje/http/hibernate/validator/package-info.java   |  2 +-
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/http-hibernate-validator/pom.xml b/http-hibernate-validator/pom.xml
index f1f4a0b30..9ea068f58 100644
--- a/http-hibernate-validator/pom.xml
+++ b/http-hibernate-validator/pom.xml
@@ -4,12 +4,12 @@
 
   io.avaje
   avaje-http-hibernate-validator
-  2.5
+  2.6
 
   
     org.avaje
     java8-oss
-    3.1
+    3.2
   
 
   
@@ -34,14 +34,14 @@
     
       io.avaje
       avaje-http-api
-      1.4
+      1.12
       provided
     
 
     
       io.avaje
       avaje-inject
-      6.1
+      6.12
       provided
     
 
@@ -50,7 +50,7 @@
     
       io.avaje
       avaje-inject-generator
-      6.1
+      6.12
       provided
     
 
diff --git a/http-hibernate-validator/src/main/java/io/avaje/http/hibernate/validator/package-info.java b/http-hibernate-validator/src/main/java/io/avaje/http/hibernate/validator/package-info.java
index 5c1e02ecd..01ee5a58a 100644
--- a/http-hibernate-validator/src/main/java/io/avaje/http/hibernate/validator/package-info.java
+++ b/http-hibernate-validator/src/main/java/io/avaje/http/hibernate/validator/package-info.java
@@ -1,4 +1,4 @@
-@InjectModule(name = "bean-validator", provides = "validator")
+@InjectModule(name = "bean-validator", provides = io.avaje.http.api.Validator.class)
 package io.avaje.http.hibernate.validator;
 
 import io.avaje.inject.InjectModule;

From 377676303a8137846461e951890cb1afbed0c19b Mon Sep 17 00:00:00 2001
From: Rob Bygrave 
Date: Tue, 26 Oct 2021 14:30:05 +1300
Subject: [PATCH 0220/1323] Bump tests to use avaje-inject 6.12 (and bumped
 hibernate validator)

---
 tests/test-client/pom.xml                                  | 2 +-
 .../test-client/src/main/java/org/example/server/Main.java | 4 ++--
 tests/test-helidon/pom.xml                                 | 4 ++--
 tests/test-helidon/src/main/java/org/example/Main.java     | 5 +++--
 tests/test-javalin/pom.xml                                 | 6 +++---
 .../test-javalin/src/main/java/org/example/myapp/Main.java | 7 ++++---
 tests/test-jex/pom.xml                                     | 4 ++--
 tests/test-jex/src/main/java/org/example/Main.java         | 4 ++--
 tests/test-spark/pom.xml                                   | 6 +++---
 9 files changed, 22 insertions(+), 20 deletions(-)

diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml
index 771ed2e08..bb6c70815 100644
--- a/tests/test-client/pom.xml
+++ b/tests/test-client/pom.xml
@@ -15,7 +15,7 @@
   
     true
     1.6
-    6.1
+    6.12
   
 
   
diff --git a/tests/test-client/src/main/java/org/example/server/Main.java b/tests/test-client/src/main/java/org/example/server/Main.java
index 304c0ebad..f6467f02a 100644
--- a/tests/test-client/src/main/java/org/example/server/Main.java
+++ b/tests/test-client/src/main/java/org/example/server/Main.java
@@ -1,6 +1,5 @@
 package org.example.server;
 
-import io.avaje.inject.ApplicationScope;
 import io.avaje.inject.BeanScope;
 import io.avaje.jex.Jex;
 import io.avaje.jex.Routing;
@@ -14,7 +13,8 @@ public static void main(String[] args) {
   }
 
   public static Jex.Server start(int port) {
-    return start(port, ApplicationScope.scope());
+    BeanScope beanScope = BeanScope.newBuilder().build();
+    return start(port, beanScope);
   }
 
   public static Jex.Server start(int port, BeanScope context) {
diff --git a/tests/test-helidon/pom.xml b/tests/test-helidon/pom.xml
index df2d4a578..b9a471fff 100644
--- a/tests/test-helidon/pom.xml
+++ b/tests/test-helidon/pom.xml
@@ -40,12 +40,12 @@
     
       io.avaje
       avaje-inject
-      6.1
+      6.12
     
     
       io.avaje
       avaje-inject-generator
-      6.1
+      6.12
       provided
     
 
diff --git a/tests/test-helidon/src/main/java/org/example/Main.java b/tests/test-helidon/src/main/java/org/example/Main.java
index 18a392b87..664cda221 100644
--- a/tests/test-helidon/src/main/java/org/example/Main.java
+++ b/tests/test-helidon/src/main/java/org/example/Main.java
@@ -1,6 +1,6 @@
 package org.example;
 
-import io.avaje.inject.ApplicationScope;
+import io.avaje.inject.BeanScope;
 import io.helidon.health.HealthSupport;
 import io.helidon.media.jackson.JacksonSupport;
 import io.helidon.metrics.MetricsSupport;
@@ -58,7 +58,8 @@ private static Routing createRouting() {
       .register(MetricsSupport.create())
       .register("/greet", new GreetService());
 
-    ApplicationScope.list(Service.class).forEach(builder::register);
+    BeanScope beanScope = BeanScope.newBuilder().build();
+    beanScope.list(Service.class).forEach(builder::register);
 
     return builder.build();
   }
diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml
index f77e41876..898bda9ba 100644
--- a/tests/test-javalin/pom.xml
+++ b/tests/test-javalin/pom.xml
@@ -51,7 +51,7 @@
     
       io.avaje
       avaje-inject
-      6.1
+      6.12
     
 
     
@@ -63,7 +63,7 @@
     
       io.avaje
       avaje-http-hibernate-validator
-      2.5
+      2.6
     
 
     
@@ -77,7 +77,7 @@
     
       io.avaje
       avaje-inject-generator
-      6.1
+      6.12
       provided
     
 
diff --git a/tests/test-javalin/src/main/java/org/example/myapp/Main.java b/tests/test-javalin/src/main/java/org/example/myapp/Main.java
index e783363d1..1b69c32fc 100644
--- a/tests/test-javalin/src/main/java/org/example/myapp/Main.java
+++ b/tests/test-javalin/src/main/java/org/example/myapp/Main.java
@@ -1,7 +1,7 @@
 package org.example.myapp;
 
 import io.avaje.http.api.*;
-import io.avaje.inject.ApplicationScope;
+import io.avaje.inject.BeanScope;
 import io.avaje.inject.InjectModule;
 import io.javalin.Javalin;
 import io.javalin.http.staticfiles.Location;
@@ -14,7 +14,7 @@
 import java.util.List;
 import java.util.Map;
 
-@InjectModule(name = "app", dependsOn= "validator", requires = Validator.class)
+@InjectModule(name = "app", requires = Validator.class)
 @OpenAPIDefinition(info = @Info(title = "Example service", description = "Example Javalin controllers with Java and Maven"))
 public class Main {
 
@@ -68,7 +68,8 @@ public static Javalin start(int port) {
     });
 
     // All WebRoutes / Controllers ... from DI Context
-    List webRoutes = ApplicationScope.list(WebRoutes.class);
+    BeanScope beanScope = BeanScope.newBuilder().build();
+    List webRoutes = beanScope.list(WebRoutes.class);
     app.routes(() -> webRoutes.forEach(WebRoutes::registerRoutes));
 
     app.start(port);
diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml
index 528cfe888..274be86ad 100644
--- a/tests/test-jex/pom.xml
+++ b/tests/test-jex/pom.xml
@@ -18,7 +18,7 @@
     2.0
     2.0.8
     2.12.3
-    6.1
+    6.12
     1.13-SNAPSHOT
   
 
@@ -63,7 +63,7 @@
     
       io.avaje
       avaje-http-hibernate-validator
-      2.5
+      2.6
     
 
     
diff --git a/tests/test-jex/src/main/java/org/example/Main.java b/tests/test-jex/src/main/java/org/example/Main.java
index 23a6bccc7..466315a18 100644
--- a/tests/test-jex/src/main/java/org/example/Main.java
+++ b/tests/test-jex/src/main/java/org/example/Main.java
@@ -2,7 +2,6 @@
 
 import io.avaje.http.api.ValidationException;
 import io.avaje.http.api.Validator;
-import io.avaje.inject.ApplicationScope;
 import io.avaje.inject.BeanScope;
 import io.avaje.inject.InjectModule;
 import io.avaje.jex.Jex;
@@ -19,7 +18,8 @@ public static void main(String[] args) {
   }
 
   public static Jex.Server start(int port) {
-    return start(port, ApplicationScope.scope());
+    BeanScope beanScope = BeanScope.newBuilder().build();
+    return start(port, beanScope);
   }
 
   public static Jex.Server start(int port, BeanScope context) {
diff --git a/tests/test-spark/pom.xml b/tests/test-spark/pom.xml
index cd8024b65..dcbe44ffb 100644
--- a/tests/test-spark/pom.xml
+++ b/tests/test-spark/pom.xml
@@ -43,7 +43,7 @@
     
       io.avaje
       avaje-inject
-      6.1
+      6.12
     
 
     
@@ -55,7 +55,7 @@
     
       io.avaje
       avaje-http-hibernate-validator
-      2.5
+      2.6
     
 
     
@@ -69,7 +69,7 @@
     
       io.avaje
       avaje-inject-generator
-      6.1
+      6.12
       provided
     
 

From 83ca5db176b8786fe14cdcdb959b74e06530f226 Mon Sep 17 00:00:00 2001
From: Rob Bygrave 
Date: Thu, 28 Oct 2021 21:34:06 +1300
Subject: [PATCH 0221/1323] Fix whitespace in generated code only

---
 .../io/avaje/http/generator/helidon/ControllerWriter.java     | 4 ++--
 .../io/avaje/http/generator/javalin/ControllerWriter.java     | 4 ++--
 .../java/io/avaje/http/generator/jex/ControllerWriter.java    | 4 ++--
 3 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/ControllerWriter.java b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/ControllerWriter.java
index 75fb2d57d..e490d3fe4 100644
--- a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/ControllerWriter.java
+++ b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/ControllerWriter.java
@@ -80,9 +80,9 @@ private void writeClassStart() {
       writer.append(", Validator validator");
     }
     writer.append(") {").eol();
-    writer.append("   this.%s = %s;", controllerName, controllerName).eol();
+    writer.append("    this.%s = %s;", controllerName, controllerName).eol();
     if (reader.isIncludeValidator()) {
-      writer.append("   this.validator = validator;").eol();
+      writer.append("    this.validator = validator;").eol();
     }
     writer.append("  }").eol().eol();
   }
diff --git a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java
index c7bdc0d99..807146b19 100644
--- a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java
+++ b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java
@@ -66,9 +66,9 @@ private void writeClassStart() {
       writer.append(", Validator validator");
     }
     writer.append(") {").eol();
-    writer.append("   this.%s = %s;", controllerName, controllerName).eol();
+    writer.append("    this.%s = %s;", controllerName, controllerName).eol();
     if (reader.isIncludeValidator()) {
-      writer.append("   this.validator = validator;").eol();
+      writer.append("    this.validator = validator;").eol();
     }
     writer.append("  }").eol().eol();
   }
diff --git a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerWriter.java b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerWriter.java
index b95b966fc..dd5cb4ab0 100644
--- a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerWriter.java
+++ b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerWriter.java
@@ -68,9 +68,9 @@ private void writeClassStart() {
       writer.append(", Validator validator");
     }
     writer.append(") {").eol();
-    writer.append("   this.%s = %s;", controllerName, controllerName).eol();
+    writer.append("    this.%s = %s;", controllerName, controllerName).eol();
     if (reader.isIncludeValidator()) {
-      writer.append("   this.validator = validator;").eol();
+      writer.append("    this.validator = validator;").eol();
     }
     writer.append("  }").eol().eol();
   }

From c5a6de92c54c0e6e6712ba792225bb6a130bf997 Mon Sep 17 00:00:00 2001
From: Rob Bygrave 
Date: Thu, 28 Oct 2021 21:34:35 +1300
Subject: [PATCH 0222/1323] Make PathSegment final and tidy javadoc

---
 .../main/java/io/avaje/http/api/PathSegment.java    | 13 ++++---------
 .../java/io/avaje/http/api/PathTypeConversion.java  |  2 +-
 2 files changed, 5 insertions(+), 10 deletions(-)

diff --git a/http-api/src/main/java/io/avaje/http/api/PathSegment.java b/http-api/src/main/java/io/avaje/http/api/PathSegment.java
index 2d745a10f..03394f639 100644
--- a/http-api/src/main/java/io/avaje/http/api/PathSegment.java
+++ b/http-api/src/main/java/io/avaje/http/api/PathSegment.java
@@ -9,9 +9,8 @@
  * like chair;vendor=ikea;size=small.
  * 

* Matrix parameters are optional 'qualifiers' of the path segment. - *

*/ -public class PathSegment { +public final class PathSegment { private final String val; @@ -45,10 +44,8 @@ public PathSegment(String value) { * Return the main segment value. *

* For "chair" this returns "chair" - *

*

* For "chair;vendor=ikea;size=small" this returns "chair" - *

*/ public String val() { return val; @@ -58,13 +55,11 @@ public String val() { * Return a metric value for the given key. *

* For example, given "chair;vendor=ikea;size=small" - *

*

- * metric("vendor") returns "ikea". - *

+ * matrix("vendor") returns "ikea". * - * @param key The metric key - * @return The metric value if supplied or null + * @param key The matrix key + * @return The matrix value if supplied or null */ public String matrix(String key) { return matrixValues == null ? null : matrixValues.get(key); diff --git a/http-api/src/main/java/io/avaje/http/api/PathTypeConversion.java b/http-api/src/main/java/io/avaje/http/api/PathTypeConversion.java index b99c853f1..f05fc568d 100644 --- a/http-api/src/main/java/io/avaje/http/api/PathTypeConversion.java +++ b/http-api/src/main/java/io/avaje/http/api/PathTypeConversion.java @@ -9,7 +9,7 @@ *

* These methods are intended to be used by APT source generators. */ -public class PathTypeConversion { +public final class PathTypeConversion { /** * Return the value if non-null and otherwise the default value. From 654b71af8eb0198189a1714c2a4823fb568a1738 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Mon, 22 Nov 2021 17:36:19 +1300 Subject: [PATCH 0223/1323] #32 - Add headerAddIfAbsent() helper method --- .../avaje/http/client/DHttpClientRequest.java | 11 +++++++ .../avaje/http/client/HttpClientRequest.java | 9 ++++++ .../http/client/HelloControllerTest.java | 29 +++++++++++++++++++ 3 files changed, 49 insertions(+) diff --git a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java index dd6af4299..435086fe0 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java +++ b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java @@ -105,6 +105,14 @@ public HttpClientRequest requestTimeout(Duration requestTimeout) { return this; } + @Override + public HttpClientRequest headerAddIfAbsent(String name, Object value) { + if (headers == null || !headers.containsKey(name)) { + header(name, value); + } + return this; + } + @Override public HttpClientRequest header(String name, String value) { if (headers == null) { @@ -131,6 +139,9 @@ public HttpClientRequest header(Map headers) { @Override public List header(String name) { + if (headers == null) { + return Collections.emptyList(); + } final List values = headers.get(name); return values == null ? Collections.emptyList() : values; } diff --git a/http-client/client/src/main/java/io/avaje/http/client/HttpClientRequest.java b/http-client/client/src/main/java/io/avaje/http/client/HttpClientRequest.java index c837b7344..90054a81c 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/HttpClientRequest.java +++ b/http-client/client/src/main/java/io/avaje/http/client/HttpClientRequest.java @@ -90,6 +90,15 @@ public interface HttpClientRequest { */ HttpClientRequest requestTimeout(Duration requestTimeout); + /** + * Add the header to the request but only if there is no existing value for the given header. + * + * @param name The header name + * @param value The header value + * @return The request being built + */ + HttpClientRequest headerAddIfAbsent(String name, Object value); + /** * Add the header to the request. * diff --git a/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java b/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java index 9eaaefd96..6c594bd54 100644 --- a/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java +++ b/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java @@ -432,6 +432,35 @@ void asString_readInvalidResponse() { assertThat(errorMap.get("email")).isEqualTo("must be a well-formed email address"); } + @Test + void headers_get_whenEmpty() { + final HttpClientRequest request = clientContext.request(); + + List headers = request.header("x-client-id"); + if (headers.isEmpty()) { + request.header("x-client-id", "42"); + } + assertThat(request.header("x-client-id")).containsExactly("42"); + } + + @Test + void headers_headerAddIfAbsent_whenEmpty() { + final HttpClientRequest request = clientContext.request(); + assertThat(request.header("x-client-id")).isEmpty(); + + request.headerAddIfAbsent("x-client-id", "42"); + assertThat(request.header("x-client-id")).containsExactly("42"); + } + + @Test + void headers_headerAddIfAbsent_whenAlreadySet() { + final HttpClientRequest request = clientContext.request(); + request.header("x-client-id", "someValue"); + + request.headerAddIfAbsent("x-client-id", "42"); + assertThat(request.header("x-client-id")).containsExactly("someValue"); + } + @Test void headers() { final HttpClientRequest request = clientContext.request(); From c11d63df214198c870d660b2f10dde90d7d6aee4 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Mon, 22 Nov 2021 17:47:19 +1300 Subject: [PATCH 0224/1323] bump test dependencies --- http-client/client/pom.xml | 14 +++++++------- .../example/webserver/HelloController$Route.java | 12 ++++++------ .../org/example/webserver/HelloController.java | 2 +- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/http-client/client/pom.xml b/http-client/client/pom.xml index 3c40e91cc..cb9d54593 100644 --- a/http-client/client/pom.xml +++ b/http-client/client/pom.xml @@ -34,37 +34,37 @@ - org.avaje.composite + io.avaje junit - 5.0 + 1.0 test io.javalin javalin - 3.9.1 + 4.1.1 test io.avaje avaje-inject - 4.1 + 6.12 test io.avaje avaje-http-api - 1.9 + 1.12 test io.avaje avaje-http-hibernate-validator - 2.0 + 2.6 test @@ -80,7 +80,7 @@ io.avaje avaje-inject-generator - 4.1 + 6.12 test diff --git a/http-client/client/src/test/java/org/example/webserver/HelloController$Route.java b/http-client/client/src/test/java/org/example/webserver/HelloController$Route.java index fa7a6a3a3..782f5f93f 100644 --- a/http-client/client/src/test/java/org/example/webserver/HelloController$Route.java +++ b/http-client/client/src/test/java/org/example/webserver/HelloController$Route.java @@ -12,7 +12,7 @@ import static io.avaje.http.api.PathTypeConversion.asLocalDate; import static io.avaje.http.api.PathTypeConversion.toLocalDate; -@Singleton +//@Singleton public class HelloController$Route implements WebRoutes { private final HelloController controller; @@ -47,7 +47,7 @@ public void registerRoutes() { controller.stream(ctx); }); - ApiBuilder.get("/hello/:id/:date", ctx -> { + ApiBuilder.get("/hello/{id}/{date}", ctx -> { ctx.status(200); int id = asInt(ctx.pathParam("id")); LocalDate date = asLocalDate(ctx.pathParam("date")); @@ -55,7 +55,7 @@ public void registerRoutes() { ctx.json(controller.hello(id, date, otherParam)); }); - ApiBuilder.get("/hello/findbyname/:name", ctx -> { + ApiBuilder.get("/hello/findbyname/{name}", ctx -> { ctx.status(200); String name = ctx.pathParam("name"); String otherParam = ctx.queryParam("otherParam"); @@ -69,7 +69,7 @@ public void registerRoutes() { ctx.json(controller.post(dto)); }); - ApiBuilder.post("/hello/savebean/:foo", ctx -> { + ApiBuilder.post("/hello/savebean/{foo}", ctx -> { ctx.status(201); String foo = ctx.pathParam("foo"); HelloDto dto = ctx.bodyAsClass(HelloDto.class); @@ -116,13 +116,13 @@ public void registerRoutes() { ctx.json(controller.getAll()); }); - ApiBuilder.delete("/hello/:id", ctx -> { + ApiBuilder.delete("/hello/{id}", ctx -> { ctx.status(204); int id = asInt(ctx.pathParam("id")); controller.deleteById(id); }); - ApiBuilder.get("/hello/withMatrix/:year_segment/:other", ctx -> { + ApiBuilder.get("/hello/withMatrix/{year_segment}/{other}", ctx -> { ctx.status(200); PathSegment year_segment = PathSegment.of(ctx.pathParam("year_segment")); int year = asInt(year_segment.val()); diff --git a/http-client/client/src/test/java/org/example/webserver/HelloController.java b/http-client/client/src/test/java/org/example/webserver/HelloController.java index 45feb95e2..63256abb6 100644 --- a/http-client/client/src/test/java/org/example/webserver/HelloController.java +++ b/http-client/client/src/test/java/org/example/webserver/HelloController.java @@ -20,7 +20,7 @@ */ //@Hidden @Valid -@Controller +//@Controller @Path("/hello") class HelloController { From e91eda8e881002bf0650f9a6137c04fdc0be019d Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Mon, 22 Nov 2021 22:24:34 +1300 Subject: [PATCH 0225/1323] [maven-release-plugin] prepare release avaje-http-client-1.12 --- http-client/client/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/http-client/client/pom.xml b/http-client/client/pom.xml index cb9d54593..d121616b7 100644 --- a/http-client/client/pom.xml +++ b/http-client/client/pom.xml @@ -9,11 +9,11 @@ io.avaje avaje-http-client - 1.12-SNAPSHOT + 1.12 scm:git:git@github.com:avaje/avaje-http-client.git - HEAD + avaje-http-client-1.12 From 2ea07c434e833d97d634f6f297c7ef0a88e4c4f0 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Mon, 22 Nov 2021 22:24:40 +1300 Subject: [PATCH 0226/1323] [maven-release-plugin] prepare for next development iteration --- http-client/client/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/http-client/client/pom.xml b/http-client/client/pom.xml index d121616b7..b5a475ea3 100644 --- a/http-client/client/pom.xml +++ b/http-client/client/pom.xml @@ -9,11 +9,11 @@ io.avaje avaje-http-client - 1.12 + 1.13-SNAPSHOT scm:git:git@github.com:avaje/avaje-http-client.git - avaje-http-client-1.12 + HEAD From 6fee2fa0e8d505bde06f95b1a7b47ba5186d43f2 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Mon, 22 Nov 2021 22:28:59 +1300 Subject: [PATCH 0227/1323] bump dependencies --- http-client/gson-adapter/pom.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/http-client/gson-adapter/pom.xml b/http-client/gson-adapter/pom.xml index f9722ab44..8f9f71fca 100644 --- a/http-client/gson-adapter/pom.xml +++ b/http-client/gson-adapter/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-client-gson - 1.11 + 1.12 scm:git:git@github.com:avaje/avaje-http-client.git @@ -21,22 +21,22 @@ com.google.code.gson gson - 2.8.7 + 2.8.9 io.avaje avaje-http-client - 1.11 + 1.12 provided - org.avaje.composite + io.avaje junit - 5.0 + 1.0 test From ad06a28babbc050b027538be9a3bf23676903f94 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 23 Nov 2021 09:57:34 +1300 Subject: [PATCH 0228/1323] update test pom --- http-client/gson-adapter/pom.xml | 2 +- http-client/test/pom.xml | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/http-client/gson-adapter/pom.xml b/http-client/gson-adapter/pom.xml index 8f9f71fca..e8fc8d999 100644 --- a/http-client/gson-adapter/pom.xml +++ b/http-client/gson-adapter/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-client-gson - 1.12 + 1.13-SNAPSHOT scm:git:git@github.com:avaje/avaje-http-client.git diff --git a/http-client/test/pom.xml b/http-client/test/pom.xml index c5a9aaf16..5548d4302 100644 --- a/http-client/test/pom.xml +++ b/http-client/test/pom.xml @@ -16,31 +16,31 @@ io.avaje avaje-http-client - 1.12-SNAPSHOT + 1.13-SNAPSHOT io.avaje avaje-http-client-gson - 1.11 + 1.13-SNAPSHOT io.avaje avaje-http-api - 1.7 + 1.12 com.fasterxml.jackson.core jackson-databind - 2.12.2 + 2.12.5 - org.avaje.composite + io.avaje junit - 5.0 + 1.0 test From 7d7a6afc104d606a9f52df69faa9683d651c334f Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Thu, 25 Nov 2021 13:34:18 +1300 Subject: [PATCH 0229/1323] #33 - Add support for using avaje-jsonb to serialise to/from json content --- http-client/client/pom.xml | 16 +++ .../io/avaje/http/client/BodyAdapter.java | 2 +- .../java/io/avaje/http/client/BodyWriter.java | 6 +- .../avaje/http/client/DHttpClientContext.java | 2 +- .../avaje/http/client/JacksonBodyAdapter.java | 17 ++- .../avaje/http/client/JsonbBodyAdapter.java | 100 ++++++++++++++++++ .../client/src/main/java/module-info.java | 1 + .../io/avaje/http/client/DHttpApiTest.java | 24 +++++ .../java/org/example/github/GithubTest.java | 1 - .../test/java/org/example/github/Repo.java | 3 + .../org/example/github/RepoJsonAdapter.java | 83 +++++++++++++++ 11 files changed, 240 insertions(+), 15 deletions(-) create mode 100644 http-client/client/src/main/java/io/avaje/http/client/JsonbBodyAdapter.java create mode 100644 http-client/client/src/test/java/org/example/github/RepoJsonAdapter.java diff --git a/http-client/client/pom.xml b/http-client/client/pom.xml index b5a475ea3..a796299f8 100644 --- a/http-client/client/pom.xml +++ b/http-client/client/pom.xml @@ -31,6 +31,13 @@ true + + io.avaje + avaje-jsonb + 0.5 + true + + @@ -84,6 +91,13 @@ test + + + + + + + @@ -94,11 +108,13 @@ --add-modules com.fasterxml.jackson.databind + --add-modules io.avaje.jsonb --add-opens io.avaje.http.client/io.avaje.http.client=ALL-UNNAMED --add-opens io.avaje.http.client/org.example.webserver=ALL-UNNAMED --add-opens io.avaje.http.client/org.example.github=ALL-UNNAMED --add-opens io.avaje.http.client/org.example.webserver=com.fasterxml.jackson.databind --add-opens io.avaje.http.client/org.example.github=com.fasterxml.jackson.databind + --add-opens io.avaje.http.client/org.example.github=io.avaje.jsonb diff --git a/http-client/client/src/main/java/io/avaje/http/client/BodyAdapter.java b/http-client/client/src/main/java/io/avaje/http/client/BodyAdapter.java index 7306887b8..3c0ffa4ea 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/BodyAdapter.java +++ b/http-client/client/src/main/java/io/avaje/http/client/BodyAdapter.java @@ -14,7 +14,7 @@ public interface BodyAdapter { * * @param type The type of the bean this writer is for */ - BodyWriter beanWriter(Class type); + BodyWriter beanWriter(Class type); /** * Return a BodyReader to read response content and convert to a bean. diff --git a/http-client/client/src/main/java/io/avaje/http/client/BodyWriter.java b/http-client/client/src/main/java/io/avaje/http/client/BodyWriter.java index 65fc9f27e..c306b4a67 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/BodyWriter.java +++ b/http-client/client/src/main/java/io/avaje/http/client/BodyWriter.java @@ -3,7 +3,7 @@ /** * Writes beans as content for a specific content type. */ -public interface BodyWriter { +public interface BodyWriter { /** * Write the bean as content using the default content type. @@ -11,7 +11,7 @@ public interface BodyWriter { * Used when all beans sent via POST, PUT, PATCH will be sent as * a single content type like application/json; charset=utf8. */ - BodyContent write(Object bean); + BodyContent write(T bean); /** * Write the bean as content with the requested content type. @@ -19,6 +19,6 @@ public interface BodyWriter { * The writer is expected to use the given contentType to determine * how to write the bean as content. */ - BodyContent write(Object bean, String contentType); + BodyContent write(T bean, String contentType); } diff --git a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContext.java b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContext.java index a830e872d..d44602d69 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContext.java +++ b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContext.java @@ -176,7 +176,7 @@ CompletableFuture> sendAsync(HttpRequest.Builder requestBuil return httpClient.sendAsync(requestBuilder.build(), bodyHandler); } - BodyContent write(Object bean, String contentType) { + BodyContent write(T bean, String contentType) { return bodyAdapter.beanWriter(bean.getClass()).write(bean, contentType); } diff --git a/http-client/client/src/main/java/io/avaje/http/client/JacksonBodyAdapter.java b/http-client/client/src/main/java/io/avaje/http/client/JacksonBodyAdapter.java index a6c959dac..1b0ab483a 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/JacksonBodyAdapter.java +++ b/http-client/client/src/main/java/io/avaje/http/client/JacksonBodyAdapter.java @@ -25,10 +25,8 @@ public class JacksonBodyAdapter implements BodyAdapter { private final ObjectMapper mapper; - private final ConcurrentHashMap, BodyWriter> beanWriterCache = new ConcurrentHashMap<>(); - + private final ConcurrentHashMap, BodyWriter> beanWriterCache = new ConcurrentHashMap<>(); private final ConcurrentHashMap, BodyReader> beanReaderCache = new ConcurrentHashMap<>(); - private final ConcurrentHashMap, BodyReader> listReaderCache = new ConcurrentHashMap<>(); /** @@ -49,11 +47,12 @@ public JacksonBodyAdapter() { .setSerializationInclusion(JsonInclude.Include.NON_EMPTY); } + @SuppressWarnings("unchecked") @Override - public BodyWriter beanWriter(Class cls) { - return beanWriterCache.computeIfAbsent(cls, aClass -> { + public BodyWriter beanWriter(Class cls) { + return (BodyWriter)beanWriterCache.computeIfAbsent(cls, aClass -> { try { - return new JWriter(mapper.writerFor(cls)); + return new JWriter<>(mapper.writerFor(cls)); } catch (Exception e) { throw new RuntimeException(e); } @@ -113,7 +112,7 @@ public T read(BodyContent bodyContent) { } } - private static class JWriter implements BodyWriter { + private static class JWriter implements BodyWriter { private final ObjectWriter writer; @@ -122,14 +121,14 @@ public JWriter(ObjectWriter writer) { } @Override - public BodyContent write(Object bean, String contentType) { + public BodyContent write(T bean, String contentType) { // ignoring the requested contentType and always // writing the body as json content return write(bean); } @Override - public BodyContent write(Object bean) { + public BodyContent write(T bean) { try { return BodyContent.asJson(writer.writeValueAsBytes(bean)); } catch (JsonProcessingException e) { diff --git a/http-client/client/src/main/java/io/avaje/http/client/JsonbBodyAdapter.java b/http-client/client/src/main/java/io/avaje/http/client/JsonbBodyAdapter.java new file mode 100644 index 000000000..e04a0dc7b --- /dev/null +++ b/http-client/client/src/main/java/io/avaje/http/client/JsonbBodyAdapter.java @@ -0,0 +1,100 @@ +package io.avaje.http.client; + +import io.avaje.jsonb.JsonType; +import io.avaje.jsonb.Jsonb; + +import java.util.List; +import java.util.concurrent.ConcurrentHashMap; + +/** + * avaje jsonb BodyAdapter to read and write beans as JSON. + * + *

{@code
+ *
+ *   HttpClientContext.newBuilder()
+ *       .baseUrl(baseUrl)
+ *       .bodyAdapter(new JsonbBodyAdapter())
+ *       .build();
+ *
+ * }
+ */ +public class JsonbBodyAdapter implements BodyAdapter { + + private final Jsonb jsonb; + private final ConcurrentHashMap, BodyWriter> beanWriterCache = new ConcurrentHashMap<>(); + private final ConcurrentHashMap, BodyReader> beanReaderCache = new ConcurrentHashMap<>(); + private final ConcurrentHashMap, BodyReader> listReaderCache = new ConcurrentHashMap<>(); + + /** + * Create passing the Jsonb to use. + */ + public JsonbBodyAdapter(Jsonb jsonb) { + this.jsonb = jsonb; + } + + /** + * Create with a default Jsonb that allows unknown properties. + */ + public JsonbBodyAdapter() { + this.jsonb = Jsonb.newBuilder().build(); + } + + @SuppressWarnings("unchecked") + @Override + public BodyWriter beanWriter(Class cls) { + return (BodyWriter) beanWriterCache.computeIfAbsent(cls, aClass -> new JWriter<>(jsonb.type(cls))); + } + + @SuppressWarnings("unchecked") + @Override + public BodyReader beanReader(Class cls) { + return (BodyReader) beanReaderCache.computeIfAbsent(cls, aClass -> new JReader<>(jsonb.type(cls))); + } + + @SuppressWarnings("unchecked") + @Override + public BodyReader> listReader(Class cls) { + return (BodyReader>) listReaderCache.computeIfAbsent(cls, aClass -> new JReader<>(jsonb.type(cls).list())); + } + + private static class JReader implements BodyReader { + + private final JsonType reader; + + JReader(JsonType reader) { + this.reader = reader; + } + + @Override + public T readBody(String content) { + return reader.fromJson(content); + } + + @Override + public T read(BodyContent bodyContent) { + return reader.fromJson(bodyContent.content()); + } + } + + private static class JWriter implements BodyWriter { + + private final JsonType writer; + + public JWriter(JsonType writer) { + this.writer = writer; + } + + @Override + public BodyContent write(T bean, String contentType) { + // ignoring the requested contentType and always + // writing the body as json content + return write(bean); + } + + @Override + public BodyContent write(T bean) { + return BodyContent.asJson(writer.toJsonBytes(bean)); + } + } + +} diff --git a/http-client/client/src/main/java/module-info.java b/http-client/client/src/main/java/module-info.java index 385d4f19a..2f77bbc8a 100644 --- a/http-client/client/src/main/java/module-info.java +++ b/http-client/client/src/main/java/module-info.java @@ -5,6 +5,7 @@ requires transitive java.net.http; requires transitive org.slf4j; requires static com.fasterxml.jackson.databind; + requires static io.avaje.jsonb; exports io.avaje.http.client; } diff --git a/http-client/client/src/test/java/io/avaje/http/client/DHttpApiTest.java b/http-client/client/src/test/java/io/avaje/http/client/DHttpApiTest.java index cee2051e3..0e5e1abea 100644 --- a/http-client/client/src/test/java/io/avaje/http/client/DHttpApiTest.java +++ b/http-client/client/src/test/java/io/avaje/http/client/DHttpApiTest.java @@ -1,8 +1,11 @@ package io.avaje.http.client; +import io.avaje.jsonb.Jsonb; import org.example.github.Repo; import org.example.github.Simple; import org.example.github.httpclient.Simple$HttpClient; +import org.example.github.RepoJsonAdapter; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import java.util.List; @@ -11,6 +14,7 @@ public class DHttpApiTest { + @Disabled @Test void test_github_listRepos() { @@ -27,4 +31,24 @@ void test_github_listRepos() { assertThat(repos).isNotEmpty(); } + @Test + void jsonb_github_listRepos() { + + Jsonb jsonb = Jsonb.newBuilder() + .add(Repo.class, RepoJsonAdapter::new) + .build(); + + final HttpClientContext clientContext = HttpClientContext.newBuilder() + .baseUrl("https://api.github.com") + .bodyAdapter(new JsonbBodyAdapter(jsonb)) + .build(); + + DHttpApi httpApi = new DHttpApi(); + httpApi.addProvider(new Simple$HttpClient.Provider()); + final Simple simple = httpApi.provideFor(Simple.class, clientContext); + + final List repos = simple.listRepos("rbygrave", "junk"); + assertThat(repos).isNotEmpty(); + } + } diff --git a/http-client/client/src/test/java/org/example/github/GithubTest.java b/http-client/client/src/test/java/org/example/github/GithubTest.java index bb9521eb3..c464e1e1b 100644 --- a/http-client/client/src/test/java/org/example/github/GithubTest.java +++ b/http-client/client/src/test/java/org/example/github/GithubTest.java @@ -2,7 +2,6 @@ import io.avaje.http.client.HttpClientContext; import io.avaje.http.client.JacksonBodyAdapter; -import io.avaje.http.client.RequestLogger; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; diff --git a/http-client/client/src/test/java/org/example/github/Repo.java b/http-client/client/src/test/java/org/example/github/Repo.java index a2823f8f8..6803db85b 100644 --- a/http-client/client/src/test/java/org/example/github/Repo.java +++ b/http-client/client/src/test/java/org/example/github/Repo.java @@ -1,5 +1,8 @@ package org.example.github; +//import io.avaje.jsonb.Json; + +//@Json public class Repo { public long id; public String name; diff --git a/http-client/client/src/test/java/org/example/github/RepoJsonAdapter.java b/http-client/client/src/test/java/org/example/github/RepoJsonAdapter.java new file mode 100644 index 000000000..69e5b2ab2 --- /dev/null +++ b/http-client/client/src/test/java/org/example/github/RepoJsonAdapter.java @@ -0,0 +1,83 @@ +package org.example.github; + +import io.avaje.jsonb.JsonAdapter; +import io.avaje.jsonb.JsonReader; +import io.avaje.jsonb.JsonWriter; +import io.avaje.jsonb.Jsonb; +import io.avaje.jsonb.spi.PropertyNames; +import io.avaje.jsonb.spi.ViewBuilder; +import io.avaje.jsonb.spi.ViewBuilderAware; + +import java.lang.invoke.MethodHandle; + +public class RepoJsonAdapter extends JsonAdapter implements ViewBuilderAware { + + // naming convention Match + // id [long] name:id publicField + // name [java.lang.String] name:name publicField + + private final JsonAdapter plongJsonAdapter; + private final JsonAdapter stringJsonAdapter; + private final PropertyNames names; + + public RepoJsonAdapter(Jsonb jsonb) { + this.plongJsonAdapter = jsonb.adapter(Long.TYPE); + this.stringJsonAdapter = jsonb.adapter(String.class); + this.names = jsonb.properties("id", "name"); + } + + @Override + public boolean isViewBuilderAware() { + return true; + } + + @Override + public ViewBuilderAware viewBuild() { + return this; + } + + @Override + public void build(ViewBuilder builder, String name, MethodHandle handle) { + builder.beginObject(name, handle); + builder.add("id", plongJsonAdapter, builder.field(Repo.class, "id")); + builder.add("name", stringJsonAdapter, builder.field(Repo.class, "name")); + builder.endObject(); + } + + @Override + public void toJson(JsonWriter writer, Repo repo) { + writer.beginObject(); + writer.names(names); + writer.name(0); + plongJsonAdapter.toJson(writer, repo.id); + writer.name(1); + stringJsonAdapter.toJson(writer, repo.name); + writer.endObject(); + } + + @Override + public Repo fromJson(JsonReader reader) { + Repo _$repo = new Repo(); + + // read json + reader.beginObject(); + while (reader.hasNextField()) { + String fieldName = reader.nextField(); + switch (fieldName) { + case "id": { + _$repo.id = plongJsonAdapter.fromJson(reader); break; + } + case "name": { + _$repo.name = stringJsonAdapter.fromJson(reader); break; + } + default: { + reader.unmappedField(fieldName); + reader.skipValue(); + } + } + } + reader.endObject(); + + return _$repo; + } +} From 152dc57107f77286ab9493aa6939bebca1724061 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Thu, 25 Nov 2021 14:02:02 +1300 Subject: [PATCH 0230/1323] [maven-release-plugin] prepare release avaje-http-client-1.13 --- http-client/client/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/http-client/client/pom.xml b/http-client/client/pom.xml index a796299f8..630c5a83f 100644 --- a/http-client/client/pom.xml +++ b/http-client/client/pom.xml @@ -9,11 +9,11 @@ io.avaje avaje-http-client - 1.13-SNAPSHOT + 1.13 scm:git:git@github.com:avaje/avaje-http-client.git - HEAD + avaje-http-client-1.13 From 0b592607861334a6939006a8a12deaa2593da86a Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Thu, 25 Nov 2021 14:02:07 +1300 Subject: [PATCH 0231/1323] [maven-release-plugin] prepare for next development iteration --- http-client/client/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/http-client/client/pom.xml b/http-client/client/pom.xml index 630c5a83f..f4932bfd4 100644 --- a/http-client/client/pom.xml +++ b/http-client/client/pom.xml @@ -9,11 +9,11 @@ io.avaje avaje-http-client - 1.13 + 1.14-SNAPSHOT scm:git:git@github.com:avaje/avaje-http-client.git - avaje-http-client-1.13 + HEAD From 397235379c274d47d2508b68b4c3c77ab2abe513 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Thu, 25 Nov 2021 14:13:19 +1300 Subject: [PATCH 0232/1323] Support 1.13 API with BodyWriter --- http-client/gson-adapter/pom.xml | 4 +- .../http/client/gson/GsonBodyAdapter.java | 39 ++++++++----------- 2 files changed, 18 insertions(+), 25 deletions(-) diff --git a/http-client/gson-adapter/pom.xml b/http-client/gson-adapter/pom.xml index e8fc8d999..13fb408a1 100644 --- a/http-client/gson-adapter/pom.xml +++ b/http-client/gson-adapter/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-client-gson - 1.13-SNAPSHOT + 1.13 scm:git:git@github.com:avaje/avaje-http-client.git @@ -27,7 +27,7 @@ io.avaje avaje-http-client - 1.12 + 1.13 provided diff --git a/http-client/gson-adapter/src/main/java/io/avaje/http/client/gson/GsonBodyAdapter.java b/http-client/gson-adapter/src/main/java/io/avaje/http/client/gson/GsonBodyAdapter.java index 238dc3756..9de20dd31 100644 --- a/http-client/gson-adapter/src/main/java/io/avaje/http/client/gson/GsonBodyAdapter.java +++ b/http-client/gson-adapter/src/main/java/io/avaje/http/client/gson/GsonBodyAdapter.java @@ -10,11 +10,7 @@ import io.avaje.http.client.BodyReader; import io.avaje.http.client.BodyWriter; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.OutputStreamWriter; +import java.io.*; import java.util.List; import java.util.concurrent.ConcurrentHashMap; @@ -38,10 +34,8 @@ public class GsonBodyAdapter implements BodyAdapter { private final Gson gson; - private final ConcurrentHashMap, BodyWriter> beanWriterCache = new ConcurrentHashMap<>(); - + private final ConcurrentHashMap, BodyWriter> beanWriterCache = new ConcurrentHashMap<>(); private final ConcurrentHashMap, BodyReader> beanReaderCache = new ConcurrentHashMap<>(); - private final ConcurrentHashMap, BodyReader> listReaderCache = new ConcurrentHashMap<>(); /** @@ -51,11 +45,12 @@ public GsonBodyAdapter(Gson gson) { this.gson = gson; } + @SuppressWarnings({"unchecked", "rawtypes"}) @Override - public BodyWriter beanWriter(Class cls) { - return beanWriterCache.computeIfAbsent(cls, aClass -> { + public BodyWriter beanWriter(Class cls) { + return (BodyWriter) beanWriterCache.computeIfAbsent(cls, aClass -> { try { - final TypeAdapter adapter = gson.getAdapter(cls); + final TypeAdapter adapter = gson.getAdapter(cls); return new Writer(gson, adapter); } catch (Exception e) { throw new RuntimeException(e); @@ -76,14 +71,14 @@ public BodyReader beanReader(Class cls) { }); } - @SuppressWarnings("unchecked") + @SuppressWarnings({"unchecked", "rawtypes"}) @Override public BodyReader> listReader(Class cls) { return (BodyReader>) listReaderCache.computeIfAbsent(cls, aClass -> { try { - final TypeToken listType = TypeToken.getParameterized(List.class, cls); - final TypeAdapter adapter = gson.getAdapter(listType); - return new Reader(gson, adapter); + final TypeToken listType = TypeToken.getParameterized(List.class, cls); + final TypeAdapter> adapter = gson.getAdapter(listType); + return new Reader<>(gson, adapter); } catch (Exception e) { throw new RuntimeException(e); } @@ -114,8 +109,7 @@ public T readBody(String content) { @Override public T read(BodyContent body) { - try { - InputStreamReader reader = new InputStreamReader(new ByteArrayInputStream(body.content())); + try (InputStreamReader reader = new InputStreamReader(new ByteArrayInputStream(body.content()))) { final JsonReader jsonReader = gson.newJsonReader(reader); return adapter.read(jsonReader); } catch (IOException e) { @@ -124,24 +118,23 @@ public T read(BodyContent body) { } } - @SuppressWarnings({"rawtypes"}) - private static class Writer implements BodyWriter { + private static class Writer implements BodyWriter { private final Gson gson; - private final TypeAdapter adapter; + private final TypeAdapter adapter; - Writer(Gson gson, TypeAdapter adapter) { + Writer(Gson gson, TypeAdapter adapter) { this.gson = gson; this.adapter = adapter; } @Override - public BodyContent write(Object bean, String contentType) { + public BodyContent write(T bean, String contentType) { return write(bean); } @Override - public BodyContent write(Object bean) { + public BodyContent write(T bean) { try { ByteArrayOutputStream os = new ByteArrayOutputStream(200); JsonWriter jsonWriter = gson.newJsonWriter(new OutputStreamWriter(os, UTF_8)); From 0bc5cf45ac49c772a15d2451357c20d064d8b1bb Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Thu, 25 Nov 2021 16:37:47 +1300 Subject: [PATCH 0233/1323] add git workflow --- http-client/.github/workflows/build.yml | 36 +++++++++++++++++++++++++ http-client/gson-adapter/pom.xml | 4 +-- 2 files changed, 38 insertions(+), 2 deletions(-) create mode 100644 http-client/.github/workflows/build.yml diff --git a/http-client/.github/workflows/build.yml b/http-client/.github/workflows/build.yml new file mode 100644 index 000000000..9a8047eeb --- /dev/null +++ b/http-client/.github/workflows/build.yml @@ -0,0 +1,36 @@ + +name: Build + +on: [push, pull_request] + +jobs: + build: + + runs-on: ${{ matrix.os }} + permissions: + contents: read + packages: write + strategy: + fail-fast: false + matrix: + java_version: [17] + os: [ubuntu-latest] + + steps: + - uses: actions/checkout@v2 + - name: Set up Java + uses: actions/setup-java@v2 + with: + java-version: ${{ matrix.java_version }} + distribution: 'adopt' + - name: Maven cache + uses: actions/cache@v2 + env: + cache-name: maven-cache + with: + path: + ~/.m2 + key: build-${{ env.cache-name }} + - name: Build with Maven + run: mvn verify + diff --git a/http-client/gson-adapter/pom.xml b/http-client/gson-adapter/pom.xml index 13fb408a1..059bf3c64 100644 --- a/http-client/gson-adapter/pom.xml +++ b/http-client/gson-adapter/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-client-gson - 1.13 + 1.13-SNAPSHOT scm:git:git@github.com:avaje/avaje-http-client.git @@ -27,7 +27,7 @@ io.avaje avaje-http-client - 1.13 + 1.13-SNAPSHOT provided From 862f78080ab071e2def5833ea13458825d9f4763 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Thu, 25 Nov 2021 16:39:54 +1300 Subject: [PATCH 0234/1323] Update README --- http-client/README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/http-client/README.md b/http-client/README.md index ae42f261f..96e3d82ba 100644 --- a/http-client/README.md +++ b/http-client/README.md @@ -1,3 +1,7 @@ +[![Build](https://github.com/avaje/avaje-http-client/actions/workflows/build.yml/badge.svg)](https://github.com/avaje/avaje-http-client/actions/workflows/build.yml) +[![Maven Central](https://img.shields.io/maven-central/v/io.avaje/avaje-http-client.svg?label=Maven%20Central)](https://mvnrepository.com/artifact/io.avaje/avaje-http-client) +[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://github.com/avaje/avaje-http-client/blob/master/LICENSE) + # avaje-http-client Documentation at [avaje.io/http-client](https://avaje.io/http-client/) @@ -20,7 +24,7 @@ A lightweight wrapper to the [JDK 11+ Java Http Client](http://openjdk.java.net/ io.avaje avaje-http-client - 1.11 + 1.12 ``` From 1fdb791e2e09578661ed63801bcb3dd2281396e1 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Thu, 25 Nov 2021 16:42:41 +1300 Subject: [PATCH 0235/1323] bump parent pom to java11-oss 3.3 --- http-client/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/http-client/pom.xml b/http-client/pom.xml index 79d059d20..7a53d9311 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,7 +4,7 @@ java11-oss org.avaje - 3.2 + 3.3 io.avaje From 63a7fa78c5b00c20a85e2f1018d42ab70d1d5475 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Thu, 25 Nov 2021 18:04:57 +1300 Subject: [PATCH 0236/1323] bump parent pom to java11-oss 3.3 --- http-client/client/pom.xml | 2 +- http-client/gson-adapter/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/http-client/client/pom.xml b/http-client/client/pom.xml index f4932bfd4..5cd600b89 100644 --- a/http-client/client/pom.xml +++ b/http-client/client/pom.xml @@ -4,7 +4,7 @@ java11-oss org.avaje - 3.2 + 3.3 io.avaje diff --git a/http-client/gson-adapter/pom.xml b/http-client/gson-adapter/pom.xml index 059bf3c64..2d41e8d59 100644 --- a/http-client/gson-adapter/pom.xml +++ b/http-client/gson-adapter/pom.xml @@ -4,7 +4,7 @@ java11-oss org.avaje - 3.2 + 3.3 io.avaje From 58d4a52cc07d3997d6af316788879e632ae97405 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Thu, 25 Nov 2021 18:33:24 +1300 Subject: [PATCH 0237/1323] bump poms to 1.14-SNAPSHOT --- http-client/gson-adapter/pom.xml | 4 ++-- http-client/test/pom.xml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/http-client/gson-adapter/pom.xml b/http-client/gson-adapter/pom.xml index 2d41e8d59..21a3a61d8 100644 --- a/http-client/gson-adapter/pom.xml +++ b/http-client/gson-adapter/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-client-gson - 1.13-SNAPSHOT + 1.14-SNAPSHOT scm:git:git@github.com:avaje/avaje-http-client.git @@ -27,7 +27,7 @@ io.avaje avaje-http-client - 1.13-SNAPSHOT + 1.14-SNAPSHOT provided diff --git a/http-client/test/pom.xml b/http-client/test/pom.xml index 5548d4302..a0a80cb32 100644 --- a/http-client/test/pom.xml +++ b/http-client/test/pom.xml @@ -16,13 +16,13 @@ io.avaje avaje-http-client - 1.13-SNAPSHOT + 1.14-SNAPSHOT io.avaje avaje-http-client-gson - 1.13-SNAPSHOT + 1.14-SNAPSHOT From e3be7a23f551998b98fb0077f7a26251e9e307af Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Fri, 3 Dec 2021 12:06:09 +1300 Subject: [PATCH 0238/1323] #34 - Add support for context.waitForAsync( maxWaitMillis ) ... for explicit waiting on submitted async requests --- .../avaje/http/client/DHttpClientContext.java | 19 +++++++++ .../avaje/http/client/DHttpClientRequest.java | 2 +- .../avaje/http/client/HttpClientContext.java | 8 ++++ .../java/io/avaje/http/client/AsyncTest.java | 40 +++++++++++++++++++ .../java/org/example/github/GithubTest.java | 24 ++++++----- 5 files changed, 81 insertions(+), 12 deletions(-) create mode 100644 http-client/client/src/test/java/io/avaje/http/client/AsyncTest.java diff --git a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContext.java b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContext.java index d44602d69..21e2c7c68 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContext.java +++ b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContext.java @@ -11,7 +11,9 @@ import java.util.List; import java.util.Map; import java.util.concurrent.CompletableFuture; +import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicReference; +import java.util.concurrent.locks.LockSupport; class DHttpClientContext implements HttpClientContext { @@ -31,6 +33,7 @@ class DHttpClientContext implements HttpClientContext { private final boolean withAuthToken; private final AuthTokenProvider authTokenProvider; private final AtomicReference tokenRef = new AtomicReference<>(); + private final AtomicLong activeAsync = new AtomicLong(); private int loggingMaxBody = 1_000; DHttpClientContext(HttpClient httpClient, String baseUrl, Duration requestTimeout, BodyAdapter bodyAdapter, RetryHandler retryHandler, RequestListener requestListener, AuthTokenProvider authTokenProvider, RequestIntercept intercept) { @@ -173,6 +176,7 @@ HttpResponse send(HttpRequest.Builder requestBuilder, HttpResponse.BodyHa } CompletableFuture> sendAsync(HttpRequest.Builder requestBuilder, HttpResponse.BodyHandler bodyHandler) { + activeAsync.incrementAndGet(); return httpClient.sendAsync(requestBuilder.build(), bodyHandler); } @@ -192,6 +196,18 @@ List readList(Class cls, BodyContent content) { return bodyAdapter.listReader(cls).read(content); } + @Override + public boolean waitForAsync(long millis) { + final long until = System.currentTimeMillis() + millis; + do { + if (activeAsync.get() <= 0) { + return true; + } + LockSupport.parkNanos(10_000_000); + } while (System.currentTimeMillis() < until); + return false; + } + void afterResponse(DHttpClientRequest request) { if (requestListener != null) { requestListener.response(request.listenerEvent()); @@ -199,6 +215,9 @@ void afterResponse(DHttpClientRequest request) { if (requestIntercept != null) { requestIntercept.afterResponse(request.response(), request); } + if (request.startAsyncNanos > 0) { + activeAsync.decrementAndGet(); + } } void beforeRequest(DHttpClientRequest request) { diff --git a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java index 435086fe0..a10b11c8a 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java +++ b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java @@ -50,7 +50,7 @@ class DHttpClientRequest implements HttpClientRequest, HttpClientResponse { private boolean loggableResponseBody; private boolean skipAuthToken; private boolean suppressLogging; - private long startAsyncNanos; + protected long startAsyncNanos; private String label; private Map customAttributes; diff --git a/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java b/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java index 139c63b95..bb149c96a 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java +++ b/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java @@ -115,6 +115,14 @@ static HttpClientContext.Builder newBuilder() { */ byte[] decodeContent(String encoding, byte[] content); + /** + * Wait for any submitted async requests with a given maximum wait time. + * + * @param maxWaitMillis The maximum time to wait in milliseconds + * @return True if waiting was successful or false if there are still async requests that have not yet come back for completion. + */ + boolean waitForAsync(long maxWaitMillis); + /** * Builds the HttpClientContext. * diff --git a/http-client/client/src/test/java/io/avaje/http/client/AsyncTest.java b/http-client/client/src/test/java/io/avaje/http/client/AsyncTest.java new file mode 100644 index 000000000..22d98ab06 --- /dev/null +++ b/http-client/client/src/test/java/io/avaje/http/client/AsyncTest.java @@ -0,0 +1,40 @@ +package io.avaje.http.client; + +import org.junit.jupiter.api.Test; + +import java.net.http.HttpResponse; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import static org.assertj.core.api.Assertions.assertThat; + +class AsyncTest extends BaseWebTest { + + final HttpClientContext clientContext = client(); + + @Test + void waitForAsync() { + final CompletableFuture>> future = clientContext.request() + .path("hello").path("stream") + .GET() + .async() + .asLines(); + + final AtomicBoolean flag = new AtomicBoolean(); + future.whenComplete((hres, throwable) -> { + flag.set(true); + assertThat(hres.statusCode()).isEqualTo(200); + List lines = hres.body().collect(Collectors.toList()); + assertThat(lines).hasSize(4); + assertThat(lines.get(0)).contains("{\"id\":1, \"name\":\"one\"}"); + }); + + assertThat(flag).isFalse(); + assertThat(clientContext.waitForAsync(1_000)).isTrue(); + assertThat(flag).isTrue(); + } + +} diff --git a/http-client/client/src/test/java/org/example/github/GithubTest.java b/http-client/client/src/test/java/org/example/github/GithubTest.java index c464e1e1b..b78b78ecd 100644 --- a/http-client/client/src/test/java/org/example/github/GithubTest.java +++ b/http-client/client/src/test/java/org/example/github/GithubTest.java @@ -13,7 +13,7 @@ public class GithubTest { @Test @Disabled - void test() throws InterruptedException { + void test() { final HttpClientContext clientContext = HttpClientContext.newBuilder() .baseUrl("https://api.github.com") @@ -21,24 +21,26 @@ void test() throws InterruptedException { .requestLogging(false) .build(); + // will not work under module classpath without registering the HttpApiProvider + final Simple simple = clientContext.create(Simple.class); + + final List repos = simple.listRepos("rbygrave", "junk"); + assertThat(repos).isNotEmpty(); + clientContext.request() .path("users").path("rbygrave").path("repos") .GET() .async() .asString() .thenAccept(res -> { - - System.out.println("RES: "+res.statusCode()); - System.out.println("BODY: "+res.body()); + System.out.println("RES: " + res.statusCode()); + System.out.println("BODY: " + res.body().substring(0, 150) + "..."); }); - Thread.sleep(1_000); - - // will not work under module classpath without registering the HttpApiProvider - final Simple simple = clientContext.create(Simple.class); - - final List repos = simple.listRepos("rbygrave", "junk"); - assertThat(repos).isNotEmpty(); + long st = System.currentTimeMillis(); + System.out.println("waitForAsync"); + boolean waitSuccess = clientContext.waitForAsync(2_000); + System.out.println("waitForAsync waitSuccess:" + waitSuccess + " waitMillis: " + (System.currentTimeMillis() - st)); } } From 3d2e4a2e86b077331b8c7a09ccb724dc6350d867 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Fri, 3 Dec 2021 12:07:54 +1300 Subject: [PATCH 0239/1323] Bump provided dependency avaje-jsonb to 0.8 --- http-client/client/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/http-client/client/pom.xml b/http-client/client/pom.xml index 5cd600b89..2e8c133f8 100644 --- a/http-client/client/pom.xml +++ b/http-client/client/pom.xml @@ -34,7 +34,7 @@ io.avaje avaje-jsonb - 0.5 + 0.8 true From 3569e13d24d10f652ab8104014af6b7cc1d832ce Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Mon, 6 Dec 2021 14:29:33 +1300 Subject: [PATCH 0240/1323] Add javadoc examples of using .join() with .async() In test code we frequently will use .join() to wait for the async callback to execute before proceeding with asserts etc --- .../avaje/http/client/HttpAsyncResponse.java | 49 +++++++++++++++++++ .../avaje/http/client/HttpClientResponse.java | 26 ++++++++++ 2 files changed, 75 insertions(+) diff --git a/http-client/client/src/main/java/io/avaje/http/client/HttpAsyncResponse.java b/http-client/client/src/main/java/io/avaje/http/client/HttpAsyncResponse.java index 8cfc213c4..d6aef2c0f 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/HttpAsyncResponse.java +++ b/http-client/client/src/main/java/io/avaje/http/client/HttpAsyncResponse.java @@ -8,6 +8,55 @@ /** * Async processing of the request with responses as CompletableFuture. + * + *

Testing and .join()

+ *

+ * Note that when testing with async requests we frequently use {@code .join()} + * on the {@code CompletableFuture} such that the main thread waits for the async + * processing to complete. After that various asserts can run knowing that the + * async callback code has been executed. + * + *

Example using .join() for testing purposes

+ *
{@code
+ *
+ *    clientContext.request()
+ *       ...
+ *       .POST().async()
+ *       .bean(HelloDto.class)
+ *       .whenComplete((helloDto, throwable) -> {
+ *         ...
+ *       }).join(); // wait for async processing to complete
+ *
+ *       // can assert now ...
+ *       assertThat(...)
+ *
+ * }
+ * + *

Example async().bean()

+ *

+ * In this example POST async that will return a bean converted from json response. + *

{@code
+ *
+ *    clientContext.request()
+ *       ...
+ *       .POST().async()
+ *       .bean(HelloDto.class)
+ *       .whenComplete((helloDto, throwable) -> {
+ *
+ *         if (throwable != null) {
+ *           HttpException httpException = (HttpException) throwable.getCause();
+ *           int statusCode = httpException.statusCode();
+ *
+ *           // maybe convert json error response body to a bean (using Jackson/Gson)
+ *           MyErrorBean errorResponse = httpException.bean(MyErrorBean.class);
+ *           ..
+ *
+ *         } else {
+ *           // process helloDto
+ *           ...
+ *         }
+ *       });
+ * }
*/ public interface HttpAsyncResponse { diff --git a/http-client/client/src/main/java/io/avaje/http/client/HttpClientResponse.java b/http-client/client/src/main/java/io/avaje/http/client/HttpClientResponse.java index 67e1ee8bd..088f9a2b5 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/HttpClientResponse.java +++ b/http-client/client/src/main/java/io/avaje/http/client/HttpClientResponse.java @@ -14,6 +14,32 @@ public interface HttpClientResponse { /** * Send the request async using CompletableFuture. + * + *

Example async().bean()

+ *

+ * In this example POST async that will return a bean converted from json response. + *

{@code
+   *
+   *    clientContext.request()
+   *       ...
+   *       .POST().async()
+   *       .bean(HelloDto.class)
+   *       .whenComplete((helloDto, throwable) -> {
+   *
+   *         if (throwable != null) {
+   *           HttpException httpException = (HttpException) throwable.getCause();
+   *           int statusCode = httpException.statusCode();
+   *
+   *           // maybe convert json error response body to a bean (using Jackson/Gson)
+   *           MyErrorBean errorResponse = httpException.bean(MyErrorBean.class);
+   *           ..
+   *
+   *         } else {
+   *           // process helloDto
+   *           ...
+   *         }
+   *       });
+   * }
*/ HttpAsyncResponse async(); From e84ecd3fced50fb3e28204516e1fc44db56d01a2 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Mon, 6 Dec 2021 14:43:57 +1300 Subject: [PATCH 0241/1323] Cleanup removal of waitForAsync() --- .../avaje/http/client/DHttpClientContext.java | 19 ------------------- .../avaje/http/client/DHttpClientRequest.java | 2 +- .../avaje/http/client/HttpClientContext.java | 8 -------- .../java/io/avaje/http/client/AsyncTest.java | 4 +--- .../java/org/example/github/GithubTest.java | 7 +------ 5 files changed, 3 insertions(+), 37 deletions(-) diff --git a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContext.java b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContext.java index 21e2c7c68..d44602d69 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContext.java +++ b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContext.java @@ -11,9 +11,7 @@ import java.util.List; import java.util.Map; import java.util.concurrent.CompletableFuture; -import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicReference; -import java.util.concurrent.locks.LockSupport; class DHttpClientContext implements HttpClientContext { @@ -33,7 +31,6 @@ class DHttpClientContext implements HttpClientContext { private final boolean withAuthToken; private final AuthTokenProvider authTokenProvider; private final AtomicReference tokenRef = new AtomicReference<>(); - private final AtomicLong activeAsync = new AtomicLong(); private int loggingMaxBody = 1_000; DHttpClientContext(HttpClient httpClient, String baseUrl, Duration requestTimeout, BodyAdapter bodyAdapter, RetryHandler retryHandler, RequestListener requestListener, AuthTokenProvider authTokenProvider, RequestIntercept intercept) { @@ -176,7 +173,6 @@ HttpResponse send(HttpRequest.Builder requestBuilder, HttpResponse.BodyHa } CompletableFuture> sendAsync(HttpRequest.Builder requestBuilder, HttpResponse.BodyHandler bodyHandler) { - activeAsync.incrementAndGet(); return httpClient.sendAsync(requestBuilder.build(), bodyHandler); } @@ -196,18 +192,6 @@ List readList(Class cls, BodyContent content) { return bodyAdapter.listReader(cls).read(content); } - @Override - public boolean waitForAsync(long millis) { - final long until = System.currentTimeMillis() + millis; - do { - if (activeAsync.get() <= 0) { - return true; - } - LockSupport.parkNanos(10_000_000); - } while (System.currentTimeMillis() < until); - return false; - } - void afterResponse(DHttpClientRequest request) { if (requestListener != null) { requestListener.response(request.listenerEvent()); @@ -215,9 +199,6 @@ void afterResponse(DHttpClientRequest request) { if (requestIntercept != null) { requestIntercept.afterResponse(request.response(), request); } - if (request.startAsyncNanos > 0) { - activeAsync.decrementAndGet(); - } } void beforeRequest(DHttpClientRequest request) { diff --git a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java index a10b11c8a..435086fe0 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java +++ b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java @@ -50,7 +50,7 @@ class DHttpClientRequest implements HttpClientRequest, HttpClientResponse { private boolean loggableResponseBody; private boolean skipAuthToken; private boolean suppressLogging; - protected long startAsyncNanos; + private long startAsyncNanos; private String label; private Map customAttributes; diff --git a/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java b/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java index bb149c96a..139c63b95 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java +++ b/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java @@ -115,14 +115,6 @@ static HttpClientContext.Builder newBuilder() { */ byte[] decodeContent(String encoding, byte[] content); - /** - * Wait for any submitted async requests with a given maximum wait time. - * - * @param maxWaitMillis The maximum time to wait in milliseconds - * @return True if waiting was successful or false if there are still async requests that have not yet come back for completion. - */ - boolean waitForAsync(long maxWaitMillis); - /** * Builds the HttpClientContext. * diff --git a/http-client/client/src/test/java/io/avaje/http/client/AsyncTest.java b/http-client/client/src/test/java/io/avaje/http/client/AsyncTest.java index 22d98ab06..2bc5a44bf 100644 --- a/http-client/client/src/test/java/io/avaje/http/client/AsyncTest.java +++ b/http-client/client/src/test/java/io/avaje/http/client/AsyncTest.java @@ -30,10 +30,8 @@ void waitForAsync() { List lines = hres.body().collect(Collectors.toList()); assertThat(lines).hasSize(4); assertThat(lines.get(0)).contains("{\"id\":1, \"name\":\"one\"}"); - }); + }).join(); - assertThat(flag).isFalse(); - assertThat(clientContext.waitForAsync(1_000)).isTrue(); assertThat(flag).isTrue(); } diff --git a/http-client/client/src/test/java/org/example/github/GithubTest.java b/http-client/client/src/test/java/org/example/github/GithubTest.java index b78b78ecd..fad785fea 100644 --- a/http-client/client/src/test/java/org/example/github/GithubTest.java +++ b/http-client/client/src/test/java/org/example/github/GithubTest.java @@ -35,12 +35,7 @@ void test() { .thenAccept(res -> { System.out.println("RES: " + res.statusCode()); System.out.println("BODY: " + res.body().substring(0, 150) + "..."); - }); - - long st = System.currentTimeMillis(); - System.out.println("waitForAsync"); - boolean waitSuccess = clientContext.waitForAsync(2_000); - System.out.println("waitForAsync waitSuccess:" + waitSuccess + " waitMillis: " + (System.currentTimeMillis() - st)); + }).join(); } } From 24c17c00f79142ca41d9b3ec6c617eccf2a4c364 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Thu, 24 Feb 2022 16:58:06 +1300 Subject: [PATCH 0242/1323] #40 - Change Jackson adapter to throw UncheckedIOException rather than RuntimeException --- http-client/client/pom.xml | 2 +- .../main/java/io/avaje/http/client/JacksonBodyAdapter.java | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/http-client/client/pom.xml b/http-client/client/pom.xml index 2e8c133f8..d24c05671 100644 --- a/http-client/client/pom.xml +++ b/http-client/client/pom.xml @@ -34,7 +34,7 @@ io.avaje avaje-jsonb - 0.8 + 0.11 true diff --git a/http-client/client/src/main/java/io/avaje/http/client/JacksonBodyAdapter.java b/http-client/client/src/main/java/io/avaje/http/client/JacksonBodyAdapter.java index 1b0ab483a..8dc9a5727 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/JacksonBodyAdapter.java +++ b/http-client/client/src/main/java/io/avaje/http/client/JacksonBodyAdapter.java @@ -6,6 +6,7 @@ import com.fasterxml.jackson.databind.type.CollectionType; import java.io.IOException; +import java.io.UncheckedIOException; import java.util.List; import java.util.concurrent.ConcurrentHashMap; @@ -98,7 +99,7 @@ public T readBody(String content) { try { return reader.readValue(content); } catch (IOException e) { - throw new RuntimeException(e); + throw new UncheckedIOException(e); } } @@ -107,7 +108,7 @@ public T read(BodyContent bodyContent) { try { return reader.readValue(bodyContent.content()); } catch (IOException e) { - throw new RuntimeException(e); + throw new UncheckedIOException(e); } } } @@ -132,7 +133,7 @@ public BodyContent write(T bean) { try { return BodyContent.asJson(writer.writeValueAsBytes(bean)); } catch (JsonProcessingException e) { - throw new RuntimeException(e); + throw new UncheckedIOException(e); } } } From e0f5b8822e3d72f7eac03d24427a31be2fc24caf Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Fri, 25 Feb 2022 13:32:53 +1300 Subject: [PATCH 0243/1323] #41 - ENH: Add HttpClientContext metrics() to provide statistical overview of activity --- http-client/client/pom.xml | 2 +- .../java/io/avaje/http/client/DHttpApi.java | 2 +- .../java/io/avaje/http/client/DHttpAsync.java | 2 +- .../java/io/avaje/http/client/DHttpCall.java | 2 +- .../avaje/http/client/DHttpClientContext.java | 90 ++++++++++++++++++- .../client/DHttpClientContextBuilder.java | 2 +- .../avaje/http/client/DHttpClientRequest.java | 9 +- .../client/DHttpClientRequestWithRetry.java | 2 +- .../http/client/DRequestInterceptors.java | 2 +- .../avaje/http/client/DRequestListeners.java | 2 +- .../java/io/avaje/http/client/GzipUtil.java | 2 +- .../avaje/http/client/HttpClientContext.java | 50 +++++++++++ .../avaje/http/client/JacksonBodyAdapter.java | 2 +- .../avaje/http/client/JsonbBodyAdapter.java | 2 +- .../io/avaje/http/client/PathConversion.java | 2 +- .../java/io/avaje/http/client/UrlBuilder.java | 2 +- .../io/avaje/http/client/DHttpApiTest.java | 1 + .../http/client/DHttpClientRequestTest.java | 9 +- .../http/client/HelloControllerTest.java | 34 ++++++- 19 files changed, 197 insertions(+), 22 deletions(-) diff --git a/http-client/client/pom.xml b/http-client/client/pom.xml index d24c05671..8ecf4c8dd 100644 --- a/http-client/client/pom.xml +++ b/http-client/client/pom.xml @@ -34,7 +34,7 @@ io.avaje avaje-jsonb - 0.11 + 0.12 true diff --git a/http-client/client/src/main/java/io/avaje/http/client/DHttpApi.java b/http-client/client/src/main/java/io/avaje/http/client/DHttpApi.java index 3337346f3..25376f4a0 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/DHttpApi.java +++ b/http-client/client/src/main/java/io/avaje/http/client/DHttpApi.java @@ -10,7 +10,7 @@ /** * Service loads the HttpApiProvider for HttpApi. */ -class DHttpApi { +final class DHttpApi { private static final Logger log = LoggerFactory.getLogger(DHttpApi.class); diff --git a/http-client/client/src/main/java/io/avaje/http/client/DHttpAsync.java b/http-client/client/src/main/java/io/avaje/http/client/DHttpAsync.java index dba3cce5a..b7083c126 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/DHttpAsync.java +++ b/http-client/client/src/main/java/io/avaje/http/client/DHttpAsync.java @@ -6,7 +6,7 @@ import java.util.concurrent.CompletableFuture; import java.util.stream.Stream; -class DHttpAsync implements HttpAsyncResponse { +final class DHttpAsync implements HttpAsyncResponse { private final DHttpClientRequest request; diff --git a/http-client/client/src/main/java/io/avaje/http/client/DHttpCall.java b/http-client/client/src/main/java/io/avaje/http/client/DHttpCall.java index 53ec3abba..08d2835ce 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/DHttpCall.java +++ b/http-client/client/src/main/java/io/avaje/http/client/DHttpCall.java @@ -6,7 +6,7 @@ import java.util.concurrent.CompletableFuture; import java.util.stream.Stream; -class DHttpCall implements HttpCallResponse { +final class DHttpCall implements HttpCallResponse { private final DHttpClientRequest request; diff --git a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContext.java b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContext.java index d44602d69..a1f06d570 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContext.java +++ b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContext.java @@ -12,8 +12,10 @@ import java.util.Map; import java.util.concurrent.CompletableFuture; import java.util.concurrent.atomic.AtomicReference; +import java.util.concurrent.atomic.LongAccumulator; +import java.util.concurrent.atomic.LongAdder; -class DHttpClientContext implements HttpClientContext { +final class DHttpClientContext implements HttpClientContext { /** * HTTP Authorization header. @@ -33,6 +35,12 @@ class DHttpClientContext implements HttpClientContext { private final AtomicReference tokenRef = new AtomicReference<>(); private int loggingMaxBody = 1_000; + private final LongAdder metricResTotal = new LongAdder(); + private final LongAdder metricResError = new LongAdder(); + private final LongAdder metricResBytes = new LongAdder(); + private final LongAdder metricResMicros = new LongAdder(); + private final LongAccumulator metricResMaxMicros = new LongAccumulator(Math::max, 0); + DHttpClientContext(HttpClient httpClient, String baseUrl, Duration requestTimeout, BodyAdapter bodyAdapter, RetryHandler retryHandler, RequestListener requestListener, AuthTokenProvider authTokenProvider, RequestIntercept intercept) { this.httpClient = httpClient; this.baseUrl = baseUrl; @@ -94,6 +102,76 @@ public HttpClient httpClient() { return httpClient; } + @Override + public Metrics metrics() { + return metrics(false); + } + + @Override + public Metrics metrics(boolean reset) { + if (reset) { + return new DMetrics(metricResTotal.sumThenReset(), metricResError.sumThenReset(), metricResBytes.sumThenReset(), metricResMicros.sumThenReset(), metricResMaxMicros.getThenReset()); + } else { + return new DMetrics(metricResTotal.sum(), metricResError.sum(), metricResBytes.sum(), metricResMicros.sum(), metricResMaxMicros.get()); + } + } + + void metricsString(int stringBody) { + metricResBytes.add(stringBody); + } + + static final class DMetrics implements Metrics { + + private final long totalCount; + private final long errorCount; + private final long responseBytes; + private final long totalMicros; + private final long maxMicros; + + DMetrics(long totalCount, long errorCount, long responseBytes, long totalMicros, long maxMicros) { + this.totalCount = totalCount; + this.errorCount = errorCount; + this.responseBytes = responseBytes; + this.totalMicros = totalMicros; + this.maxMicros = maxMicros; + } + + @Override + public String toString() { + return "totalCount:" + totalCount + " errorCount:" + errorCount + " responseBytes:" + responseBytes + " totalMicros:" + totalMicros + " avgMicros:" + avgMicros()+ " maxMicros:" + maxMicros; + } + + @Override + public long totalCount() { + return totalCount; + } + + @Override + public long errorCount() { + return errorCount; + } + + @Override + public long responseBytes() { + return responseBytes; + } + + @Override + public long totalMicros() { + return totalMicros; + } + + @Override + public long maxMicros() { + return maxMicros; + } + + @Override + public long avgMicros() { + return totalCount == 0 ? 0 : totalMicros / totalCount; + } + } + @Override public void checkResponse(HttpResponse response) { if (response.statusCode() >= 300) { @@ -123,6 +201,10 @@ public BodyContent readErrorContent(boolean responseAsBytes, HttpResponse htt @Override public BodyContent readContent(HttpResponse httpResponse) { + final byte[] body = httpResponse.body(); + if (body != null && body.length > 0) { + metricResBytes.add(body.length); + } byte[] bodyBytes = decodeContent(httpResponse); final String contentType = getContentType(httpResponse); return new BodyContent(contentType, bodyBytes); @@ -193,6 +275,12 @@ List readList(Class cls, BodyContent content) { } void afterResponse(DHttpClientRequest request) { + metricResTotal.add(1); + metricResMicros.add(request.responseTimeMicros()); + metricResMaxMicros.accumulate(request.responseTimeMicros()); + if (request.response().statusCode() >= 300) { + metricResError.add(1); + } if (requestListener != null) { requestListener.response(request.listenerEvent()); } diff --git a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContextBuilder.java b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContextBuilder.java index e81a1e5ca..f9e390ea6 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContextBuilder.java +++ b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContextBuilder.java @@ -14,7 +14,7 @@ import static java.util.Objects.requireNonNull; -class DHttpClientContextBuilder implements HttpClientContext.Builder { +final class DHttpClientContextBuilder implements HttpClientContext.Builder { private HttpClient client; private String baseUrl; diff --git a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java index 435086fe0..3c080abe8 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java +++ b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java @@ -531,16 +531,21 @@ public HttpResponse asByteArray() { return withHandler(HttpResponse.BodyHandlers.ofByteArray()); } + private HttpResponse addMetrics(final HttpResponse res) { + context.metricsString(res.body().length()); + return res; + } + @Override public HttpResponse asString() { loggableResponseBody = true; - return withHandler(HttpResponse.BodyHandlers.ofString()); + return addMetrics(withHandler(HttpResponse.BodyHandlers.ofString())); } @Override public HttpResponse asPlainString() { loggableResponseBody = true; - final HttpResponse hres = withHandler(HttpResponse.BodyHandlers.ofString()); + final HttpResponse hres = addMetrics(withHandler(HttpResponse.BodyHandlers.ofString())); context.checkResponse(hres); return hres; } diff --git a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequestWithRetry.java b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequestWithRetry.java index 47ff59e39..6d5d26606 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequestWithRetry.java +++ b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequestWithRetry.java @@ -6,7 +6,7 @@ /** * Extends DHttpClientRequest with retry attempts. */ -class DHttpClientRequestWithRetry extends DHttpClientRequest { +final class DHttpClientRequestWithRetry extends DHttpClientRequest { private final RetryHandler retryHandler; private int retryCount; diff --git a/http-client/client/src/main/java/io/avaje/http/client/DRequestInterceptors.java b/http-client/client/src/main/java/io/avaje/http/client/DRequestInterceptors.java index 3ae70aef5..0051e708f 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/DRequestInterceptors.java +++ b/http-client/client/src/main/java/io/avaje/http/client/DRequestInterceptors.java @@ -10,7 +10,7 @@ *

* Noting that afterResponse interceptors are processed in reverse order. */ -class DRequestInterceptors implements RequestIntercept { +final class DRequestInterceptors implements RequestIntercept { private final List before; private final List after; diff --git a/http-client/client/src/main/java/io/avaje/http/client/DRequestListeners.java b/http-client/client/src/main/java/io/avaje/http/client/DRequestListeners.java index 5b076713f..6dda3b896 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/DRequestListeners.java +++ b/http-client/client/src/main/java/io/avaje/http/client/DRequestListeners.java @@ -2,7 +2,7 @@ import java.util.List; -class DRequestListeners implements RequestListener { +final class DRequestListeners implements RequestListener { private final RequestListener[] listeners; diff --git a/http-client/client/src/main/java/io/avaje/http/client/GzipUtil.java b/http-client/client/src/main/java/io/avaje/http/client/GzipUtil.java index 4b7cba1e4..5ecced63a 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/GzipUtil.java +++ b/http-client/client/src/main/java/io/avaje/http/client/GzipUtil.java @@ -7,7 +7,7 @@ import java.util.zip.GZIPInputStream; import java.util.zip.GZIPOutputStream; -class GzipUtil { +final class GzipUtil { static byte[] gzip(String content) { return gzip(content.getBytes(StandardCharsets.UTF_8)); diff --git a/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java b/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java index 139c63b95..d65bf0181 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java +++ b/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java @@ -84,6 +84,20 @@ static HttpClientContext.Builder newBuilder() { */ HttpClient httpClient(); + /** + * Return the current aggregate metrics. + *

+ * These metrics are collected for all requests sent via this context. + */ + Metrics metrics(); + + /** + * Return the current metrics with the option of resetting the underlying counters. + *

+ * These metrics are collected for all requests sent via this context. + */ + Metrics metrics(boolean reset); + /** * Check the response status code and throw HttpException if the status * code is in the error range. @@ -309,4 +323,40 @@ interface Builder { */ HttpClientContext build(); } + + /** + * Statistic metrics collected to provide an overview of activity of this client. + */ + interface Metrics { + + /** + * Return the total number of responses. + */ + long totalCount(); + + /** + * Return the total number of error responses (status code >= 300). + */ + long errorCount(); + + /** + * Return the total response bytes (excludes streaming responses). + */ + long responseBytes(); + + /** + * Return the total response time in microseconds. + */ + long totalMicros(); + + /** + * Return the max response time in microseconds (since the last reset). + */ + long maxMicros(); + + /** + * Return the average response time in microseconds. + */ + long avgMicros(); + } } diff --git a/http-client/client/src/main/java/io/avaje/http/client/JacksonBodyAdapter.java b/http-client/client/src/main/java/io/avaje/http/client/JacksonBodyAdapter.java index 8dc9a5727..e0acfa4a6 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/JacksonBodyAdapter.java +++ b/http-client/client/src/main/java/io/avaje/http/client/JacksonBodyAdapter.java @@ -22,7 +22,7 @@ * * }

*/ -public class JacksonBodyAdapter implements BodyAdapter { +public final class JacksonBodyAdapter implements BodyAdapter { private final ObjectMapper mapper; diff --git a/http-client/client/src/main/java/io/avaje/http/client/JsonbBodyAdapter.java b/http-client/client/src/main/java/io/avaje/http/client/JsonbBodyAdapter.java index e04a0dc7b..2ae8e8a50 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/JsonbBodyAdapter.java +++ b/http-client/client/src/main/java/io/avaje/http/client/JsonbBodyAdapter.java @@ -18,7 +18,7 @@ * * }
*/ -public class JsonbBodyAdapter implements BodyAdapter { +public final class JsonbBodyAdapter implements BodyAdapter { private final Jsonb jsonb; private final ConcurrentHashMap, BodyWriter> beanWriterCache = new ConcurrentHashMap<>(); diff --git a/http-client/client/src/main/java/io/avaje/http/client/PathConversion.java b/http-client/client/src/main/java/io/avaje/http/client/PathConversion.java index 03b4fcd45..adffd2771 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/PathConversion.java +++ b/http-client/client/src/main/java/io/avaje/http/client/PathConversion.java @@ -3,7 +3,7 @@ /** * Helper methods to convert common types to String path values. */ -public class PathConversion { +public final class PathConversion { /** * Convert to path. diff --git a/http-client/client/src/main/java/io/avaje/http/client/UrlBuilder.java b/http-client/client/src/main/java/io/avaje/http/client/UrlBuilder.java index 55818ff92..40e82d787 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/UrlBuilder.java +++ b/http-client/client/src/main/java/io/avaje/http/client/UrlBuilder.java @@ -7,7 +7,7 @@ /** * Build a URL typically using a base url and adding path and query parameters. */ -public class UrlBuilder { +public final class UrlBuilder { private final StringBuilder buffer = new StringBuilder(100); diff --git a/http-client/client/src/test/java/io/avaje/http/client/DHttpApiTest.java b/http-client/client/src/test/java/io/avaje/http/client/DHttpApiTest.java index 0e5e1abea..97c541cdb 100644 --- a/http-client/client/src/test/java/io/avaje/http/client/DHttpApiTest.java +++ b/http-client/client/src/test/java/io/avaje/http/client/DHttpApiTest.java @@ -36,6 +36,7 @@ void jsonb_github_listRepos() { Jsonb jsonb = Jsonb.newBuilder() .add(Repo.class, RepoJsonAdapter::new) + //.adapter(new JacksonAdapter()) .build(); final HttpClientContext clientContext = HttpClientContext.newBuilder() diff --git a/http-client/client/src/test/java/io/avaje/http/client/DHttpClientRequestTest.java b/http-client/client/src/test/java/io/avaje/http/client/DHttpClientRequestTest.java index 3c92f16e4..f771785c9 100644 --- a/http-client/client/src/test/java/io/avaje/http/client/DHttpClientRequestTest.java +++ b/http-client/client/src/test/java/io/avaje/http/client/DHttpClientRequestTest.java @@ -5,14 +5,14 @@ import java.time.Duration; import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; class DHttpClientRequestTest { + final DHttpClientContext context = new DHttpClientContext(null, null, null, null, null, null, null, null); + @Test void suppressLogging_listenerEvent_expect_suppressedPayloadContent() { - - final DHttpClientRequest request = new DHttpClientRequest(mock(DHttpClientContext.class), Duration.ZERO); + final DHttpClientRequest request = new DHttpClientRequest(context, Duration.ZERO); request.suppressLogging(); final RequestListener.Event event = request.listenerEvent(); @@ -23,8 +23,7 @@ void suppressLogging_listenerEvent_expect_suppressedPayloadContent() { @Test void skipAuthToken_listenerEvent_expect_suppressedPayloadContent() { - - final DHttpClientRequest request = new DHttpClientRequest(mock(DHttpClientContext.class), Duration.ZERO); + final DHttpClientRequest request = new DHttpClientRequest(context, Duration.ZERO); assertThat(request.isSkipAuthToken()).isFalse(); request.skipAuthToken(); diff --git a/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java b/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java index 6c594bd54..3671602aa 100644 --- a/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java +++ b/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java @@ -31,6 +31,7 @@ class HelloControllerTest extends BaseWebTest { @Test void queryParamMap() { + clientContext.metrics(true); Map params = new LinkedHashMap<>(); params.put("A", "a"); params.put("B", "b"); @@ -42,6 +43,14 @@ void queryParamMap() { assertThat(hres.statusCode()).isEqualTo(200); assertThat(hres.uri().toString()).isEqualTo("http://localhost:8887/hello/message?A=a&B=b"); + + HttpClientContext.Metrics metrics = clientContext.metrics(); + assertThat(metrics.totalCount()).isEqualTo(1); + assertThat(metrics.errorCount()).isEqualTo(0); + assertThat(metrics.responseBytes()).isGreaterThan(0); + assertThat(metrics.totalMicros()).isGreaterThan(0); + assertThat(metrics.maxMicros()).isEqualTo(metrics.totalMicros()); + assertThat(metrics.avgMicros()).isEqualTo(metrics.totalMicros()); } @Test @@ -61,6 +70,7 @@ void asLines() { @Test void asLines_async() throws ExecutionException, InterruptedException { + clientContext.metrics(true); final CompletableFuture>> future = clientContext.request() .path("hello").path("stream") .GET() @@ -73,6 +83,11 @@ void asLines_async() throws ExecutionException, InterruptedException { assertThat(lines).hasSize(4); assertThat(lines.get(0)).contains("{\"id\":1, \"name\":\"one\"}"); + HttpClientContext.Metrics metrics = clientContext.metrics(); + assertThat(metrics.totalCount()).isEqualTo(1); + assertThat(metrics.errorCount()).isEqualTo(0); + assertThat(metrics.responseBytes()).isEqualTo(0); + assertThat(metrics.totalMicros()).isGreaterThan(0); } @Test @@ -206,6 +221,7 @@ void get_stream() { @Test void get_stream_NotFoundException() { + clientContext.metrics(true); final HttpException httpException = assertThrows(HttpException.class, () -> clientContext.request() .path("this-path-does-not-exist") @@ -214,6 +230,11 @@ void get_stream_NotFoundException() { assertThat(httpException.statusCode()).isEqualTo(404); assertThat(httpException.httpResponse().statusCode()).isEqualTo(404); + HttpClientContext.Metrics metrics = clientContext.metrics(true); + assertThat(metrics.totalCount()).isEqualTo(1); + assertThat(metrics.errorCount()).isEqualTo(1); + assertThat(metrics.responseBytes()).isEqualTo(0); + assertThat(metrics.totalMicros()).isGreaterThan(0); } @Test @@ -360,6 +381,7 @@ void asByteArray_async() throws ExecutionException, InterruptedException { @Test void get_notFound() { + clientContext.metrics(true); UUID nullUUID = null; final HttpClientRequest request = clientContext.request() .path("hello").path(UUID.randomUUID()).queryParam("zone", ZoneId.of("UTC")) @@ -373,6 +395,11 @@ void get_notFound() { assertThat(hres.statusCode()).isEqualTo(404); assertThat(hres.body()).contains("Not found"); + HttpClientContext.Metrics metrics = clientContext.metrics(true); + assertThat(metrics.totalCount()).isEqualTo(1); + assertThat(metrics.errorCount()).isEqualTo(1); + assertThat(metrics.responseBytes()).isGreaterThan(0); + assertThat(metrics.totalMicros()).isGreaterThan(0); } @Test @@ -732,7 +759,7 @@ void async_whenComplete_returningBean() throws ExecutionException, InterruptedEx @Test void async_whenComplete_throwingHttpException() { - + clientContext.metrics(true); AtomicReference causeRef = new AtomicReference<>(); final CompletableFuture future = clientContext.request() @@ -766,6 +793,11 @@ void async_whenComplete_throwingHttpException() { } catch (CompletionException e) { assertThat(e.getCause()).isSameAs(causeRef.get()); } + HttpClientContext.Metrics metrics = clientContext.metrics(true); + assertThat(metrics.totalCount()).isEqualTo(1); + assertThat(metrics.errorCount()).isEqualTo(1); + assertThat(metrics.responseBytes()).isGreaterThan(0); + assertThat(metrics.totalMicros()).isGreaterThan(0); } @Test From 75560f85645a76e62215d1e28075bf0585324808 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Fri, 25 Feb 2022 13:51:10 +1300 Subject: [PATCH 0244/1323] Bump parent pom and optional dependency versions --- http-client/client/pom.xml | 6 +++--- http-client/pom.xml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/http-client/client/pom.xml b/http-client/client/pom.xml index 8ecf4c8dd..f64c11e55 100644 --- a/http-client/client/pom.xml +++ b/http-client/client/pom.xml @@ -4,7 +4,7 @@ java11-oss org.avaje - 3.3 + 3.5 io.avaje @@ -21,13 +21,13 @@ org.slf4j slf4j-api - 1.7.30 + 1.7.36 com.fasterxml.jackson.core jackson-databind - 2.12.2 + 2.13.1 true diff --git a/http-client/pom.xml b/http-client/pom.xml index 7a53d9311..af1788bc8 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,7 +4,7 @@ java11-oss org.avaje - 3.3 + 3.5 io.avaje From 471be61b2172ecf0501023cb00f3bd1488e352f4 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Fri, 25 Feb 2022 13:58:30 +1300 Subject: [PATCH 0245/1323] Update module-info to optionally use jackson annotation and core --- http-client/client/src/main/java/module-info.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/http-client/client/src/main/java/module-info.java b/http-client/client/src/main/java/module-info.java index 2f77bbc8a..a7b6fcbf4 100644 --- a/http-client/client/src/main/java/module-info.java +++ b/http-client/client/src/main/java/module-info.java @@ -5,6 +5,8 @@ requires transitive java.net.http; requires transitive org.slf4j; requires static com.fasterxml.jackson.databind; + requires static com.fasterxml.jackson.annotation; + requires static com.fasterxml.jackson.core; requires static io.avaje.jsonb; exports io.avaje.http.client; From 8d8b3e9c584d73a537a3a832d424b5ea3cb9b1ef Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Fri, 25 Feb 2022 13:59:19 +1300 Subject: [PATCH 0246/1323] [maven-release-plugin] prepare release avaje-http-client-1.14 --- http-client/client/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/http-client/client/pom.xml b/http-client/client/pom.xml index f64c11e55..4fe011e40 100644 --- a/http-client/client/pom.xml +++ b/http-client/client/pom.xml @@ -9,11 +9,11 @@ io.avaje avaje-http-client - 1.14-SNAPSHOT + 1.14 scm:git:git@github.com:avaje/avaje-http-client.git - HEAD + avaje-http-client-1.14 From fc743ed58724fdd1603d2cf68edff23143eaf523 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Fri, 25 Feb 2022 13:59:25 +1300 Subject: [PATCH 0247/1323] [maven-release-plugin] prepare for next development iteration --- http-client/client/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/http-client/client/pom.xml b/http-client/client/pom.xml index 4fe011e40..b07552557 100644 --- a/http-client/client/pom.xml +++ b/http-client/client/pom.xml @@ -9,11 +9,11 @@ io.avaje avaje-http-client - 1.14 + 1.15-SNAPSHOT scm:git:git@github.com:avaje/avaje-http-client.git - avaje-http-client-1.14 + HEAD From 9baff99a3fe14fe706aff3981260945962852d4c Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Fri, 25 Feb 2022 14:34:04 +1300 Subject: [PATCH 0248/1323] Bump Gson dependency etc --- http-client/gson-adapter/pom.xml | 8 ++++---- http-client/test/pom.xml | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/http-client/gson-adapter/pom.xml b/http-client/gson-adapter/pom.xml index 21a3a61d8..2385c02cb 100644 --- a/http-client/gson-adapter/pom.xml +++ b/http-client/gson-adapter/pom.xml @@ -4,12 +4,12 @@ java11-oss org.avaje - 3.3 + 3.5 io.avaje avaje-http-client-gson - 1.14-SNAPSHOT + 1.15-SNAPSHOT scm:git:git@github.com:avaje/avaje-http-client.git @@ -21,13 +21,13 @@ com.google.code.gson gson - 2.8.9 + 2.9.0 io.avaje avaje-http-client - 1.14-SNAPSHOT + 1.15-SNAPSHOT provided diff --git a/http-client/test/pom.xml b/http-client/test/pom.xml index a0a80cb32..4d4ab735a 100644 --- a/http-client/test/pom.xml +++ b/http-client/test/pom.xml @@ -16,13 +16,13 @@ io.avaje avaje-http-client - 1.14-SNAPSHOT + 1.15-SNAPSHOT io.avaje avaje-http-client-gson - 1.14-SNAPSHOT + 1.15-SNAPSHOT @@ -34,7 +34,7 @@ com.fasterxml.jackson.core jackson-databind - 2.12.5 + 2.13.1 From 62202b336819ef8e8b4ef64f9c63a29987bbdc00 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Fri, 25 Feb 2022 17:06:12 +1300 Subject: [PATCH 0249/1323] #43 - ENH: Add gitter support to SimpleRetryHandler --- .../avaje/http/client/SimpleRetryHandler.java | 21 ++++++++++++++++-- .../java/io/avaje/http/client/RetryTest.java | 22 ++++++++++++++----- 2 files changed, 35 insertions(+), 8 deletions(-) diff --git a/http-client/client/src/main/java/io/avaje/http/client/SimpleRetryHandler.java b/http-client/client/src/main/java/io/avaje/http/client/SimpleRetryHandler.java index 3b0ea5534..9089046d3 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/SimpleRetryHandler.java +++ b/http-client/client/src/main/java/io/avaje/http/client/SimpleRetryHandler.java @@ -4,6 +4,7 @@ import org.slf4j.LoggerFactory; import java.net.http.HttpResponse; +import java.util.Random; /** * Simple retry with max attempts and linear backoff. @@ -14,16 +15,31 @@ public class SimpleRetryHandler implements RetryHandler { private final int maxRetries; private final long backoffMillis; + private final int gitterMillis; + private final Random random; /** * Create with maximum number of retries and linear backoff time. * * @param maxRetries The maximum number of retry attempts * @param backoffMillis The linear backoff between attempts in milliseconds + * @param gitterMillis The maximum amount of gitter that gets added to backoffMillis */ - public SimpleRetryHandler(int maxRetries, long backoffMillis) { + public SimpleRetryHandler(int maxRetries, int backoffMillis, int gitterMillis) { this.maxRetries = maxRetries; this.backoffMillis = backoffMillis; + this.gitterMillis = gitterMillis; + this.random = new Random(); + } + + /** + * Create with maximum number of retries and linear backoff time and no gitter. + * + * @param maxRetries The maximum number of retry attempts + * @param backoffMillis The linear backoff between attempts in milliseconds + */ + public SimpleRetryHandler(int maxRetries, int backoffMillis) { + this(maxRetries, backoffMillis, 0); } @Override @@ -33,7 +49,8 @@ public boolean isRetry(int retryCount, HttpResponse response) { } log.debug("retry count:{} status:{} uri:{}", retryCount, response.statusCode(), response.uri()); try { - Thread.sleep(backoffMillis); + int gitter = gitterMillis < 1 ? 0 : random.nextInt(gitterMillis); + Thread.sleep(backoffMillis + gitter); } catch (InterruptedException e) { Thread.currentThread().interrupt(); return false; diff --git a/http-client/client/src/test/java/io/avaje/http/client/RetryTest.java b/http-client/client/src/test/java/io/avaje/http/client/RetryTest.java index 745416043..0bde5578a 100644 --- a/http-client/client/src/test/java/io/avaje/http/client/RetryTest.java +++ b/http-client/client/src/test/java/io/avaje/http/client/RetryTest.java @@ -1,28 +1,38 @@ package io.avaje.http.client; -import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.jupiter.api.Test; import java.net.http.HttpResponse; import static org.assertj.core.api.Assertions.assertThat; -public class RetryTest extends BaseWebTest { +class RetryTest extends BaseWebTest { - final MyIntercept myIntercept = new MyIntercept(); - final HttpClientContext clientContext = initClientWithRetry(); - HttpClientContext initClientWithRetry() { + HttpClientContext initClientWithRetry(MyIntercept myIntercept, RetryHandler retryHandler) { return HttpClientContext.newBuilder() .baseUrl("http://localhost:8887") .bodyAdapter(new JacksonBodyAdapter()) - .retryHandler(new SimpleRetryHandler(4, 1)) + .retryHandler(retryHandler) .requestIntercept(myIntercept) .build(); } @Test void retryTest() { + final MyIntercept myIntercept = new MyIntercept(); + final HttpClientContext clientContext = initClientWithRetry(myIntercept, new SimpleRetryHandler(4, 1)); + performGetRequestAndAssert(myIntercept, clientContext); + } + + @Test + void retryWithGitterTest() { + final MyIntercept myIntercept = new MyIntercept(); + final HttpClientContext clientContext = initClientWithRetry(myIntercept, new SimpleRetryHandler(4, 10, 20)); + performGetRequestAndAssert(myIntercept, clientContext); + } + + private void performGetRequestAndAssert(MyIntercept myIntercept, HttpClientContext clientContext) { HttpResponse res = clientContext.request() .label("http_client_hello_retry") .path("hello/retry") From 6646ee46d7512f9619fc97c3b81d239092bc5d37 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Fri, 25 Feb 2022 17:43:01 +1300 Subject: [PATCH 0250/1323] #44 - Migrate to use System.Logger rather than SLF4J-API (better support for jlink / module-path) --- http-client/client/pom.xml | 13 ++++---- .../java/io/avaje/http/client/DHttpApi.java | 9 +++-- .../io/avaje/http/client/RequestLogger.java | 33 +++++++++---------- .../avaje/http/client/SimpleRetryHandler.java | 10 +++--- .../client/src/main/java/module-info.java | 1 - 5 files changed, 32 insertions(+), 34 deletions(-) diff --git a/http-client/client/pom.xml b/http-client/client/pom.xml index b07552557..69eee9480 100644 --- a/http-client/client/pom.xml +++ b/http-client/client/pom.xml @@ -18,12 +18,6 @@ - - org.slf4j - slf4j-api - 1.7.36 - - com.fasterxml.jackson.core jackson-databind @@ -40,6 +34,13 @@ + + io.avaje + avaje-slf4j-jpl + 1.0 + test + + io.avaje junit diff --git a/http-client/client/src/main/java/io/avaje/http/client/DHttpApi.java b/http-client/client/src/main/java/io/avaje/http/client/DHttpApi.java index 25376f4a0..86ba99eae 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/DHttpApi.java +++ b/http-client/client/src/main/java/io/avaje/http/client/DHttpApi.java @@ -1,18 +1,17 @@ package io.avaje.http.client; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.util.HashMap; import java.util.Map; import java.util.ServiceLoader; +import static java.lang.System.Logger.Level.*; + /** * Service loads the HttpApiProvider for HttpApi. */ final class DHttpApi { - private static final Logger log = LoggerFactory.getLogger(DHttpApi.class); + private static final System.Logger log = System.getLogger("io.avaje.http.client"); private static final DHttpApi INSTANCE = new DHttpApi(); @@ -27,7 +26,7 @@ void init() { for (HttpApiProvider apiProvider : ServiceLoader.load(HttpApiProvider.class)) { addProvider(apiProvider); } - log.debug("providers for {}", providerMap.keySet()); + log.log(DEBUG, "providers for %s", providerMap.keySet()); } void addProvider(HttpApiProvider apiProvider) { diff --git a/http-client/client/src/main/java/io/avaje/http/client/RequestLogger.java b/http-client/client/src/main/java/io/avaje/http/client/RequestLogger.java index 48b8a53b9..b673b2d36 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/RequestLogger.java +++ b/http-client/client/src/main/java/io/avaje/http/client/RequestLogger.java @@ -1,8 +1,6 @@ package io.avaje.http.client; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - +import java.lang.System.Logger.Level; import java.net.http.HttpHeaders; import java.net.http.HttpRequest; import java.net.http.HttpResponse; @@ -11,23 +9,24 @@ import java.util.Set; /** - * Logs request and response details for debug logging purposes. + * Logs request and response details for debug logging purposes using System.Logger. + *

+ * This implementation logs the request and response with the same single logging entry + * rather than separate logging of the request and response. *

- * This implementation logs the request and response with the same - * single logging entry rather than separate logging of the request - * and response. + * With logging level set to {@code DEBUG} for {@code io.avaje.http.client.RequestLogger} the + * request and response are logged as a summary with response status and time. *

- * With logging level set to {@code DEBUG} for - * {@code io.avaje.http.client.RequestLogger} the request and response - * are logged as a summary with response status and time. + * Set the logging level to {@code TRACE} to include the request and response headers and body + * payloads with truncation for large bodies. *

- * Set the logging level to {@code TRACE} to include the request - * and response headers and body payloads with truncation for large - * bodies. + * Using System.Logger, messages by default go to JUL (Java Util Logging) unless a provider + * is registered. We can use io.avaje:avaje-slf4j-jpl to have System.Logger + * messages go to slf4j-api. */ public class RequestLogger implements RequestListener { - private static final Logger log = LoggerFactory.getLogger(RequestLogger.class); + private static final System.Logger log = System.getLogger("io.avaje.http.client.RequestLogger"); private final String delimiter; @@ -47,7 +46,7 @@ public RequestLogger(String delimiter) { @Override public void response(Event event) { - if (log.isDebugEnabled()) { + if (log.isLoggable(Level.DEBUG)) { final HttpResponse response = event.response(); final HttpRequest request = response.request(); long micros = event.responseTimeMicros(); @@ -58,13 +57,13 @@ public void response(Event event) { .append(" uri:").append(event.uri()) .append(" timeMicros:").append(micros); - if (log.isTraceEnabled()) { + if (log.isLoggable(Level.TRACE)) { headers(sb, "req-head: ", request.headers()); body(sb, "req-body: ", event.requestBody()); headers(sb, "res-head: ", response.headers()); body(sb, "res-body: ", event.responseBody()); } - log.debug(sb.toString()); + log.log(Level.DEBUG, sb.toString()); } } diff --git a/http-client/client/src/main/java/io/avaje/http/client/SimpleRetryHandler.java b/http-client/client/src/main/java/io/avaje/http/client/SimpleRetryHandler.java index 9089046d3..6ec75aa8d 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/SimpleRetryHandler.java +++ b/http-client/client/src/main/java/io/avaje/http/client/SimpleRetryHandler.java @@ -1,8 +1,6 @@ package io.avaje.http.client; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - +import java.lang.System.Logger.Level; import java.net.http.HttpResponse; import java.util.Random; @@ -11,7 +9,7 @@ */ public class SimpleRetryHandler implements RetryHandler { - private static final Logger log = LoggerFactory.getLogger(SimpleRetryHandler.class); + private static final System.Logger log = System.getLogger("io.avaje.http.client"); private final int maxRetries; private final long backoffMillis; @@ -47,7 +45,9 @@ public boolean isRetry(int retryCount, HttpResponse response) { if (response.statusCode() < 500 || retryCount >= maxRetries) { return false; } - log.debug("retry count:{} status:{} uri:{}", retryCount, response.statusCode(), response.uri()); + if (log.isLoggable(Level.DEBUG)) { + log.log(Level.DEBUG, "retry count:%s status:%s uri:%s", retryCount, response.statusCode(), response.uri()); + } try { int gitter = gitterMillis < 1 ? 0 : random.nextInt(gitterMillis); Thread.sleep(backoffMillis + gitter); diff --git a/http-client/client/src/main/java/module-info.java b/http-client/client/src/main/java/module-info.java index a7b6fcbf4..dbd155928 100644 --- a/http-client/client/src/main/java/module-info.java +++ b/http-client/client/src/main/java/module-info.java @@ -3,7 +3,6 @@ uses io.avaje.http.client.HttpApiProvider; requires transitive java.net.http; - requires transitive org.slf4j; requires static com.fasterxml.jackson.databind; requires static com.fasterxml.jackson.annotation; requires static com.fasterxml.jackson.core; From 9f2eff568d0b54f3fb661cdebc8bc77b7c08f18e Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Fri, 25 Feb 2022 17:44:10 +1300 Subject: [PATCH 0251/1323] Update README --- http-client/README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/http-client/README.md b/http-client/README.md index 96e3d82ba..2c086cc1e 100644 --- a/http-client/README.md +++ b/http-client/README.md @@ -24,7 +24,7 @@ A lightweight wrapper to the [JDK 11+ Java Http Client](http://openjdk.java.net/ io.avaje avaje-http-client - 1.12 + 1.14 ``` @@ -37,7 +37,6 @@ Create a HttpClientContext with a baseUrl, Jackson or Gson based JSON public HttpClientContext client() { return HttpClientContext.newBuilder() .withBaseUrl(baseUrl) - .withRequestListener(new RequestLogger()) .withBodyAdapter(new JacksonBodyAdapter(new ObjectMapper())) // .withBodyAdapter(new GsonBodyAdapter(new Gson())) .build(); From f6864b8c1d0cbcdbe9ed465a548ca80b18bad852 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Wed, 4 May 2022 13:05:29 +1200 Subject: [PATCH 0252/1323] Bump optional dependency avaje-jsonb to 0.15 --- http-client/client/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/http-client/client/pom.xml b/http-client/client/pom.xml index 69eee9480..d401f69cc 100644 --- a/http-client/client/pom.xml +++ b/http-client/client/pom.xml @@ -28,7 +28,7 @@ io.avaje avaje-jsonb - 0.12 + 0.15 true From 085077846d16655bc03b2ba721f71ec377828fce Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Thu, 5 May 2022 08:51:11 +1200 Subject: [PATCH 0253/1323] #46 - Change method .newBuilder() -> .builder() with deprecation --- http-client/README.md | 21 ++++++++++--------- .../client/DHttpClientContextBuilder.java | 2 +- .../avaje/http/client/HttpClientContext.java | 18 +++++++++++----- .../avaje/http/client/JacksonBodyAdapter.java | 2 +- .../avaje/http/client/JsonbBodyAdapter.java | 2 +- .../io/avaje/http/client/package-info.java | 2 +- .../io/avaje/http/client/AuthTokenTest.java | 2 +- .../io/avaje/http/client/BaseWebTest.java | 2 +- .../http/client/BasicAuthInterceptTest.java | 2 +- .../io/avaje/http/client/DHttpApiTest.java | 4 ++-- .../http/client/DHttpClientContextTest.java | 6 +++--- .../avaje/http/client/HelloBasicAuthTest.java | 2 +- .../http/client/RequestListenerTest.java | 3 +-- .../java/io/avaje/http/client/RetryTest.java | 2 +- .../java/org/example/github/GithubTest.java | 2 +- .../http/client/gson/GsonBodyAdapter.java | 10 ++++----- .../test/java/example/github/GithubTest.java | 2 +- 17 files changed, 46 insertions(+), 38 deletions(-) diff --git a/http-client/README.md b/http-client/README.md index 2c086cc1e..97e894403 100644 --- a/http-client/README.md +++ b/http-client/README.md @@ -35,10 +35,11 @@ Create a HttpClientContext with a baseUrl, Jackson or Gson based JSON ```java public HttpClientContext client() { - return HttpClientContext.newBuilder() - .withBaseUrl(baseUrl) - .withBodyAdapter(new JacksonBodyAdapter(new ObjectMapper())) -// .withBodyAdapter(new GsonBodyAdapter(new Gson())) + return HttpClientContext.builder() + .baseUrl(baseUrl) + .bodyAdapter(new JsonbBodyAdapter()) + //.bodyAdapter(new JacksonBodyAdapter(new ObjectMapper())) + //.bodyAdapter(new GsonBodyAdapter(new Gson())) .build(); } @@ -443,10 +444,10 @@ header ("Basic Auth"). ```java HttpClientContext clientContext = - HttpClientContext.newBuilder() - .withBaseUrl(baseUrl) + HttpClientContext.builder() + .baseUrl(baseUrl) ... - .withRequestIntercept(new BasicAuthIntercept("myUsername", "myPassword")) -proc:none diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index ebcf1e780..f99f77a18 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -61,7 +61,7 @@ org.apache.maven.plugins maven-compiler-plugin - 3.8.1 + 3.10.1 1.8 1.8 diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index 39c879ac6..cd09e6a8a 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -27,7 +27,7 @@ org.apache.maven.plugins maven-compiler-plugin - 3.8.1 + 3.10.1 1.8 1.8 diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index d3ca0421f..b275d5e56 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -27,7 +27,7 @@ org.apache.maven.plugins maven-compiler-plugin - 3.8.1 + 3.10.1 1.8 1.8 diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index 5e326c3f1..4c5d2510a 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -27,7 +27,7 @@ org.apache.maven.plugins maven-compiler-plugin - 3.8.1 + 3.10.1 1.8 1.8 diff --git a/http-generator-spark/pom.xml b/http-generator-spark/pom.xml index 6fe67ef38..815570adb 100644 --- a/http-generator-spark/pom.xml +++ b/http-generator-spark/pom.xml @@ -28,7 +28,7 @@ org.apache.maven.plugins maven-compiler-plugin - 3.8.1 + 3.10.1 1.8 1.8 diff --git a/pom.xml b/pom.xml index 8e21242bc..a6e126490 100644 --- a/pom.xml +++ b/pom.xml @@ -24,9 +24,9 @@ - org.avaje.composite + io.avaje junit - 5.1 + 1.1 test diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index bb6c70815..b3de2a760 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -4,7 +4,8 @@ java11-oss org.avaje - 3.2 + 3.8 + 4.0.0 @@ -15,15 +16,15 @@ true 1.6 - 6.12 + 8.3 - org.avaje.composite + org.avaje logback - 1.1 + 1.0 @@ -101,7 +102,7 @@ org.apache.maven.plugins maven-compiler-plugin - 3.8.1 + 3.10.1 diff --git a/tests/test-helidon/pom.xml b/tests/test-helidon/pom.xml index b9a471fff..73a38c0d2 100644 --- a/tests/test-helidon/pom.xml +++ b/tests/test-helidon/pom.xml @@ -9,7 +9,8 @@ org.avaje java11-oss - 3.2 + 3.8 + @@ -125,7 +126,7 @@ org.apache.maven.plugins maven-compiler-plugin - 3.8.1 + 3.10.1 11 diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 898bda9ba..af2829151 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -9,7 +9,8 @@ org.avaje java11-oss - 3.2 + 3.8 + @@ -25,9 +26,9 @@ - org.avaje.composite + org.avaje logback - 1.1 + 1.0 @@ -63,7 +64,7 @@ io.avaje avaje-http-hibernate-validator - 2.6 + 2.8 @@ -91,9 +92,9 @@ - org.avaje.composite + io.avaje junit - 5.1 + 1.1 test diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 274be86ad..f55492401 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -9,7 +9,8 @@ org.avaje java11-oss - 3.2 + 3.8 + @@ -18,16 +19,16 @@ 2.0 2.0.8 2.12.3 - 6.12 + 8.3 1.13-SNAPSHOT - org.avaje.composite + org.avaje logback - 1.1 + 1.0 @@ -63,7 +64,7 @@ io.avaje avaje-http-hibernate-validator - 2.6 + 2.8 @@ -91,9 +92,9 @@ - org.avaje.composite + io.avaje junit - 5.1 + 1.1 test diff --git a/tests/test-spark/pom.xml b/tests/test-spark/pom.xml index dcbe44ffb..d88f6e64f 100644 --- a/tests/test-spark/pom.xml +++ b/tests/test-spark/pom.xml @@ -23,9 +23,9 @@ - org.avaje.composite + org.avaje logback - 1.1 + 1.0 @@ -55,7 +55,7 @@ io.avaje avaje-http-hibernate-validator - 2.6 + 2.8 @@ -83,9 +83,9 @@ - org.avaje.composite + io.avaje junit - 5.1 + 1.1 test From 8320015a6f533f65473d33825bcbd0a0938dae90 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 19 May 2022 06:18:07 +0000 Subject: [PATCH 0272/1323] Bump jackson-databind from 2.12.3 to 2.12.6.1 in /tests/test-jex Bumps [jackson-databind](https://github.com/FasterXML/jackson) from 2.12.3 to 2.12.6.1. - [Release notes](https://github.com/FasterXML/jackson/releases) - [Commits](https://github.com/FasterXML/jackson/commits) --- updated-dependencies: - dependency-name: com.fasterxml.jackson.core:jackson-databind dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- tests/test-jex/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index f55492401..4ec3294a2 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -18,7 +18,7 @@ org.example.myapp.Main 2.0 2.0.8 - 2.12.3 + 2.12.6.1 8.3 1.13-SNAPSHOT From 7170c2831e3f36837edd0d32fab37794e4e6b525 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Thu, 19 May 2022 18:23:46 +1200 Subject: [PATCH 0273/1323] Bump to 1.16-SNAPSHOT --- .github/workflows/build.yml | 36 +++++++++++++++++++++++++++++ .github/workflows/jdk-ea.yml | 41 ++++++++++++++++++++++++++++++++++ http-api/pom.xml | 2 +- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 4 ++-- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- pom.xml | 2 +- tests/test-client/pom.xml | 2 +- tests/test-helidon/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- 13 files changed, 89 insertions(+), 12 deletions(-) create mode 100644 .github/workflows/build.yml create mode 100644 .github/workflows/jdk-ea.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 000000000..e921ac573 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,36 @@ +name: Build + +on: [push, pull_request, workflow_dispatch] + +jobs: + build: + + runs-on: ${{ matrix.os }} + permissions: + contents: read + packages: write + strategy: + fail-fast: false + matrix: + java_version: [11,17] + os: [ubuntu-latest] + + steps: + - uses: actions/checkout@v2 + - name: Set up Java + uses: actions/setup-java@v2 + with: + java-version: ${{ matrix.java_version }} + distribution: 'zulu' + - name: Maven cache + uses: actions/cache@v2 + env: + cache-name: maven-cache + with: + path: + ~/.m2 + key: build-${{ env.cache-name }} + - name: Maven version + run: mvn --version + - name: Build with Maven + run: mvn clean test diff --git a/.github/workflows/jdk-ea.yml b/.github/workflows/jdk-ea.yml new file mode 100644 index 000000000..91ba1659a --- /dev/null +++ b/.github/workflows/jdk-ea.yml @@ -0,0 +1,41 @@ + +name: avaje-inject EA + +on: + workflow_dispatch: + schedule: + - cron: '39 1 * * 1,3,5' + +jobs: + build: + + runs-on: ${{ matrix.os }} + permissions: + contents: read + packages: write + strategy: + fail-fast: false + matrix: + java_version: [GA,EA] ## valhalla (fails javadoc) + os: [ubuntu-latest] + + steps: + - uses: actions/checkout@v2 + - name: Set up Java + uses: oracle-actions/setup-java@v1 + with: + website: jdk.java.net + release: ${{ matrix.java_version }} + - name: Maven cache + uses: actions/cache@v2 + env: + cache-name: maven-cache + with: + path: + ~/.m2 + key: build-${{ env.cache-name }} + - name: Maven version + run: mvn --version + - name: Build with Maven + run: mvn package + diff --git a/http-api/pom.xml b/http-api/pom.xml index c3f5a8a19..ce513555c 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-generator-parent - 1.13-SNAPSHOT + 1.16-SNAPSHOT .. diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index 1472df1fd..2fddcfdf4 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -5,7 +5,7 @@ io.avaje avaje-http-generator-parent - 1.13-SNAPSHOT + 1.16-SNAPSHOT .. diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index f99f77a18..c0b55d564 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-generator-parent - 1.13-SNAPSHOT + 1.16-SNAPSHOT .. @@ -33,7 +33,7 @@ io.avaje avaje-http-api - 1.13-SNAPSHOT + 1.16-SNAPSHOT diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index cd09e6a8a..2425e888d 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-generator-parent - 1.13-SNAPSHOT + 1.16-SNAPSHOT .. diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index b275d5e56..0b2f33e3d 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-generator-parent - 1.13-SNAPSHOT + 1.16-SNAPSHOT .. diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index 4c5d2510a..f04efe934 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-generator-parent - 1.13-SNAPSHOT + 1.16-SNAPSHOT .. diff --git a/pom.xml b/pom.xml index a6e126490..8b1ce2626 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-generator-parent - 1.13-SNAPSHOT + 1.16-SNAPSHOT pom diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index b3de2a760..68f5840df 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -36,7 +36,7 @@ io.avaje avaje-http-api - 1.13-SNAPSHOT + 1.16-SNAPSHOT diff --git a/tests/test-helidon/pom.xml b/tests/test-helidon/pom.xml index 73a38c0d2..7449f170d 100644 --- a/tests/test-helidon/pom.xml +++ b/tests/test-helidon/pom.xml @@ -17,7 +17,7 @@ true org.example.Main 2.3.0 - 1.13-SNAPSHOT + 1.16-SNAPSHOT diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index af2829151..70f43d065 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -20,7 +20,7 @@ 2.0.8 1.3.71 2.12.3 - 1.13-SNAPSHOT + 1.16-SNAPSHOT diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index f55492401..45ddc2169 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -20,7 +20,7 @@ 2.0.8 2.12.3 8.3 - 1.13-SNAPSHOT + 1.16-SNAPSHOT From fdc99ecebc16bdef4bcb694f03c8119fea31cb9a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 19 May 2022 06:24:26 +0000 Subject: [PATCH 0274/1323] Bump jackson-databind from 2.12.3 to 2.12.6.1 in /tests/test-javalin Bumps [jackson-databind](https://github.com/FasterXML/jackson) from 2.12.3 to 2.12.6.1. - [Release notes](https://github.com/FasterXML/jackson/releases) - [Commits](https://github.com/FasterXML/jackson/commits) --- updated-dependencies: - dependency-name: com.fasterxml.jackson.core:jackson-databind dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- tests/test-javalin/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 70f43d065..7b24410bc 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -19,7 +19,7 @@ 4.1.1 2.0.8 1.3.71 - 2.12.3 + 2.12.6.1 1.16-SNAPSHOT From 38db853491dfb3a64e8a0fb5b2502dafea621fa5 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Thu, 19 May 2022 18:39:39 +1200 Subject: [PATCH 0275/1323] Bump test avaje-http-client dependency --- .github/workflows/jdk-ea.yml | 2 +- tests/test-client/pom.xml | 2 +- tests/test-helidon/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-spark/pom.xml | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/jdk-ea.yml b/.github/workflows/jdk-ea.yml index 91ba1659a..9b8ba702e 100644 --- a/.github/workflows/jdk-ea.yml +++ b/.github/workflows/jdk-ea.yml @@ -37,5 +37,5 @@ jobs: - name: Maven version run: mvn --version - name: Build with Maven - run: mvn package + run: mvn clean verify diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index 68f5840df..d875d2228 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -30,7 +30,7 @@ io.avaje avaje-http-client - 1.11 + 1.16 diff --git a/tests/test-helidon/pom.xml b/tests/test-helidon/pom.xml index 7449f170d..0a1ffa972 100644 --- a/tests/test-helidon/pom.xml +++ b/tests/test-helidon/pom.xml @@ -115,7 +115,7 @@ io.avaje avaje-http-client - 1.11 + 1.16 test diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 70f43d065..2ee844fbf 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -108,7 +108,7 @@ io.avaje avaje-http-client - 1.11 + 1.16 test diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 45ddc2169..81597cb89 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -101,7 +101,7 @@ io.avaje avaje-http-client - 1.11 + 1.16 test diff --git a/tests/test-spark/pom.xml b/tests/test-spark/pom.xml index d88f6e64f..b982bcd0b 100644 --- a/tests/test-spark/pom.xml +++ b/tests/test-spark/pom.xml @@ -93,7 +93,7 @@ io.avaje avaje-http-client - 1.11 + 1.16 test From 3b060f53611ac57651f05a61a1670ee0483c6118 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Thu, 19 May 2022 18:43:12 +1200 Subject: [PATCH 0276/1323] Bump to 1.16-SNAPSHOT --- tests/test-client/pom.xml | 4 ++-- tests/test-spark/pom.xml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index d875d2228..d3242b7e9 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -108,12 +108,12 @@ io.avaje avaje-http-client-generator - 1.12-SNAPSHOT + 1.16-SNAPSHOT io.avaje avaje-http-jex-generator - 1.12-SNAPSHOT + 1.16-SNAPSHOT io.avaje diff --git a/tests/test-spark/pom.xml b/tests/test-spark/pom.xml index b982bcd0b..4bea9011c 100644 --- a/tests/test-spark/pom.xml +++ b/tests/test-spark/pom.xml @@ -17,7 +17,7 @@ org.example.myapp.Main 2.0.8 - 1.12-SNAPSHOT + 1.16-SNAPSHOT @@ -76,7 +76,7 @@ io.avaje avaje-http-spark-generator - 1.12-SNAPSHOT + 1.16-SNAPSHOT provided From a682b983937efdda7e3edf5c115de67f380e1570 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Thu, 19 May 2022 18:43:46 +1200 Subject: [PATCH 0277/1323] Bump to 1.16-SNAPSHOT --- http-generator-spark/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/http-generator-spark/pom.xml b/http-generator-spark/pom.xml index 815570adb..2942b15da 100644 --- a/http-generator-spark/pom.xml +++ b/http-generator-spark/pom.xml @@ -8,7 +8,7 @@ io.avaje avaje-http-generator-parent - 1.2-SNAPSHOT + 1.16-SNAPSHOT .. From de04111a747097bb474d985718999a208a1ab862 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Thu, 19 May 2022 18:44:53 +1200 Subject: [PATCH 0278/1323] Remove http-generator-spark --- http-generator-spark/pom.xml | 43 -------- .../spark/ControllerMethodWriter.java | 103 ------------------ .../generator/spark/ControllerWriter.java | 79 -------------- .../http/generator/spark/SparkAdapter.java | 89 --------------- .../http/generator/spark/SparkProcessor.java | 21 ---- .../javax.annotation.processing.Processor | 1 - 6 files changed, 336 deletions(-) delete mode 100644 http-generator-spark/pom.xml delete mode 100644 http-generator-spark/src/main/java/io/avaje/http/generator/spark/ControllerMethodWriter.java delete mode 100644 http-generator-spark/src/main/java/io/avaje/http/generator/spark/ControllerWriter.java delete mode 100644 http-generator-spark/src/main/java/io/avaje/http/generator/spark/SparkAdapter.java delete mode 100644 http-generator-spark/src/main/java/io/avaje/http/generator/spark/SparkProcessor.java delete mode 100644 http-generator-spark/src/main/resources/META-INF/services/javax.annotation.processing.Processor diff --git a/http-generator-spark/pom.xml b/http-generator-spark/pom.xml deleted file mode 100644 index 2942b15da..000000000 --- a/http-generator-spark/pom.xml +++ /dev/null @@ -1,43 +0,0 @@ - - - 4.0.0 - - avaje-http-spark-generator - - - - io.avaje - avaje-http-generator-parent - 1.16-SNAPSHOT - .. - - - - - - io.avaje - avaje-http-generator-core - ${project.version} - - - - - - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.10.1 - - 1.8 - 1.8 - - -proc:none - - - - - - - diff --git a/http-generator-spark/src/main/java/io/avaje/http/generator/spark/ControllerMethodWriter.java b/http-generator-spark/src/main/java/io/avaje/http/generator/spark/ControllerMethodWriter.java deleted file mode 100644 index 341da6c09..000000000 --- a/http-generator-spark/src/main/java/io/avaje/http/generator/spark/ControllerMethodWriter.java +++ /dev/null @@ -1,103 +0,0 @@ -package io.avaje.http.generator.spark; - -import io.avaje.http.api.MediaType; -import io.avaje.http.generator.core.Append; -import io.avaje.http.generator.core.MethodParam; -import io.avaje.http.generator.core.MethodReader; -import io.avaje.http.generator.core.PathSegments; -import io.avaje.http.generator.core.ProcessingContext; -import io.avaje.http.generator.core.WebMethod; - -import java.util.List; - -/** - * Write code to register Web route for a given controller method. - */ -class ControllerMethodWriter { - - private final MethodReader method; - private final Append writer; - private final WebMethod webMethod; - private final ProcessingContext ctx; - - ControllerMethodWriter(MethodReader method, Append writer, ProcessingContext ctx) { - this.method = method; - this.writer = writer; - this.webMethod = method.getWebMethod(); - this.ctx = ctx; - } - - void write(boolean requestScoped) { - - final PathSegments segments = method.getPathSegments(); - final String fullPath = segments.fullPathColon(); - - writer.append(" Spark.%s(\"%s\", (request, response) -> {", webMethod.name().toLowerCase(), fullPath).eol(); - writer.append(" response.status(%s);", method.getStatusCode()).eol(); - - List matrixSegments = segments.matrixSegments(); - for (PathSegments.Segment matrixSegment : matrixSegments) { - matrixSegment.writeCreateSegment(writer, ctx.platform()); - } - - final List params = method.getParams(); - for (MethodParam param : params) { - param.writeCtxGet(writer, segments); - } - writer.append(" "); - if (method.includeValidate()) { - for (MethodParam param : params) { - param.writeValidate(writer); - } - } - if (!method.isVoid()) { - writeContextReturn(); - } - - if (requestScoped) { - writer.append("factory.create(request, response)."); - } else { - writer.append("controller."); - } - writer.append(method.simpleName()).append("("); - for (int i = 0; i < params.size(); i++) { - if (i > 0) { - writer.append(", "); - } - params.get(i).buildParamName(writer); - } - writer.append(")"); -// if (!method.isVoid()) { -// writer.append(";");//")" -// } - writer.append(";").eol(); - writer.append(" }"); - -// List roles = method.roles(); -// if (!roles.isEmpty()) { -// writer.append(", roles("); -// for (int i = 0; i < roles.size(); i++) { -// if (i > 0) { -// writer.append(", "); -// } -// writer.append(Util.shortName(roles.get(i))); -// } -// writer.append(")"); -// } - writer.append(");").eol().eol(); //) - } - - private void writeContextReturn() { - final String produces = method.getProduces(); - if (produces == null || produces.equalsIgnoreCase(MediaType.APPLICATION_JSON)) { - //writer.append("response.type(\"application/json\")"); - } else if (produces.equalsIgnoreCase(MediaType.TEXT_HTML)) { - writer.append("response.type(\"text/html\");").eol().append(" "); - } else if (produces.equalsIgnoreCase(MediaType.TEXT_PLAIN)) { - writer.append("response.type(\"text/plain\");").eol().append(" "); - } else { - writer.append("response.type(\"%s\");", produces).eol().append(" "); - } - writer.append("return "); - } -} diff --git a/http-generator-spark/src/main/java/io/avaje/http/generator/spark/ControllerWriter.java b/http-generator-spark/src/main/java/io/avaje/http/generator/spark/ControllerWriter.java deleted file mode 100644 index e198117d6..000000000 --- a/http-generator-spark/src/main/java/io/avaje/http/generator/spark/ControllerWriter.java +++ /dev/null @@ -1,79 +0,0 @@ -package io.avaje.http.generator.spark; - -import io.avaje.http.generator.core.BaseControllerWriter; -import io.avaje.http.generator.core.ControllerReader; -import io.avaje.http.generator.core.MethodReader; -import io.avaje.http.generator.core.ProcessingContext; - -import java.io.IOException; - -/** - * Write Javalin specific Controller WebRoute handling adapter. - */ -class ControllerWriter extends BaseControllerWriter { - - private static final String AT_GENERATED = "@Generated(\"io.dinject.javalin-generator\")"; - private static final String API_BUILDER = "spark.Spark"; - - ControllerWriter(ControllerReader reader, ProcessingContext ctx) throws IOException { - super(reader, ctx); - reader.addImportType(API_BUILDER); - } - - void write() { - writePackage(); - writeImports(); - writeClassStart(); - writeAddRoutes(); - writeClassEnd(); - } - - private void writeAddRoutes() { - writer.append(" @Override").eol(); - writer.append(" public void registerRoutes() {").eol().eol(); - for (MethodReader method : reader.getMethods()) { - if (method.isWebMethod()) { - writeForMethod(method); - } - } - writer.append(" }").eol().eol(); - } - - private void writeForMethod(MethodReader method) { - new ControllerMethodWriter(method, writer, ctx).write(isRequestScoped()); - if (!reader.isDocHidden()) { - method.buildApiDocumentation(ctx); - } - } - - private void writeClassStart() { - writer.append(AT_GENERATED).eol(); - writer.append("@Singleton").eol(); - writer.append("public class ").append(shortName).append("$Route implements WebRoutes {").eol().eol(); - - String controllerName = "controller"; - String controllerType = shortName; - if (isRequestScoped()) { - controllerName = "factory"; - controllerType += Constants.FACTORY_SUFFIX; - } - writer.append(" private final %s %s;", controllerType, controllerName).eol(); - - if (reader.isIncludeValidator()) { - writer.append(" private final Validator validator;").eol(); - } - writer.eol(); - - writer.append(" public %s$Route(%s %s", shortName, controllerType, controllerName); - if (reader.isIncludeValidator()) { - writer.append(", Validator validator"); - } - writer.append(") {").eol(); - writer.append(" this.%s = %s;", controllerName, controllerName).eol(); - if (reader.isIncludeValidator()) { - writer.append(" this.validator = validator;").eol(); - } - writer.append(" }").eol().eol(); - } - -} diff --git a/http-generator-spark/src/main/java/io/avaje/http/generator/spark/SparkAdapter.java b/http-generator-spark/src/main/java/io/avaje/http/generator/spark/SparkAdapter.java deleted file mode 100644 index 032626427..000000000 --- a/http-generator-spark/src/main/java/io/avaje/http/generator/spark/SparkAdapter.java +++ /dev/null @@ -1,89 +0,0 @@ -package io.avaje.http.generator.spark; - -import io.avaje.http.generator.core.Append; -import io.avaje.http.generator.core.ControllerReader; -import io.avaje.http.generator.core.ParamType; -import io.avaje.http.generator.core.PlatformAdapter; - -import java.util.List; - -class SparkAdapter implements PlatformAdapter { - - static final String REQ = "spark.Request"; - static final String RES = "spark.Response"; - - @Override - public boolean isContextType(String rawType) { - return REQ.equals(rawType) || RES.equals(rawType); - } - - @Override - public String platformVariable(String rawType) { - if (REQ.equals(rawType)) { - return "request"; - } - if (RES.equals(rawType)) { - return "response"; - } - return "unknownVariable for: " + rawType; - } - - @Override - public boolean isBodyMethodParam() { - return false; - } - - @Override - public String bodyAsClass(String shortType) { - return "ctx.bodyAsClass(" + shortType + ".class)"; - } - - @Override - public String indent() { - return " "; - } - - @Override - public void controllerRoles(List roles, ControllerReader controller) { - addRoleImports(roles, controller); - } - - @Override - public void methodRoles(List roles, ControllerReader controller) { - addRoleImports(roles, controller); - } - - private void addRoleImports(List roles, ControllerReader controller) { - - } - - @Override - public void writeReadParameter(Append writer, ParamType paramType, String paramName) { - switch (paramType) { - case PATHPARAM: - writer.append("request.params(\"%s\")", paramName); - break; - case QUERYPARAM: - case FORMPARAM: - writer.append("request.queryParams(\"%s\")", paramName); - break; - default: - writer.append("request.%s(\"%s\")", paramType, paramName); - } - } - - @Override - public void writeReadParameter(Append writer, ParamType paramType, String paramName, String paramDefault) { - switch (paramType) { - case PATHPARAM: - writer.append("request.params(\"%s\")", paramName); - break; - case QUERYPARAM: - case FORMPARAM: - writer.append("request.queryParamsOrDefault(\"%s\",\"%s\")", paramName, paramDefault); - break; - default: - writer.append("request.%s(\"%s\",\"%s\")", paramType, paramName, paramDefault); - } - } -} diff --git a/http-generator-spark/src/main/java/io/avaje/http/generator/spark/SparkProcessor.java b/http-generator-spark/src/main/java/io/avaje/http/generator/spark/SparkProcessor.java deleted file mode 100644 index a0a7df5d0..000000000 --- a/http-generator-spark/src/main/java/io/avaje/http/generator/spark/SparkProcessor.java +++ /dev/null @@ -1,21 +0,0 @@ -package io.avaje.http.generator.spark; - -import io.avaje.http.generator.core.BaseProcessor; -import io.avaje.http.generator.core.ControllerReader; -import io.avaje.http.generator.core.PlatformAdapter; -import io.avaje.http.generator.core.ProcessingContext; - -import java.io.IOException; - -public class SparkProcessor extends BaseProcessor { - - @Override - protected PlatformAdapter providePlatformAdapter() { - return new SparkAdapter(); - } - - @Override - public void writeControllerAdapter(ProcessingContext ctx, ControllerReader reader) throws IOException { - new ControllerWriter(reader, ctx).write(); - } -} diff --git a/http-generator-spark/src/main/resources/META-INF/services/javax.annotation.processing.Processor b/http-generator-spark/src/main/resources/META-INF/services/javax.annotation.processing.Processor deleted file mode 100644 index 50fe0c7fe..000000000 --- a/http-generator-spark/src/main/resources/META-INF/services/javax.annotation.processing.Processor +++ /dev/null @@ -1 +0,0 @@ -io.avaje.http.generator.spark.SparkProcessor From 1e0fa1d07eb45a8b6c2431051728b1a38d97f473 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Thu, 19 May 2022 19:48:06 +1200 Subject: [PATCH 0279/1323] Fix SimpleTest for updated http client generation --- tests/test-client/src/test/java/org/example/SimpleTest.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/test-client/src/test/java/org/example/SimpleTest.java b/tests/test-client/src/test/java/org/example/SimpleTest.java index d3e4d7575..006c8fe72 100644 --- a/tests/test-client/src/test/java/org/example/SimpleTest.java +++ b/tests/test-client/src/test/java/org/example/SimpleTest.java @@ -5,8 +5,8 @@ import io.avaje.http.client.HttpApiProvider; import io.avaje.http.client.HttpClientContext; import io.avaje.http.client.JacksonBodyAdapter; -import io.avaje.http.client.RequestLogger; -import org.example.httpclient.GitHubUsers$HttpClient; + +import org.example.httpclient.GitHubUsersHttpClient; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; @@ -46,7 +46,7 @@ public Class type() { @Override public GitHubUsers provide(HttpClientContext client) { - return new GitHubUsers$HttpClient(client); + return new GitHubUsersHttpClient(client); } } } From 53a1bd2aaf73b6c05b0ffd97b2c0f694536b16e8 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Thu, 19 May 2022 20:00:51 +1200 Subject: [PATCH 0280/1323] Update test dependencies --- .../main/java/org/example/server/Main.java | 2 +- .../test/java/org/example/CommonApiTest.java | 2 +- .../src/test/java/org/example/SimpleTest.java | 2 +- tests/test-helidon/pom.xml | 21 ++++++++++--------- .../src/main/java/org/example/Main.java | 2 +- .../test/java/org/example/BaseWebTest.java | 2 +- tests/test-javalin/pom.xml | 6 +++--- .../src/main/java/org/example/myapp/Main.java | 2 +- .../java/org/example/myapp/BaseWebTest.java | 2 +- .../example/myapp/HelloControllerTest.java | 7 +------ .../src/main/java/org/example/Main.java | 2 +- .../java/org/example/web/BaseWebTest.java | 2 +- 12 files changed, 24 insertions(+), 28 deletions(-) diff --git a/tests/test-client/src/main/java/org/example/server/Main.java b/tests/test-client/src/main/java/org/example/server/Main.java index f6467f02a..1479466e2 100644 --- a/tests/test-client/src/main/java/org/example/server/Main.java +++ b/tests/test-client/src/main/java/org/example/server/Main.java @@ -13,7 +13,7 @@ public static void main(String[] args) { } public static Jex.Server start(int port) { - BeanScope beanScope = BeanScope.newBuilder().build(); + BeanScope beanScope = BeanScope.builder().build(); return start(port, beanScope); } diff --git a/tests/test-client/src/test/java/org/example/CommonApiTest.java b/tests/test-client/src/test/java/org/example/CommonApiTest.java index c51eaa0b9..268e97732 100644 --- a/tests/test-client/src/test/java/org/example/CommonApiTest.java +++ b/tests/test-client/src/test/java/org/example/CommonApiTest.java @@ -24,7 +24,7 @@ static void start() { final int port = new Random().nextInt(1000) + 10_000; Main.start(port); - final HttpClientContext clientContext = HttpClientContext.newBuilder() + final HttpClientContext clientContext = HttpClientContext.builder() .baseUrl("http://localhost:" + port) .bodyAdapter(new JacksonBodyAdapter()) .build(); diff --git a/tests/test-client/src/test/java/org/example/SimpleTest.java b/tests/test-client/src/test/java/org/example/SimpleTest.java index 006c8fe72..30e27b016 100644 --- a/tests/test-client/src/test/java/org/example/SimpleTest.java +++ b/tests/test-client/src/test/java/org/example/SimpleTest.java @@ -24,7 +24,7 @@ void listRepos() { .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); final HttpClientContext clientContext = - HttpClientContext.newBuilder() + HttpClientContext.builder() .baseUrl("https://api.github.com") .bodyAdapter(new JacksonBodyAdapter(objectMapper)) .build(); diff --git a/tests/test-helidon/pom.xml b/tests/test-helidon/pom.xml index 0a1ffa972..b5e215575 100644 --- a/tests/test-helidon/pom.xml +++ b/tests/test-helidon/pom.xml @@ -23,14 +23,15 @@ - ch.qos.logback - logback-classic - 1.2.3 + org.avaje + logback + 1.0 + org.slf4j jul-to-slf4j - 1.7.25 + 1.7.36 @@ -41,12 +42,12 @@ io.avaje avaje-inject - 6.12 + 8.3 io.avaje avaje-inject-generator - 6.12 + 8.3 provided @@ -83,14 +84,14 @@ org.junit.jupiter junit-jupiter-api - 5.6.2 + 5.8.2 test org.junit.jupiter junit-jupiter-engine - 5.6.2 + 5.8.2 test @@ -103,13 +104,13 @@ org.assertj assertj-core - 3.16.1 + 3.22.0 test io.rest-assured rest-assured - 4.3.1 + 5.0.1 test diff --git a/tests/test-helidon/src/main/java/org/example/Main.java b/tests/test-helidon/src/main/java/org/example/Main.java index 664cda221..d2bedebad 100644 --- a/tests/test-helidon/src/main/java/org/example/Main.java +++ b/tests/test-helidon/src/main/java/org/example/Main.java @@ -58,7 +58,7 @@ private static Routing createRouting() { .register(MetricsSupport.create()) .register("/greet", new GreetService()); - BeanScope beanScope = BeanScope.newBuilder().build(); + BeanScope beanScope = BeanScope.builder().build(); beanScope.list(Service.class).forEach(builder::register); return builder.build(); diff --git a/tests/test-helidon/src/test/java/org/example/BaseWebTest.java b/tests/test-helidon/src/test/java/org/example/BaseWebTest.java index fdbad0eea..77a6a899d 100644 --- a/tests/test-helidon/src/test/java/org/example/BaseWebTest.java +++ b/tests/test-helidon/src/test/java/org/example/BaseWebTest.java @@ -26,7 +26,7 @@ public static void shutdown() { } public static HttpClientContext client() { - return HttpClientContext.newBuilder() + return HttpClientContext.builder() .baseUrl(baseUrl) .bodyAdapter(new JacksonBodyAdapter()) .build(); diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index d6c79e4b5..d4ed6d6bb 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -52,7 +52,7 @@ io.avaje avaje-inject - 6.12 + 8.3 @@ -78,7 +78,7 @@ io.avaje avaje-inject-generator - 6.12 + 8.3 provided @@ -101,7 +101,7 @@ io.rest-assured rest-assured - 4.3.1 + 5.0.1 test diff --git a/tests/test-javalin/src/main/java/org/example/myapp/Main.java b/tests/test-javalin/src/main/java/org/example/myapp/Main.java index 1b69c32fc..cc4b92b1a 100644 --- a/tests/test-javalin/src/main/java/org/example/myapp/Main.java +++ b/tests/test-javalin/src/main/java/org/example/myapp/Main.java @@ -68,7 +68,7 @@ public static Javalin start(int port) { }); // All WebRoutes / Controllers ... from DI Context - BeanScope beanScope = BeanScope.newBuilder().build(); + BeanScope beanScope = BeanScope.builder().build(); List webRoutes = beanScope.list(WebRoutes.class); app.routes(() -> webRoutes.forEach(WebRoutes::registerRoutes)); diff --git a/tests/test-javalin/src/test/java/org/example/myapp/BaseWebTest.java b/tests/test-javalin/src/test/java/org/example/myapp/BaseWebTest.java index 263662051..a8539cc26 100644 --- a/tests/test-javalin/src/test/java/org/example/myapp/BaseWebTest.java +++ b/tests/test-javalin/src/test/java/org/example/myapp/BaseWebTest.java @@ -26,7 +26,7 @@ public static void shutdown() { } public static HttpClientContext client() { - return HttpClientContext.newBuilder() + return HttpClientContext.builder() .baseUrl(baseUrl) .bodyAdapter(new JacksonBodyAdapter()) .build(); diff --git a/tests/test-javalin/src/test/java/org/example/myapp/HelloControllerTest.java b/tests/test-javalin/src/test/java/org/example/myapp/HelloControllerTest.java index ab50eaa48..c007a848e 100644 --- a/tests/test-javalin/src/test/java/org/example/myapp/HelloControllerTest.java +++ b/tests/test-javalin/src/test/java/org/example/myapp/HelloControllerTest.java @@ -24,14 +24,9 @@ class HelloControllerTest extends BaseWebTest { final HttpClientContext clientContext; HelloControllerTest() { - - final HttpClient httpClient = HttpClient.newBuilder() - .build(); - - this.clientContext = HttpClientContext.newBuilder() + this.clientContext = HttpClientContext.builder() .baseUrl(baseUrl) .bodyAdapter(new JacksonBodyAdapter()) - .client(httpClient) .build(); } diff --git a/tests/test-jex/src/main/java/org/example/Main.java b/tests/test-jex/src/main/java/org/example/Main.java index 466315a18..c1bb6d537 100644 --- a/tests/test-jex/src/main/java/org/example/Main.java +++ b/tests/test-jex/src/main/java/org/example/Main.java @@ -18,7 +18,7 @@ public static void main(String[] args) { } public static Jex.Server start(int port) { - BeanScope beanScope = BeanScope.newBuilder().build(); + BeanScope beanScope = BeanScope.builder().build(); return start(port, beanScope); } diff --git a/tests/test-jex/src/test/java/org/example/web/BaseWebTest.java b/tests/test-jex/src/test/java/org/example/web/BaseWebTest.java index c3c4c1b35..e21361576 100644 --- a/tests/test-jex/src/test/java/org/example/web/BaseWebTest.java +++ b/tests/test-jex/src/test/java/org/example/web/BaseWebTest.java @@ -29,7 +29,7 @@ public static void shutdown() { } public static HttpClientContext client() { - return HttpClientContext.newBuilder() + return HttpClientContext.builder() .baseUrl(baseUrl) .requestTimeout(Duration.ofMinutes(2)) .bodyAdapter(new JacksonBodyAdapter()) From 660817d3cd29f39c5eaafcae48def4fade9e867c Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Thu, 19 May 2022 20:06:00 +1200 Subject: [PATCH 0281/1323] #73 Update client generation for 1.16 withHandler() -> handler() --- .../io/avaje/http/generator/client/ClientMethodWriter.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java index ae5f284bd..bebf499e4 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java @@ -144,9 +144,9 @@ private void writeResponse(String type0, String type1) { private void writeWithHandler() { if (bodyHandlerParam != null) { - writer.append(".withHandler(%s);", bodyHandlerParam.getName()).eol(); + writer.append(".handler(%s);", bodyHandlerParam.getName()).eol(); } else { - writer.append(".withHandler(responseHandler);").eol(); // Better to barf here? + writer.append(".handler(responseHandler);").eol(); // Better to barf here? } } From 4586b9248416004dbff61663a1d91b2ae544d476 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Thu, 19 May 2022 20:28:04 +1200 Subject: [PATCH 0282/1323] [maven-release-plugin] prepare release avaje-http-generator-parent-1.16 --- http-api/pom.xml | 4 ++-- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 4 ++-- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- pom.xml | 4 ++-- 7 files changed, 10 insertions(+), 10 deletions(-) diff --git a/http-api/pom.xml b/http-api/pom.xml index ce513555c..0d8aebf61 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-generator-parent - 1.16-SNAPSHOT + 1.16 .. @@ -20,7 +20,7 @@ scm:git:git@github.com:avaje/avaje-http.git - HEAD + avaje-http-generator-parent-1.16 diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index 2fddcfdf4..7b61a0932 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -5,7 +5,7 @@ io.avaje avaje-http-generator-parent - 1.16-SNAPSHOT + 1.16 .. diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index e2fbd25ff..88df221f4 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-generator-parent - 1.16-SNAPSHOT + 1.16 .. @@ -33,7 +33,7 @@ io.avaje avaje-http-api - 1.16-SNAPSHOT + 1.16 diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index 2425e888d..52d80fcb4 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-generator-parent - 1.16-SNAPSHOT + 1.16 .. diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index 0b2f33e3d..922d2f5e5 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-generator-parent - 1.16-SNAPSHOT + 1.16 .. diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index f04efe934..c2f1acbf1 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-generator-parent - 1.16-SNAPSHOT + 1.16 .. diff --git a/pom.xml b/pom.xml index 8b1ce2626..e0a7182b0 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-generator-parent - 1.16-SNAPSHOT + 1.16 pom @@ -15,7 +15,7 @@ scm:git:git@github.com:avaje/avaje-http.git - HEAD + avaje-http-generator-parent-1.16 From 9ffa51530eb89a2ab9025b5a5527f099a591d55e Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Thu, 19 May 2022 20:28:10 +1200 Subject: [PATCH 0283/1323] [maven-release-plugin] prepare for next development iteration --- http-api/pom.xml | 4 ++-- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 4 ++-- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- pom.xml | 4 ++-- 7 files changed, 10 insertions(+), 10 deletions(-) diff --git a/http-api/pom.xml b/http-api/pom.xml index 0d8aebf61..9d4269d06 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-generator-parent - 1.16 + 1.17-SNAPSHOT .. @@ -20,7 +20,7 @@ scm:git:git@github.com:avaje/avaje-http.git - avaje-http-generator-parent-1.16 + HEAD diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index 7b61a0932..46ef67f8f 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -5,7 +5,7 @@ io.avaje avaje-http-generator-parent - 1.16 + 1.17-SNAPSHOT .. diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 88df221f4..96931d7a4 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-generator-parent - 1.16 + 1.17-SNAPSHOT .. @@ -33,7 +33,7 @@ io.avaje avaje-http-api - 1.16 + 1.17-SNAPSHOT diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index 52d80fcb4..335fdf68c 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-generator-parent - 1.16 + 1.17-SNAPSHOT .. diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index 922d2f5e5..e01018f77 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-generator-parent - 1.16 + 1.17-SNAPSHOT .. diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index c2f1acbf1..2522bf29e 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-generator-parent - 1.16 + 1.17-SNAPSHOT .. diff --git a/pom.xml b/pom.xml index e0a7182b0..46196ede0 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-generator-parent - 1.16 + 1.17-SNAPSHOT pom @@ -15,7 +15,7 @@ scm:git:git@github.com:avaje/avaje-http.git - avaje-http-generator-parent-1.16 + HEAD From f22ccca97b55d641146f3e979abef58fbae3108c Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Thu, 19 May 2022 20:38:01 +1200 Subject: [PATCH 0284/1323] Bump to 1.17-SNAPSHOT after release --- tests/test-client/pom.xml | 6 +- tests/test-helidon/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-spark/pom.xml | 127 ------------------ .../src/main/java/org/example/web/App.java | 22 --- .../src/main/java/org/example/web/Hello.java | 7 - .../java/org/example/web/HelloController.java | 25 ---- .../java/org/example/web/JsonTransformer.java | 14 -- .../test-spark/src/main/resources/logback.xml | 19 --- .../src/main/resources/public/openapi.json | 74 ---------- .../src/test/resources/logback-test.xml | 19 --- 12 files changed, 6 insertions(+), 313 deletions(-) delete mode 100644 tests/test-spark/pom.xml delete mode 100644 tests/test-spark/src/main/java/org/example/web/App.java delete mode 100644 tests/test-spark/src/main/java/org/example/web/Hello.java delete mode 100644 tests/test-spark/src/main/java/org/example/web/HelloController.java delete mode 100644 tests/test-spark/src/main/java/org/example/web/JsonTransformer.java delete mode 100644 tests/test-spark/src/main/resources/logback.xml delete mode 100644 tests/test-spark/src/main/resources/public/openapi.json delete mode 100644 tests/test-spark/src/test/resources/logback-test.xml diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index f0d9cd165..ad0aa0f3b 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -36,7 +36,7 @@ io.avaje avaje-http-api - 1.16-SNAPSHOT + 1.17-SNAPSHOT @@ -108,12 +108,12 @@ io.avaje avaje-http-client-generator - 1.16-SNAPSHOT + 1.17-SNAPSHOT io.avaje avaje-http-jex-generator - 1.16-SNAPSHOT + 1.17-SNAPSHOT io.avaje diff --git a/tests/test-helidon/pom.xml b/tests/test-helidon/pom.xml index b5e215575..b315fb397 100644 --- a/tests/test-helidon/pom.xml +++ b/tests/test-helidon/pom.xml @@ -17,7 +17,7 @@ true org.example.Main 2.3.0 - 1.16-SNAPSHOT + 1.17-SNAPSHOT diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index d4ed6d6bb..c1b2ba2fe 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -20,7 +20,7 @@ 2.0.8 1.3.71 2.12.6.1 - 1.16-SNAPSHOT + 1.17-SNAPSHOT diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index ae3d7e94b..53f4ec729 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -20,7 +20,7 @@ 2.0.8 2.12.6.1 8.3 - 1.16-SNAPSHOT + 1.17-SNAPSHOT diff --git a/tests/test-spark/pom.xml b/tests/test-spark/pom.xml deleted file mode 100644 index 6e070249d..000000000 --- a/tests/test-spark/pom.xml +++ /dev/null @@ -1,127 +0,0 @@ - - - 4.0.0 - - org.example - test-spark - 1 - - - org.avaje - java11-oss - 3.2 - - - - org.example.myapp.Main - 2.0.8 - 1.16-SNAPSHOT - - - - - - org.avaje - logback - 1.0 - - - - com.sparkjava - spark-core - 2.9.2 - - - - com.fasterxml.jackson.core - jackson-databind - 2.12.6.1 - - - - io.avaje - avaje-inject - 6.12 - - - - io.avaje - avaje-http-api - ${avaje-http-version} - - - - io.avaje - avaje-http-hibernate-validator - 2.8 - - - - io.swagger.core.v3 - swagger-annotations - ${swagger.version} - - - - - - io.avaje - avaje-inject-generator - 6.12 - provided - - - - io.avaje - avaje-http-spark-generator - 1.16-SNAPSHOT - provided - - - - - - io.avaje - junit - 1.1 - test - - - - - io.avaje - avaje-http-client - 1.16 - test - - - - - - app - - - - io.dinject - openapi-maven-plugin - 1.2 - - - - - - main - process-classes - - openapi - - - - - - - - - diff --git a/tests/test-spark/src/main/java/org/example/web/App.java b/tests/test-spark/src/main/java/org/example/web/App.java deleted file mode 100644 index ed0c8a9ba..000000000 --- a/tests/test-spark/src/main/java/org/example/web/App.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.example.web; - -import io.avaje.http.api.WebRoutes; -import spark.Spark; - -public class App { - - public static void main(String[] args) { - - JsonTransformer jsonTransformer = new JsonTransformer(); - - Spark.port(8082); - Spark.defaultResponseTransformer(jsonTransformer); - Spark.get("/", (request, response) -> { - response.status(200); - return "hello"; - }); - - ApplicationScope.list(WebRoutes.class) - .forEach(WebRoutes::registerRoutes); - } -} diff --git a/tests/test-spark/src/main/java/org/example/web/Hello.java b/tests/test-spark/src/main/java/org/example/web/Hello.java deleted file mode 100644 index 3c3a25ff3..000000000 --- a/tests/test-spark/src/main/java/org/example/web/Hello.java +++ /dev/null @@ -1,7 +0,0 @@ -package org.example.web; - -public class Hello { - - public long id; - public String name; -} diff --git a/tests/test-spark/src/main/java/org/example/web/HelloController.java b/tests/test-spark/src/main/java/org/example/web/HelloController.java deleted file mode 100644 index c60c8b689..000000000 --- a/tests/test-spark/src/main/java/org/example/web/HelloController.java +++ /dev/null @@ -1,25 +0,0 @@ -package org.example.web; - -import io.avaje.http.api.Controller; -import io.avaje.http.api.Get; -import io.avaje.http.api.Path; -import io.avaje.http.api.Produces; - -@Controller -@Path("hello") -public class HelloController { - - @Produces("text/plain") - @Get - String helloThere2() { - return "helloThere"; - } - - @Get("{id}") - Hello getById(long id) { - Hello hello =new Hello(); - hello.id = id; - hello.name = "foo"; - return hello; - } -} diff --git a/tests/test-spark/src/main/java/org/example/web/JsonTransformer.java b/tests/test-spark/src/main/java/org/example/web/JsonTransformer.java deleted file mode 100644 index fe82f1f18..000000000 --- a/tests/test-spark/src/main/java/org/example/web/JsonTransformer.java +++ /dev/null @@ -1,14 +0,0 @@ -package org.example.web; - -import com.fasterxml.jackson.databind.ObjectMapper; -import spark.ResponseTransformer; - -public class JsonTransformer implements ResponseTransformer { - - private final ObjectMapper objectMapper = new ObjectMapper(); - - @Override - public String render(Object model) throws Exception { - return objectMapper.writeValueAsString(model); - } -} diff --git a/tests/test-spark/src/main/resources/logback.xml b/tests/test-spark/src/main/resources/logback.xml deleted file mode 100644 index e0ad5c82d..000000000 --- a/tests/test-spark/src/main/resources/logback.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - TRACE - - - %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n - - - - - - - - - - - - diff --git a/tests/test-spark/src/main/resources/public/openapi.json b/tests/test-spark/src/main/resources/public/openapi.json deleted file mode 100644 index 4896cf3bf..000000000 --- a/tests/test-spark/src/main/resources/public/openapi.json +++ /dev/null @@ -1,74 +0,0 @@ -{ - "openapi" : "3.0.1", - "info" : { - "title" : "", - "version" : "" - }, - "paths" : { - "/hello" : { - "get" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "responses" : { - "200" : { - "description" : "", - "content" : { - "text/plain" : { - "schema" : { - "type" : "string" - } - } - } - } - } - } - }, - "/hello/{id}" : { - "get" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "parameters" : [ { - "name" : "id", - "in" : "path", - "required" : true, - "schema" : { - "type" : "integer", - "format" : "int64", - "nullable" : false - } - } ], - "responses" : { - "200" : { - "description" : "", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/Hello" - } - } - } - } - } - } - } - }, - "components" : { - "schemas" : { - "Hello" : { - "type" : "object", - "properties" : { - "id" : { - "type" : "integer", - "format" : "int64", - "nullable" : false - }, - "name" : { - "type" : "string" - } - } - } - } - } -} \ No newline at end of file diff --git a/tests/test-spark/src/test/resources/logback-test.xml b/tests/test-spark/src/test/resources/logback-test.xml deleted file mode 100644 index 2dcd0186d..000000000 --- a/tests/test-spark/src/test/resources/logback-test.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - TRACE - - - %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n - - - - - - - - - - - - From 264d5c925b91e4d6ad827284d7e04bd435cc180f Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Fri, 20 May 2022 15:34:56 +1200 Subject: [PATCH 0285/1323] Bump test Javalin dependency to 4.6.0 --- tests/test-javalin/pom.xml | 2 +- .../src/test/java/org/example/myapp/BaseWebTest.java | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index c1b2ba2fe..7a1c210c8 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -16,7 +16,7 @@ true org.example.myapp.Main - 4.1.1 + 4.6.0 2.0.8 1.3.71 2.12.6.1 diff --git a/tests/test-javalin/src/test/java/org/example/myapp/BaseWebTest.java b/tests/test-javalin/src/test/java/org/example/myapp/BaseWebTest.java index a8539cc26..872f82e48 100644 --- a/tests/test-javalin/src/test/java/org/example/myapp/BaseWebTest.java +++ b/tests/test-javalin/src/test/java/org/example/myapp/BaseWebTest.java @@ -1,9 +1,7 @@ package org.example.myapp; -import com.fasterxml.jackson.databind.ObjectMapper; import io.avaje.http.client.HttpClientContext; import io.avaje.http.client.JacksonBodyAdapter; -import io.avaje.http.client.RequestLogger; import io.javalin.Javalin; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; From de5cb036c2e155c7d2816c9256e0821a19640363 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Fri, 20 May 2022 15:43:20 +1200 Subject: [PATCH 0286/1323] Turn off loom use in tests --- tests/test-javalin/src/main/java/org/example/myapp/Main.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/test-javalin/src/main/java/org/example/myapp/Main.java b/tests/test-javalin/src/main/java/org/example/myapp/Main.java index cc4b92b1a..8506ca0dd 100644 --- a/tests/test-javalin/src/main/java/org/example/myapp/Main.java +++ b/tests/test-javalin/src/main/java/org/example/myapp/Main.java @@ -4,6 +4,7 @@ import io.avaje.inject.BeanScope; import io.avaje.inject.InjectModule; import io.javalin.Javalin; +import io.javalin.core.LoomUtil; import io.javalin.http.staticfiles.Location; import io.swagger.v3.oas.annotations.OpenAPIDefinition; import io.swagger.v3.oas.annotations.info.Info; @@ -26,6 +27,7 @@ public static void main(String[] args) { public static Javalin start(int port) { + LoomUtil.useLoomThreadPool = false; Javalin app = Javalin.create(config -> { config.showJavalinBanner = false; config.addStaticFiles("public", Location.CLASSPATH); From 771cfb8ba78e6ed28d19d7ddf5cf98016e8694f2 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Mon, 23 May 2022 22:35:58 +1200 Subject: [PATCH 0287/1323] Update dependencies --- http-client/client/pom.xml | 11 ++++++----- http-client/gson-adapter/pom.xml | 1 + http-client/test/pom.xml | 4 ++-- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/http-client/client/pom.xml b/http-client/client/pom.xml index 27540a8f9..be08c6343 100644 --- a/http-client/client/pom.xml +++ b/http-client/client/pom.xml @@ -5,6 +5,7 @@ org.avaje java11-oss 3.8 + io.avaje @@ -21,7 +22,7 @@ com.fasterxml.jackson.core jackson-databind - 2.13.1 + 2.13.3 true @@ -58,21 +59,21 @@ io.avaje avaje-inject - 6.12 + 8.3 test io.avaje avaje-http-api - 1.12 + 1.16 test io.avaje avaje-http-hibernate-validator - 2.6 + 2.8 test @@ -88,7 +89,7 @@ io.avaje avaje-inject-generator - 6.12 + 8.3 test diff --git a/http-client/gson-adapter/pom.xml b/http-client/gson-adapter/pom.xml index a6c7631c1..004af2229 100644 --- a/http-client/gson-adapter/pom.xml +++ b/http-client/gson-adapter/pom.xml @@ -5,6 +5,7 @@ org.avaje java11-oss 3.8 + io.avaje diff --git a/http-client/test/pom.xml b/http-client/test/pom.xml index 58bd4e8cc..88c7f13a0 100644 --- a/http-client/test/pom.xml +++ b/http-client/test/pom.xml @@ -28,13 +28,13 @@ io.avaje avaje-http-api - 1.12 + 1.16 com.fasterxml.jackson.core jackson-databind - 2.13.2.2 + 2.13.3 From cfabe869f423c78eaa49edf359edba8fe2d197d1 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Mon, 23 May 2022 22:37:43 +1200 Subject: [PATCH 0288/1323] #49 - When no bodyAdapter is set, use a reasonable default if avaje-jsonb or jackson is detected --- .../client/DHttpClientContextBuilder.java | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContextBuilder.java b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContextBuilder.java index f63691bb2..9db3bb021 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContextBuilder.java +++ b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContextBuilder.java @@ -159,6 +159,9 @@ public HttpClientContext build() { // register the builtin request/response logging requestListener(new RequestLogger()); } + if (bodyAdapter == null) { + bodyAdapter = defaultBodyAdapter(); + } return new DHttpClientContext(client, baseUrl, requestTimeout, bodyAdapter, retryHandler, buildListener(), authTokenProvider, buildIntercept()); } @@ -213,4 +216,35 @@ private HttpClient defaultClient() { return builder.build(); } + /** + * Create a reasonable default BodyAdapter if avaje-jsonb or Jackson are present. + */ + BodyAdapter defaultBodyAdapter() { + try { + return detectJsonb() ? new JsonbBodyAdapter() + : detectJackson() ? new JacksonBodyAdapter() + : null; + } catch (IllegalAccessError e) { + // not in module path + return null; + } + } + + boolean detectJsonb() { + return detectTypeExists("io.avaje.jsonb.Jsonb"); + } + + boolean detectJackson() { + return detectTypeExists("com.fasterxml.jackson.databind.ObjectMapper"); + } + + private boolean detectTypeExists(String className) { + try { + Class.forName(className); + return true; + } catch (ClassNotFoundException e) { + return false; + } + } + } From cae79c9ade7258037173997f539ac14d6d2be53c Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Mon, 23 May 2022 22:38:43 +1200 Subject: [PATCH 0289/1323] [maven-release-plugin] prepare release avaje-http-client-1.17 --- http-client/client/pom.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/http-client/client/pom.xml b/http-client/client/pom.xml index be08c6343..9b81a5718 100644 --- a/http-client/client/pom.xml +++ b/http-client/client/pom.xml @@ -5,16 +5,16 @@ org.avaje java11-oss 3.8 - + io.avaje avaje-http-client - 1.17-SNAPSHOT + 1.17 scm:git:git@github.com:avaje/avaje-http-client.git - HEAD + avaje-http-client-1.17 From 96417e52430ef9542502de84292525bd519089fb Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Mon, 23 May 2022 22:38:48 +1200 Subject: [PATCH 0290/1323] [maven-release-plugin] prepare for next development iteration --- http-client/client/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/http-client/client/pom.xml b/http-client/client/pom.xml index 9b81a5718..596b4dd91 100644 --- a/http-client/client/pom.xml +++ b/http-client/client/pom.xml @@ -10,11 +10,11 @@ io.avaje avaje-http-client - 1.17 + 1.18-SNAPSHOT scm:git:git@github.com:avaje/avaje-http-client.git - avaje-http-client-1.17 + HEAD From 1e65b5bd5cdf287272ad7ed59081692b783ebbc4 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Mon, 23 May 2022 22:42:04 +1200 Subject: [PATCH 0291/1323] Bump to 1.18-SNAPSHOT after release --- http-client/gson-adapter/pom.xml | 4 ++-- http-client/test/pom.xml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/http-client/gson-adapter/pom.xml b/http-client/gson-adapter/pom.xml index 004af2229..0fc1ae757 100644 --- a/http-client/gson-adapter/pom.xml +++ b/http-client/gson-adapter/pom.xml @@ -10,7 +10,7 @@ io.avaje avaje-http-client-gson - 1.17-SNAPSHOT + 1.18-SNAPSHOT scm:git:git@github.com:avaje/avaje-http-client.git @@ -28,7 +28,7 @@ io.avaje avaje-http-client - 1.17-SNAPSHOT + 1.18-SNAPSHOT provided diff --git a/http-client/test/pom.xml b/http-client/test/pom.xml index 88c7f13a0..02a6d0f3a 100644 --- a/http-client/test/pom.xml +++ b/http-client/test/pom.xml @@ -16,13 +16,13 @@ io.avaje avaje-http-client - 1.17-SNAPSHOT + 1.18-SNAPSHOT io.avaje avaje-http-client-gson - 1.17-SNAPSHOT + 1.18-SNAPSHOT From 603b9c98e5bd08b0a5cb1911da0655bd60195325 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Mon, 23 May 2022 22:46:26 +1200 Subject: [PATCH 0292/1323] Update README --- http-client/README.md | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/http-client/README.md b/http-client/README.md index 6ea33ec81..1b4d6e44a 100644 --- a/http-client/README.md +++ b/http-client/README.md @@ -24,7 +24,7 @@ A lightweight wrapper to the [JDK 11+ Java Http Client](http://openjdk.java.net/ io.avaje avaje-http-client - 1.14 + 1.17 ``` @@ -83,6 +83,15 @@ HttpResponse hres = clientContext.request() .GET() .asString(); ``` + +#### Example GET as JSON marshalling into a java class/dto +```java +CustomerDto customer = clientContext.request() + .path("customers").path(42) + .GET() + .bean(CustomerDto.class); +``` + #### Example Async GET as String - All async requests use CompletableFuture<T> - throwable is a CompletionException From 6d75fd8cf066f7b92a964605d0c808f528321041 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Mon, 23 May 2022 22:47:59 +1200 Subject: [PATCH 0293/1323] #79 - Bump to Java 11 with module-info --- http-api/pom.xml | 8 -------- http-api/src/main/java/module-info.java | 5 +++++ http-generator-client/pom.xml | 4 ++-- .../src/main/java/module-info.java | 7 +++++++ http-generator-core/pom.xml | 6 +++--- .../src/main/java/module-info.java | 15 +++++++++++++++ http-generator-helidon/pom.xml | 4 ++-- http-generator-javalin/pom.xml | 4 ++-- .../src/main/java/module-info.java | 7 +++++++ http-generator-jex/pom.xml | 4 ++-- http-generator-jex/src/main/java/module-info.java | 7 +++++++ pom.xml | 11 +++++------ 12 files changed, 57 insertions(+), 25 deletions(-) create mode 100644 http-api/src/main/java/module-info.java create mode 100644 http-generator-client/src/main/java/module-info.java create mode 100644 http-generator-core/src/main/java/module-info.java create mode 100644 http-generator-javalin/src/main/java/module-info.java create mode 100644 http-generator-jex/src/main/java/module-info.java diff --git a/http-api/pom.xml b/http-api/pom.xml index 9d4269d06..fb4bc99e2 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -10,14 +10,6 @@ avaje-http-api - - - - - - - - scm:git:git@github.com:avaje/avaje-http.git HEAD diff --git a/http-api/src/main/java/module-info.java b/http-api/src/main/java/module-info.java new file mode 100644 index 000000000..deb09ce9e --- /dev/null +++ b/http-api/src/main/java/module-info.java @@ -0,0 +1,5 @@ +module io.avaje.http.api { + + exports io.avaje.http.api; + +} diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index 46ef67f8f..98dc3f8c2 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -32,8 +32,8 @@ maven-compiler-plugin 3.10.1 - 1.8 - 1.8 + 11 + 11 -proc:none diff --git a/http-generator-client/src/main/java/module-info.java b/http-generator-client/src/main/java/module-info.java new file mode 100644 index 000000000..857d62a9c --- /dev/null +++ b/http-generator-client/src/main/java/module-info.java @@ -0,0 +1,7 @@ +module io.avaje.http.client.generator { + + provides javax.annotation.processing.Processor with io.avaje.http.generator.client.ClientProcessor; + + requires transitive io.avaje.http.generator.core; + requires java.compiler; +} diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 96931d7a4..1dbdae931 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -13,7 +13,7 @@ 2.0.8 - 2.12.6.1 + 2.13.3 @@ -63,8 +63,8 @@ maven-compiler-plugin 3.10.1 - 1.8 - 1.8 + 11 + 11 -proc:none diff --git a/http-generator-core/src/main/java/module-info.java b/http-generator-core/src/main/java/module-info.java new file mode 100644 index 000000000..6c24c84c5 --- /dev/null +++ b/http-generator-core/src/main/java/module-info.java @@ -0,0 +1,15 @@ +module io.avaje.http.generator.core { + + exports io.avaje.http.generator.core; + exports io.avaje.http.generator.core.javadoc; + exports io.avaje.http.generator.core.openapi; + + requires java.sql; + requires java.compiler; + requires transitive io.avaje.http.api; + requires transitive io.swagger.v3.oas.models; + requires transitive io.swagger.v3.oas.annotations; + requires transitive com.fasterxml.jackson.core; + requires transitive com.fasterxml.jackson.databind; + requires transitive java.validation; +} diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index 335fdf68c..fe5f51f8a 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -29,8 +29,8 @@ maven-compiler-plugin 3.10.1 - 1.8 - 1.8 + 11 + 11 -proc:none diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index e01018f77..ab8825690 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -29,8 +29,8 @@ maven-compiler-plugin 3.10.1 - 1.8 - 1.8 + 11 + 11 -proc:none diff --git a/http-generator-javalin/src/main/java/module-info.java b/http-generator-javalin/src/main/java/module-info.java new file mode 100644 index 000000000..86ac9f204 --- /dev/null +++ b/http-generator-javalin/src/main/java/module-info.java @@ -0,0 +1,7 @@ +module io.avaje.http.javalin.generator { + + provides javax.annotation.processing.Processor with io.avaje.http.generator.javalin.JavalinProcessor; + + requires transitive io.avaje.http.generator.core; + requires java.compiler; +} diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index 2522bf29e..ec18f464c 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -29,8 +29,8 @@ maven-compiler-plugin 3.10.1 - 1.8 - 1.8 + 11 + 11 -proc:none diff --git a/http-generator-jex/src/main/java/module-info.java b/http-generator-jex/src/main/java/module-info.java new file mode 100644 index 000000000..6f00d4094 --- /dev/null +++ b/http-generator-jex/src/main/java/module-info.java @@ -0,0 +1,7 @@ +module io.avaje.http.jex.generator { + + provides javax.annotation.processing.Processor with io.avaje.http.generator.jex.JexProcessor; + + requires transitive io.avaje.http.generator.core; + requires java.compiler; +} diff --git a/pom.xml b/pom.xml index 46196ede0..53f5510a5 100644 --- a/pom.xml +++ b/pom.xml @@ -1,18 +1,17 @@ 4.0.0 + + org.avaje + java11-oss + 3.8 + io.avaje avaje-http-generator-parent 1.17-SNAPSHOT pom - - org.avaje - java8-oss - 3.8 - - scm:git:git@github.com:avaje/avaje-http.git HEAD From 165a072c45b65de6b5e7671e54c9ff4609322754 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 24 May 2022 09:19:42 +1200 Subject: [PATCH 0294/1323] #79 - Bump to Java 11 with module-info Add requires transitive com.fasterxml.jackson.annotation; --- http-generator-core/src/main/java/module-info.java | 1 + 1 file changed, 1 insertion(+) diff --git a/http-generator-core/src/main/java/module-info.java b/http-generator-core/src/main/java/module-info.java index 6c24c84c5..bb321ee51 100644 --- a/http-generator-core/src/main/java/module-info.java +++ b/http-generator-core/src/main/java/module-info.java @@ -11,5 +11,6 @@ requires transitive io.swagger.v3.oas.annotations; requires transitive com.fasterxml.jackson.core; requires transitive com.fasterxml.jackson.databind; + requires transitive com.fasterxml.jackson.annotation; requires transitive java.validation; } From 30eaa3a70093ef98f562212632d3c7be897fad57 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 24 May 2022 13:59:20 +1200 Subject: [PATCH 0295/1323] [maven-release-plugin] prepare release avaje-http-generator-parent-1.17 --- http-api/pom.xml | 4 ++-- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 4 ++-- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- pom.xml | 4 ++-- 7 files changed, 10 insertions(+), 10 deletions(-) diff --git a/http-api/pom.xml b/http-api/pom.xml index fb4bc99e2..e2972cc88 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-generator-parent - 1.17-SNAPSHOT + 1.17 .. @@ -12,7 +12,7 @@ scm:git:git@github.com:avaje/avaje-http.git - HEAD + avaje-http-generator-parent-1.17 diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index 98dc3f8c2..0c93515f0 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -5,7 +5,7 @@ io.avaje avaje-http-generator-parent - 1.17-SNAPSHOT + 1.17 .. diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 1dbdae931..2b89fdf05 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-generator-parent - 1.17-SNAPSHOT + 1.17 .. @@ -33,7 +33,7 @@ io.avaje avaje-http-api - 1.17-SNAPSHOT + 1.17 diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index fe5f51f8a..8b6bf9586 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-generator-parent - 1.17-SNAPSHOT + 1.17 .. diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index ab8825690..421b8b77a 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-generator-parent - 1.17-SNAPSHOT + 1.17 .. diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index ec18f464c..712b0b7e4 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-generator-parent - 1.17-SNAPSHOT + 1.17 .. diff --git a/pom.xml b/pom.xml index 53f5510a5..9f08ae6de 100644 --- a/pom.xml +++ b/pom.xml @@ -9,12 +9,12 @@ io.avaje avaje-http-generator-parent - 1.17-SNAPSHOT + 1.17 pom scm:git:git@github.com:avaje/avaje-http.git - HEAD + avaje-http-generator-parent-1.17 From 939d25d01f34b80993e62da83d03b12d87a32ec5 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 24 May 2022 13:59:26 +1200 Subject: [PATCH 0296/1323] [maven-release-plugin] prepare for next development iteration --- http-api/pom.xml | 4 ++-- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 4 ++-- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- pom.xml | 4 ++-- 7 files changed, 10 insertions(+), 10 deletions(-) diff --git a/http-api/pom.xml b/http-api/pom.xml index e2972cc88..9f3b81200 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-generator-parent - 1.17 + 1.18-SNAPSHOT .. @@ -12,7 +12,7 @@ scm:git:git@github.com:avaje/avaje-http.git - avaje-http-generator-parent-1.17 + HEAD diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index 0c93515f0..fa66a73c1 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -5,7 +5,7 @@ io.avaje avaje-http-generator-parent - 1.17 + 1.18-SNAPSHOT .. diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 2b89fdf05..a6582edfa 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-generator-parent - 1.17 + 1.18-SNAPSHOT .. @@ -33,7 +33,7 @@ io.avaje avaje-http-api - 1.17 + 1.18-SNAPSHOT diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index 8b6bf9586..13e04c778 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-generator-parent - 1.17 + 1.18-SNAPSHOT .. diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index 421b8b77a..11bc5387c 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-generator-parent - 1.17 + 1.18-SNAPSHOT .. diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index 712b0b7e4..4f86e778b 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-generator-parent - 1.17 + 1.18-SNAPSHOT .. diff --git a/pom.xml b/pom.xml index 9f08ae6de..fa88a2a79 100644 --- a/pom.xml +++ b/pom.xml @@ -9,12 +9,12 @@ io.avaje avaje-http-generator-parent - 1.17 + 1.18-SNAPSHOT pom scm:git:git@github.com:avaje/avaje-http.git - avaje-http-generator-parent-1.17 + HEAD From 6fad506449af9e112a205d37fc1c05af39df6dc9 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 24 May 2022 14:14:12 +1200 Subject: [PATCH 0297/1323] Bump tests to 1.18-SNAPSHOT after release --- tests/test-client/pom.xml | 6 +++--- tests/test-helidon/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index ad0aa0f3b..0a77cce20 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -36,7 +36,7 @@ io.avaje avaje-http-api - 1.17-SNAPSHOT + 1.18-SNAPSHOT @@ -108,12 +108,12 @@ io.avaje avaje-http-client-generator - 1.17-SNAPSHOT + 1.18-SNAPSHOT io.avaje avaje-http-jex-generator - 1.17-SNAPSHOT + 1.18-SNAPSHOT io.avaje diff --git a/tests/test-helidon/pom.xml b/tests/test-helidon/pom.xml index b315fb397..4024d9203 100644 --- a/tests/test-helidon/pom.xml +++ b/tests/test-helidon/pom.xml @@ -17,7 +17,7 @@ true org.example.Main 2.3.0 - 1.17-SNAPSHOT + 1.18-SNAPSHOT diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 7a1c210c8..33791f54a 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -20,7 +20,7 @@ 2.0.8 1.3.71 2.12.6.1 - 1.17-SNAPSHOT + 1.18-SNAPSHOT diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 53f4ec729..1b3ad8cc0 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -20,7 +20,7 @@ 2.0.8 2.12.6.1 8.3 - 1.17-SNAPSHOT + 1.18-SNAPSHOT From 9c63b3a1fa459de9a742c8e28a5bc9a28e82e30e Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Thu, 2 Jun 2022 14:14:43 +1200 Subject: [PATCH 0298/1323] #81 - Add the missing `toFloat()` `toDouble()` type conversion methods These are used for query parameters allowing null/empty values (as opposed to `asFloat()` which does not allow nulls). --- .../io/avaje/http/api/PathTypeConversion.java | 27 +++++++++++++++++++ .../http/api/PathTypeConversionTest.java | 22 +++++++++++++++ 2 files changed, 49 insertions(+) diff --git a/http-api/src/main/java/io/avaje/http/api/PathTypeConversion.java b/http-api/src/main/java/io/avaje/http/api/PathTypeConversion.java index f05fc568d..33943a13a 100644 --- a/http-api/src/main/java/io/avaje/http/api/PathTypeConversion.java +++ b/http-api/src/main/java/io/avaje/http/api/PathTypeConversion.java @@ -228,6 +228,33 @@ public static Long toLong(String value) { } } + /** + * Convert to Double (allowing nulls). + */ + public static Double toDouble(String value) { + if (isNullOrEmpty(value)) { + return null; + } + try { + return Double.valueOf(value); + } catch (NumberFormatException e) { + throw new InvalidTypeArgumentException(e); + } + } + /** + * Convert to Float (allowing nulls). + */ + public static Float toFloat(String value) { + if (isNullOrEmpty(value)) { + return null; + } + try { + return Float.valueOf(value); + } catch (NumberFormatException e) { + throw new InvalidTypeArgumentException(e); + } + } + /** * Convert to BigDecimal (allowing nulls). */ diff --git a/http-api/src/test/java/io/avaje/http/api/PathTypeConversionTest.java b/http-api/src/test/java/io/avaje/http/api/PathTypeConversionTest.java index a4b0b6cf1..ba11c8e1e 100644 --- a/http-api/src/test/java/io/avaje/http/api/PathTypeConversionTest.java +++ b/http-api/src/test/java/io/avaje/http/api/PathTypeConversionTest.java @@ -252,6 +252,28 @@ void toLong_invalid() { assertThrows(InvalidTypeArgumentException.class, () -> PathTypeConversion.toLong("junk")); } + @Test + void toDouble() { + assertThat(PathTypeConversion.toDouble("42")).isEqualTo(42D); + assertThat(PathTypeConversion.toDouble(null)).isNull(); + } + + @Test + void toDouble_invalid() { + assertThrows(InvalidTypeArgumentException.class, () -> PathTypeConversion.toDouble("junk")); + } + + @Test + void toFloat() { + assertThat(PathTypeConversion.toFloat("42")).isEqualTo(42F); + assertThat(PathTypeConversion.toFloat(null)).isNull(); + } + + @Test + void toFloat_invalid() { + assertThrows(InvalidTypeArgumentException.class, () -> PathTypeConversion.toFloat("junk")); + } + @Test void toBigDecimal() { assertThat(PathTypeConversion.toBigDecimal("42.45")).isEqualByComparingTo("42.45"); From bdff6eff8dfd516809cfc352c3057edb9920bc12 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Thu, 2 Jun 2022 14:30:15 +1200 Subject: [PATCH 0299/1323] #81 - Fix Double query param should be `toDouble()` but is bodyAsClass() --- .../io/avaje/http/generator/core/TypeMap.java | 24 ++++++++ .../http/generator/core/TypeMapTest.java | 56 +++++++++++++++++++ .../org/example/myapp/web/BazController.java | 5 ++ 3 files changed, 85 insertions(+) create mode 100644 http-generator-core/src/test/java/io/avaje/http/generator/core/TypeMapTest.java diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/TypeMap.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/TypeMap.java index ed7771f17..686d590e7 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/TypeMap.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/TypeMap.java @@ -19,12 +19,14 @@ private static void add(TypeHandler h) { static { types.put("int", new IntHandler()); types.put("long", new PLongHandler()); + types.put("double", new PDoubleHandler()); types.put("float", new PFloatHandler()); types.put("boolean", new BoolHandler()); types.put("java.lang.String", new StringHandler()); types.put("java.lang.Integer", new IntegerHandler()); types.put("java.lang.Long", new LongHandler()); + types.put("java.lang.Double", new DoubleHandler()); types.put("java.lang.Float", new FloatHandler()); types.put("java.lang.Boolean", new BooleanHandler()); @@ -123,6 +125,28 @@ static class PFloatHandler extends Primitive { } } + static class DoubleHandler extends JavaLangType { + DoubleHandler() { + super("Double"); + } + + @Override + public String asMethod() { + return "asDouble("; + } + + @Override + public String toMethod() { + return "toDouble("; + } + } + + static class PDoubleHandler extends Primitive { + PDoubleHandler() { + super("Double"); + } + } + static class BooleanHandler extends JavaLangType { BooleanHandler() { super("Boolean"); diff --git a/http-generator-core/src/test/java/io/avaje/http/generator/core/TypeMapTest.java b/http-generator-core/src/test/java/io/avaje/http/generator/core/TypeMapTest.java new file mode 100644 index 000000000..5f4b9ac7c --- /dev/null +++ b/http-generator-core/src/test/java/io/avaje/http/generator/core/TypeMapTest.java @@ -0,0 +1,56 @@ +package io.avaje.http.generator.core; + +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.*; + +class TypeMapTest { + + @Test + void get_int() { + TypeHandler handler = TypeMap.get("int"); + assertThat(handler.asMethod()).isEqualTo("asInt("); + assertTrue(handler.isPrimitive()); + } + + @Test + void get_Integer() { + TypeHandler handler = TypeMap.get("java.lang.Integer"); + assertThat(handler).isInstanceOf(TypeMap.IntegerHandler.class); + assertThat(handler.asMethod()).isEqualTo("asInteger("); + assertFalse(handler.isPrimitive()); + } + + @Test + void get_double() { + TypeHandler handler = TypeMap.get("double"); + assertThat(handler).isInstanceOf(TypeMap.PDoubleHandler.class); + assertThat(handler.asMethod()).isEqualTo("asDouble("); + assertTrue(handler.isPrimitive()); + } + + @Test + void get_Double() { + TypeHandler handler = TypeMap.get("java.lang.Double"); + assertThat(handler).isInstanceOf(TypeMap.DoubleHandler.class); + assertThat(handler.asMethod()).isEqualTo("asDouble("); + assertFalse(handler.isPrimitive()); + } + + @Test + void get_float() { + TypeHandler handler = TypeMap.get("float"); + assertThat(handler).isInstanceOf(TypeMap.PFloatHandler.class); + assertThat(handler.asMethod()).isEqualTo("asFloat("); + assertTrue(handler.isPrimitive()); + } + + @Test + void get_Float() { + TypeHandler handler = TypeMap.get("java.lang.Float"); + assertThat(handler).isInstanceOf(TypeMap.FloatHandler.class); + assertThat(handler.asMethod()).isEqualTo("asFloat("); + assertFalse(handler.isPrimitive()); + } +} diff --git a/tests/test-javalin/src/main/java/org/example/myapp/web/BazController.java b/tests/test-javalin/src/main/java/org/example/myapp/web/BazController.java index 2275d3fd4..96923c60f 100644 --- a/tests/test-javalin/src/main/java/org/example/myapp/web/BazController.java +++ b/tests/test-javalin/src/main/java/org/example/myapp/web/BazController.java @@ -35,4 +35,9 @@ List searchByName(String name) { return Arrays.asList(b1, b2); } + + @Get("checkparams/{id}") + String checkParams(int id, String p1, Double p2, Integer p3, Float p4, String body) { + return "dummy-response"; + } } From 864d9c1cb8b3418959c92ea308ae72ea2cfc3258 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Thu, 9 Jun 2022 17:42:03 +1200 Subject: [PATCH 0300/1323] #50 - Fix debug logging messages for retry and providers --- .../client/src/main/java/io/avaje/http/client/DHttpApi.java | 2 +- .../src/main/java/io/avaje/http/client/SimpleRetryHandler.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/http-client/client/src/main/java/io/avaje/http/client/DHttpApi.java b/http-client/client/src/main/java/io/avaje/http/client/DHttpApi.java index 86ba99eae..783563e54 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/DHttpApi.java +++ b/http-client/client/src/main/java/io/avaje/http/client/DHttpApi.java @@ -26,7 +26,7 @@ void init() { for (HttpApiProvider apiProvider : ServiceLoader.load(HttpApiProvider.class)) { addProvider(apiProvider); } - log.log(DEBUG, "providers for %s", providerMap.keySet()); + log.log(DEBUG, "providers for {0}", providerMap.keySet()); } void addProvider(HttpApiProvider apiProvider) { diff --git a/http-client/client/src/main/java/io/avaje/http/client/SimpleRetryHandler.java b/http-client/client/src/main/java/io/avaje/http/client/SimpleRetryHandler.java index 6ec75aa8d..0eb6821c5 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/SimpleRetryHandler.java +++ b/http-client/client/src/main/java/io/avaje/http/client/SimpleRetryHandler.java @@ -46,7 +46,7 @@ public boolean isRetry(int retryCount, HttpResponse response) { return false; } if (log.isLoggable(Level.DEBUG)) { - log.log(Level.DEBUG, "retry count:%s status:%s uri:%s", retryCount, response.statusCode(), response.uri()); + log.log(Level.DEBUG, "retry count:{0} status:{1} uri:{2}", retryCount, response.statusCode(), response.uri()); } try { int gitter = gitterMillis < 1 ? 0 : random.nextInt(gitterMillis); From d86dec3b680ee4e6c9f17f4516fec97153a1a374 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Thu, 9 Jun 2022 22:06:41 +1200 Subject: [PATCH 0301/1323] Inline loggingMaxBody --- .../src/main/java/io/avaje/http/client/DHttpClientContext.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContext.java b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContext.java index 638620aef..afa764f29 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContext.java +++ b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContext.java @@ -33,7 +33,6 @@ final class DHttpClientContext implements HttpClientContext { private final boolean withAuthToken; private final AuthTokenProvider authTokenProvider; private final AtomicReference tokenRef = new AtomicReference<>(); - private int loggingMaxBody = 1_000; private final LongAdder metricResTotal = new LongAdder(); private final LongAdder metricResError = new LongAdder(); @@ -316,6 +315,6 @@ private String authToken() { } String maxResponseBody(String body) { - return body.length() > loggingMaxBody ? body.substring(0, loggingMaxBody) + " ..." : body; + return body.length() > 1_000 ? body.substring(0, 1_000) + " ..." : body; } } From 2e7a0e4c0ec1f6915f5c1970ecc2e855009c40c6 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Thu, 9 Jun 2022 22:08:11 +1200 Subject: [PATCH 0302/1323] #51 - Add to HttpClientContext.Builder to expose state of builder (getters) and configureWith(BeanScope) --- http-client/client/pom.xml | 80 ++++++++++++------- .../client/DHttpClientContextBuilder.java | 70 +++++++++++++++- .../avaje/http/client/HttpClientContext.java | 48 +++++++++++ .../client/src/main/java/module-info.java | 1 + .../example/dinject/ConfigureWithDITest.java | 35 ++++++++ .../java/org/example/dinject/MyDIConfig.java | 15 ++++ 6 files changed, 217 insertions(+), 32 deletions(-) create mode 100644 http-client/client/src/test/java/org/example/dinject/ConfigureWithDITest.java create mode 100644 http-client/client/src/test/java/org/example/dinject/MyDIConfig.java diff --git a/http-client/client/pom.xml b/http-client/client/pom.xml index 596b4dd91..901501e62 100644 --- a/http-client/client/pom.xml +++ b/http-client/client/pom.xml @@ -17,6 +17,10 @@ HEAD + + false + + @@ -29,7 +33,14 @@ io.avaje avaje-jsonb - 0.15 + 1.0-RC1 + true + + + + io.avaje + avaje-inject + 8.6 true @@ -56,13 +67,6 @@ test - - io.avaje - avaje-inject - 8.3 - test - - io.avaje avaje-http-api @@ -85,18 +89,10 @@ - - - io.avaje - avaje-inject-generator - 8.3 - test - - - - + + @@ -104,21 +100,43 @@ + + org.apache.maven.plugins + maven-compiler-plugin + 3.10.1 + + + default-testCompile + + + + io.avaje + avaje-inject-generator + 8.6 + + + + + + + + maven-surefire-plugin - 3.0.0-M4 - - - --add-modules com.fasterxml.jackson.databind - --add-modules io.avaje.jsonb - --add-opens io.avaje.http.client/io.avaje.http.client=ALL-UNNAMED - --add-opens io.avaje.http.client/org.example.webserver=ALL-UNNAMED - --add-opens io.avaje.http.client/org.example.github=ALL-UNNAMED - --add-opens io.avaje.http.client/org.example.webserver=com.fasterxml.jackson.databind - --add-opens io.avaje.http.client/org.example.github=com.fasterxml.jackson.databind - --add-opens io.avaje.http.client/org.example.github=io.avaje.jsonb - - + 3.0.0-M6 + + + + + + + + + + + + + diff --git a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContextBuilder.java b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContextBuilder.java index 9db3bb021..75f068c18 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContextBuilder.java +++ b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContextBuilder.java @@ -1,5 +1,9 @@ package io.avaje.http.client; +import com.fasterxml.jackson.databind.ObjectMapper; +import io.avaje.inject.BeanScope; +import io.avaje.jsonb.Jsonb; + import javax.net.ssl.SSLContext; import javax.net.ssl.SSLParameters; import java.net.Authenticator; @@ -10,11 +14,12 @@ import java.time.Duration; import java.util.ArrayList; import java.util.List; +import java.util.Optional; import java.util.concurrent.Executor; import static java.util.Objects.requireNonNull; -final class DHttpClientContextBuilder implements HttpClientContext.Builder { +final class DHttpClientContextBuilder implements HttpClientContext.Builder.State { private HttpClient client; private String baseUrl; @@ -148,6 +153,39 @@ public HttpClientContext.Builder priority(int priority) { return this; } + @Override + public State state() { + return this; + } + + @Override + public HttpClientContext.Builder configureWith(BeanScope beanScope) { + if (bodyAdapter == null) { + configureBodyAdapter(beanScope); + } + if (retryHandler == null) { + configureRetryHandler(beanScope); + } + return this; + } + + private void configureRetryHandler(BeanScope beanScope) { + beanScope.getOptional(RetryHandler.class) + .ifPresent(this::retryHandler); + } + + private void configureBodyAdapter(BeanScope beanScope) { + Optional body = beanScope.getOptional(BodyAdapter.class); + if (body.isPresent()) { + bodyAdapter = body.get(); + } else if (beanScope.contains("io.avaje.jsonb.Jsonb")) { + bodyAdapter = new JsonbBodyAdapter(beanScope.get(Jsonb.class)); + } else if (beanScope.contains("com.fasterxml.jackson.databind.ObjectMapper")) { + ObjectMapper objectMapper = beanScope.get(ObjectMapper.class); + bodyAdapter = new JacksonBodyAdapter(objectMapper); + } + } + @Override public HttpClientContext build() { requireNonNull(baseUrl, "baseUrl is not specified"); @@ -165,6 +203,36 @@ public HttpClientContext build() { return new DHttpClientContext(client, baseUrl, requestTimeout, bodyAdapter, retryHandler, buildListener(), authTokenProvider, buildIntercept()); } + @Override + public String baseUrl() { + return baseUrl; + } + + @Override + public BodyAdapter bodyAdapter() { + return bodyAdapter; + } + + @Override + public HttpClient client() { + return client; + } + + @Override + public boolean requestLogging() { + return requestLogging; + } + + @Override + public Duration requestTimeout() { + return requestTimeout; + } + + @Override + public RetryHandler retryHandler() { + return retryHandler; + } + private RequestListener buildListener() { if (listeners.isEmpty()) { return null; diff --git a/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java b/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java index ed7e8e43e..3fc7b7394 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java +++ b/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java @@ -1,5 +1,7 @@ package io.avaje.http.client; +import io.avaje.inject.BeanScope; + import javax.net.ssl.SSLContext; import javax.net.ssl.SSLParameters; import java.net.Authenticator; @@ -311,6 +313,16 @@ interface Builder { */ Builder priority(int priority); + /** + * Configure BodyAdapter and RetryHandler using dependency injection BeanScope. + */ + Builder configureWith(BeanScope beanScope); + + /** + * Return the state of the builder. + */ + State state(); + /** * Build and return the context. * @@ -330,6 +342,42 @@ interface Builder { * }

*/ HttpClientContext build(); + + /** + * The state of the builder with methods to read the set state. + */ + interface State extends Builder { + + /** + * Return the base URL. + */ + String baseUrl(); + + /** + * Return the body adapter. + */ + BodyAdapter bodyAdapter(); + + /** + * Return the HttpClient. + */ + HttpClient client(); + + /** + * Return true if requestLogging is on. + */ + boolean requestLogging(); + + /** + * Return the request timeout. + */ + Duration requestTimeout(); + + /** + * Return the retry handler. + */ + RetryHandler retryHandler(); + } } /** diff --git a/http-client/client/src/main/java/module-info.java b/http-client/client/src/main/java/module-info.java index dbd155928..3f0117ac2 100644 --- a/http-client/client/src/main/java/module-info.java +++ b/http-client/client/src/main/java/module-info.java @@ -7,6 +7,7 @@ requires static com.fasterxml.jackson.annotation; requires static com.fasterxml.jackson.core; requires static io.avaje.jsonb; + requires static io.avaje.inject; exports io.avaje.http.client; } diff --git a/http-client/client/src/test/java/org/example/dinject/ConfigureWithDITest.java b/http-client/client/src/test/java/org/example/dinject/ConfigureWithDITest.java new file mode 100644 index 000000000..74f1496f2 --- /dev/null +++ b/http-client/client/src/test/java/org/example/dinject/ConfigureWithDITest.java @@ -0,0 +1,35 @@ +package org.example.dinject; + +import io.avaje.http.client.BodyAdapter; +import io.avaje.http.client.HttpClientContext; +import io.avaje.http.client.JsonbBodyAdapter; +import io.avaje.inject.BeanScope; +import org.junit.jupiter.api.Test; + +import java.time.Duration; + +import static org.assertj.core.api.Assertions.assertThat; + +class ConfigureWithDITest { + + @Test + void configureWith() { + try (BeanScope beanScope = BeanScope.builder().build()) { + + assertThat(beanScope.contains("io.avaje.jsonb.Jsonb")).isTrue(); + + HttpClientContext.Builder builder = HttpClientContext.builder(); + HttpClientContext.Builder.State state = builder.state(); + assertThat(state.baseUrl()).isNull(); + assertThat(state.bodyAdapter()).isNull(); + assertThat(state.client()).isNull(); + assertThat(state.requestLogging()).isTrue(); + assertThat(state.requestTimeout()).isEqualByComparingTo(Duration.ofSeconds(20)); + assertThat(state.retryHandler()).isNull(); + + builder.configureWith(beanScope); + BodyAdapter bodyAdapter = state.bodyAdapter(); + assertThat(bodyAdapter).isInstanceOf(JsonbBodyAdapter.class); + } + } +} diff --git a/http-client/client/src/test/java/org/example/dinject/MyDIConfig.java b/http-client/client/src/test/java/org/example/dinject/MyDIConfig.java new file mode 100644 index 000000000..35d27dc9c --- /dev/null +++ b/http-client/client/src/test/java/org/example/dinject/MyDIConfig.java @@ -0,0 +1,15 @@ +package org.example.dinject; + +import io.avaje.inject.Bean; +import io.avaje.inject.Factory; +import io.avaje.jsonb.Jsonb; + +@Factory +class MyDIConfig { + + @Bean + Jsonb jsonb() { + return Jsonb.builder().build(); + } + +} From 1ba5596016d4fdd7a96630db4697f91d9304856d Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Thu, 9 Jun 2022 22:13:13 +1200 Subject: [PATCH 0303/1323] [maven-release-plugin] prepare release avaje-http-client-1.18 --- http-client/client/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/http-client/client/pom.xml b/http-client/client/pom.xml index 901501e62..e79c82fe4 100644 --- a/http-client/client/pom.xml +++ b/http-client/client/pom.xml @@ -10,11 +10,11 @@ io.avaje avaje-http-client - 1.18-SNAPSHOT + 1.18 scm:git:git@github.com:avaje/avaje-http-client.git - HEAD + avaje-http-client-1.18 From a32e19f1e8fc64404054b0e161aec75eb238b29b Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Thu, 9 Jun 2022 22:13:19 +1200 Subject: [PATCH 0304/1323] [maven-release-plugin] prepare for next development iteration --- http-client/client/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/http-client/client/pom.xml b/http-client/client/pom.xml index e79c82fe4..a7471835f 100644 --- a/http-client/client/pom.xml +++ b/http-client/client/pom.xml @@ -10,11 +10,11 @@ io.avaje avaje-http-client - 1.18 + 1.19-SNAPSHOT scm:git:git@github.com:avaje/avaje-http-client.git - avaje-http-client-1.18 + HEAD From df3fffcf58c9e71a339bacce792baba668c5da23 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Thu, 9 Jun 2022 22:18:33 +1200 Subject: [PATCH 0305/1323] Bump to 19-SNAPSHOT after release --- http-client/gson-adapter/pom.xml | 4 ++-- http-client/test/pom.xml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/http-client/gson-adapter/pom.xml b/http-client/gson-adapter/pom.xml index 0fc1ae757..fe14a1a4f 100644 --- a/http-client/gson-adapter/pom.xml +++ b/http-client/gson-adapter/pom.xml @@ -10,7 +10,7 @@ io.avaje avaje-http-client-gson - 1.18-SNAPSHOT + 1.19-SNAPSHOT scm:git:git@github.com:avaje/avaje-http-client.git @@ -28,7 +28,7 @@ io.avaje avaje-http-client - 1.18-SNAPSHOT + 1.19-SNAPSHOT provided diff --git a/http-client/test/pom.xml b/http-client/test/pom.xml index 02a6d0f3a..2f4021012 100644 --- a/http-client/test/pom.xml +++ b/http-client/test/pom.xml @@ -16,13 +16,13 @@ io.avaje avaje-http-client - 1.18-SNAPSHOT + 1.19-SNAPSHOT io.avaje avaje-http-client-gson - 1.18-SNAPSHOT + 1.19-SNAPSHOT From cd7482400783b88069f5df3645f76afe33d44a56 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 26 Jul 2022 16:18:57 +1200 Subject: [PATCH 0306/1323] #52 - Change to use AppLog.getLogger() rather than directly using System.getLogger() --- http-client/client/pom.xml | 17 +++++++++++++++-- .../java/io/avaje/http/client/DHttpApi.java | 4 +++- .../io/avaje/http/client/RequestLogger.java | 4 +++- .../avaje/http/client/SimpleRetryHandler.java | 4 +++- .../client/src/main/java/module-info.java | 1 + 5 files changed, 25 insertions(+), 5 deletions(-) diff --git a/http-client/client/pom.xml b/http-client/client/pom.xml index a7471835f..bb36e54b3 100644 --- a/http-client/client/pom.xml +++ b/http-client/client/pom.xml @@ -23,6 +23,12 @@ + + io.avaje + avaje-applog + 1.0 + + com.fasterxml.jackson.core jackson-databind @@ -46,10 +52,17 @@ + + + + + + + io.avaje - avaje-slf4j-jpl - 1.1 + avaje-applog-slf4j + 1.0 test diff --git a/http-client/client/src/main/java/io/avaje/http/client/DHttpApi.java b/http-client/client/src/main/java/io/avaje/http/client/DHttpApi.java index 783563e54..643f48432 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/DHttpApi.java +++ b/http-client/client/src/main/java/io/avaje/http/client/DHttpApi.java @@ -1,5 +1,7 @@ package io.avaje.http.client; +import io.avaje.applog.AppLog; + import java.util.HashMap; import java.util.Map; import java.util.ServiceLoader; @@ -11,7 +13,7 @@ */ final class DHttpApi { - private static final System.Logger log = System.getLogger("io.avaje.http.client"); + private static final System.Logger log = AppLog.getLogger("io.avaje.http.client"); private static final DHttpApi INSTANCE = new DHttpApi(); diff --git a/http-client/client/src/main/java/io/avaje/http/client/RequestLogger.java b/http-client/client/src/main/java/io/avaje/http/client/RequestLogger.java index b673b2d36..391d04b60 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/RequestLogger.java +++ b/http-client/client/src/main/java/io/avaje/http/client/RequestLogger.java @@ -1,5 +1,7 @@ package io.avaje.http.client; +import io.avaje.applog.AppLog; + import java.lang.System.Logger.Level; import java.net.http.HttpHeaders; import java.net.http.HttpRequest; @@ -26,7 +28,7 @@ */ public class RequestLogger implements RequestListener { - private static final System.Logger log = System.getLogger("io.avaje.http.client.RequestLogger"); + private static final System.Logger log = AppLog.getLogger("io.avaje.http.client.RequestLogger"); private final String delimiter; diff --git a/http-client/client/src/main/java/io/avaje/http/client/SimpleRetryHandler.java b/http-client/client/src/main/java/io/avaje/http/client/SimpleRetryHandler.java index 0eb6821c5..a7575e3af 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/SimpleRetryHandler.java +++ b/http-client/client/src/main/java/io/avaje/http/client/SimpleRetryHandler.java @@ -1,5 +1,7 @@ package io.avaje.http.client; +import io.avaje.applog.AppLog; + import java.lang.System.Logger.Level; import java.net.http.HttpResponse; import java.util.Random; @@ -9,7 +11,7 @@ */ public class SimpleRetryHandler implements RetryHandler { - private static final System.Logger log = System.getLogger("io.avaje.http.client"); + private static final System.Logger log = AppLog.getLogger("io.avaje.http.client"); private final int maxRetries; private final long backoffMillis; diff --git a/http-client/client/src/main/java/module-info.java b/http-client/client/src/main/java/module-info.java index 3f0117ac2..56ad106f8 100644 --- a/http-client/client/src/main/java/module-info.java +++ b/http-client/client/src/main/java/module-info.java @@ -3,6 +3,7 @@ uses io.avaje.http.client.HttpApiProvider; requires transitive java.net.http; + requires transitive io.avaje.applog; requires static com.fasterxml.jackson.databind; requires static com.fasterxml.jackson.annotation; requires static com.fasterxml.jackson.core; From 249515273b0af3c3da7392e857cd014804923a5c Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 26 Jul 2022 16:20:57 +1200 Subject: [PATCH 0307/1323] Bump parent pom to exclude maven descriptor from final artifact --- http-client/client/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/http-client/client/pom.xml b/http-client/client/pom.xml index bb36e54b3..4d4d1e100 100644 --- a/http-client/client/pom.xml +++ b/http-client/client/pom.xml @@ -4,7 +4,7 @@ org.avaje java11-oss - 3.8 + 3.9 From c9d770880fb5fcc1c8cbacc29f11ca07ecd801c9 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 26 Jul 2022 16:21:22 +1200 Subject: [PATCH 0308/1323] [maven-release-plugin] prepare release avaje-http-client-1.19 --- http-client/client/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/http-client/client/pom.xml b/http-client/client/pom.xml index 4d4d1e100..39ef321d8 100644 --- a/http-client/client/pom.xml +++ b/http-client/client/pom.xml @@ -10,11 +10,11 @@ io.avaje avaje-http-client - 1.19-SNAPSHOT + 1.19 scm:git:git@github.com:avaje/avaje-http-client.git - HEAD + avaje-http-client-1.19 From 4565fb14ac94bca0368fbb27a53458c056151df7 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 26 Jul 2022 16:21:28 +1200 Subject: [PATCH 0309/1323] [maven-release-plugin] prepare for next development iteration --- http-client/client/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/http-client/client/pom.xml b/http-client/client/pom.xml index 39ef321d8..b29cd98c1 100644 --- a/http-client/client/pom.xml +++ b/http-client/client/pom.xml @@ -10,11 +10,11 @@ io.avaje avaje-http-client - 1.19 + 1.20-SNAPSHOT scm:git:git@github.com:avaje/avaje-http-client.git - avaje-http-client-1.19 + HEAD From d1102db8aabbb3004a1e047445775826a4f64ba1 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 26 Jul 2022 16:23:21 +1200 Subject: [PATCH 0310/1323] Prepare gson release --- http-client/gson-adapter/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/http-client/gson-adapter/pom.xml b/http-client/gson-adapter/pom.xml index fe14a1a4f..a7e56cc7d 100644 --- a/http-client/gson-adapter/pom.xml +++ b/http-client/gson-adapter/pom.xml @@ -4,7 +4,7 @@ org.avaje java11-oss - 3.8 + 3.9 @@ -28,7 +28,7 @@ io.avaje avaje-http-client - 1.19-SNAPSHOT + 1.19 provided From ce59375f571486636170932a9bff235a199d9e2a Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 26 Jul 2022 16:23:54 +1200 Subject: [PATCH 0311/1323] [maven-release-plugin] prepare release avaje-http-client-gson-1.19 --- http-client/gson-adapter/pom.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/http-client/gson-adapter/pom.xml b/http-client/gson-adapter/pom.xml index a7e56cc7d..baca8d7e8 100644 --- a/http-client/gson-adapter/pom.xml +++ b/http-client/gson-adapter/pom.xml @@ -5,16 +5,16 @@ org.avaje java11-oss 3.9 - + io.avaje avaje-http-client-gson - 1.19-SNAPSHOT + 1.19 scm:git:git@github.com:avaje/avaje-http-client.git - HEAD + avaje-http-client-gson-1.19 From ad97a80dff8cb4449b6e8da45eb65cb82633e54e Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 26 Jul 2022 16:24:00 +1200 Subject: [PATCH 0312/1323] [maven-release-plugin] prepare for next development iteration --- http-client/gson-adapter/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/http-client/gson-adapter/pom.xml b/http-client/gson-adapter/pom.xml index baca8d7e8..990a67b9d 100644 --- a/http-client/gson-adapter/pom.xml +++ b/http-client/gson-adapter/pom.xml @@ -10,11 +10,11 @@ io.avaje avaje-http-client-gson - 1.19 + 1.20-SNAPSHOT scm:git:git@github.com:avaje/avaje-http-client.git - avaje-http-client-gson-1.19 + HEAD From ae7a9fff2f76a07c364b884fd3b15824d560cb42 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 26 Jul 2022 16:44:06 +1200 Subject: [PATCH 0313/1323] Post release bump versions --- http-client/gson-adapter/pom.xml | 2 +- http-client/test/pom.xml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/http-client/gson-adapter/pom.xml b/http-client/gson-adapter/pom.xml index 990a67b9d..0f7f59109 100644 --- a/http-client/gson-adapter/pom.xml +++ b/http-client/gson-adapter/pom.xml @@ -28,7 +28,7 @@ io.avaje avaje-http-client - 1.19 + 1.20-SNAPSHOT provided diff --git a/http-client/test/pom.xml b/http-client/test/pom.xml index 2f4021012..fa21a8bcd 100644 --- a/http-client/test/pom.xml +++ b/http-client/test/pom.xml @@ -16,13 +16,13 @@ io.avaje avaje-http-client - 1.19-SNAPSHOT + 1.20-SNAPSHOT io.avaje avaje-http-client-gson - 1.19-SNAPSHOT + 1.20-SNAPSHOT From 8ffa47889bd5b32f344a24217d04288f46e9078b Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Wed, 24 Aug 2022 20:02:17 +1200 Subject: [PATCH 0314/1323] #85 - Change to use @Component (to be agnostic to javax.inject vs jakarata.inject) --- .../src/main/java/io/avaje/http/generator/core/Constants.java | 2 +- .../java/io/avaje/http/generator/core/ControllerReader.java | 2 +- .../io/avaje/http/generator/helidon/ControllerWriter.java | 4 ++-- .../io/avaje/http/generator/javalin/ControllerWriter.java | 4 ++-- .../java/io/avaje/http/generator/jex/ControllerWriter.java | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/Constants.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/Constants.java index 984889080..d27afc336 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/Constants.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/Constants.java @@ -10,7 +10,7 @@ public class Constants { static final String OPENAPIDEFINITION = "io.swagger.v3.oas.annotations.OpenAPIDefinition"; - static final String SINGLETON = "jakarta.inject.Singleton"; + static final String COMPONENT = "io.avaje.inject.Component"; static final String IMPORT_PATH_TYPE_CONVERT = "import static io.avaje.http.api.PathTypeConversion.*;"; diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java index 156e12162..faf9914b9 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java @@ -67,7 +67,7 @@ protected void addImports(boolean withSingleton) { importTypes.add(Constants.VALIDATOR); } if (withSingleton) { - importTypes.add(Constants.SINGLETON); + importTypes.add(Constants.COMPONENT); } } diff --git a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/ControllerWriter.java b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/ControllerWriter.java index e490d3fe4..98b19a240 100644 --- a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/ControllerWriter.java +++ b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/ControllerWriter.java @@ -11,7 +11,7 @@ */ class ControllerWriter extends BaseControllerWriter { - private static final String AT_GENERATED = "@Generated(\"io.dinject.helidon-generator\")"; + private static final String AT_GENERATED = "@Generated(\"avaje-helidon-generator\")"; ControllerWriter(ControllerReader reader, ProcessingContext ctx) throws IOException { super(reader, ctx); @@ -60,7 +60,7 @@ private void writeRoutes(List methods) { private void writeClassStart() { writer.append(AT_GENERATED).eol(); - writer.append("@Singleton").eol(); + writer.append("@Component").eol(); writer.append("public class ").append(shortName).append("$Route implements Service {").eol().eol(); String controllerName = "controller"; diff --git a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java index 807146b19..837f85c05 100644 --- a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java +++ b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java @@ -9,7 +9,7 @@ */ class ControllerWriter extends BaseControllerWriter { - private static final String AT_GENERATED = "@Generated(\"io.dinject.javalin-generator\")"; + private static final String AT_GENERATED = "@Generated(\"avaje-javalin-generator\")"; private static final String API_BUILDER = "io.javalin.apibuilder.ApiBuilder"; ControllerWriter(ControllerReader reader, ProcessingContext ctx) throws IOException { @@ -45,7 +45,7 @@ private void writeForMethod(MethodReader method) { private void writeClassStart() { writer.append(AT_GENERATED).eol(); - writer.append("@Singleton").eol(); + writer.append("@Component").eol(); writer.append("public class ").append(shortName).append("$Route implements WebRoutes {").eol().eol(); String controllerName = "controller"; diff --git a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerWriter.java b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerWriter.java index dd5cb4ab0..17df515d4 100644 --- a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerWriter.java +++ b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerWriter.java @@ -47,7 +47,7 @@ private void writeForMethod(MethodReader method) { private void writeClassStart() { writer.append(AT_GENERATED).eol(); - writer.append("@Singleton").eol(); + writer.append("@Component").eol(); writer.append("public class ").append(shortName).append("$Route implements Routing.Service {").eol().eol(); String controllerName = "controller"; From 5d7c5a3fb9fa43403cc1cba5e419d81643189e62 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Wed, 24 Aug 2022 20:03:26 +1200 Subject: [PATCH 0315/1323] #86 - Use Gradle incremental aggregating annotation processing --- .../resources/META-INF/gradle/incremental.annotation.processors | 1 + .../resources/META-INF/gradle/incremental.annotation.processors | 1 + .../resources/META-INF/gradle/incremental.annotation.processors | 1 + .../resources/META-INF/gradle/incremental.annotation.processors | 1 + 4 files changed, 4 insertions(+) create mode 100644 http-generator-client/src/main/resources/META-INF/gradle/incremental.annotation.processors create mode 100644 http-generator-helidon/src/main/resources/META-INF/gradle/incremental.annotation.processors create mode 100644 http-generator-javalin/src/main/resources/META-INF/gradle/incremental.annotation.processors create mode 100644 http-generator-jex/src/main/resources/META-INF/gradle/incremental.annotation.processors diff --git a/http-generator-client/src/main/resources/META-INF/gradle/incremental.annotation.processors b/http-generator-client/src/main/resources/META-INF/gradle/incremental.annotation.processors new file mode 100644 index 000000000..2a8acc9d3 --- /dev/null +++ b/http-generator-client/src/main/resources/META-INF/gradle/incremental.annotation.processors @@ -0,0 +1 @@ +io.avaje.http.generator.client.ClientProcessor,aggregating diff --git a/http-generator-helidon/src/main/resources/META-INF/gradle/incremental.annotation.processors b/http-generator-helidon/src/main/resources/META-INF/gradle/incremental.annotation.processors new file mode 100644 index 000000000..35bdfd2c5 --- /dev/null +++ b/http-generator-helidon/src/main/resources/META-INF/gradle/incremental.annotation.processors @@ -0,0 +1 @@ +io.avaje.http.generator.helidon.HelidonProcessor,aggregating diff --git a/http-generator-javalin/src/main/resources/META-INF/gradle/incremental.annotation.processors b/http-generator-javalin/src/main/resources/META-INF/gradle/incremental.annotation.processors new file mode 100644 index 000000000..8b730b9ad --- /dev/null +++ b/http-generator-javalin/src/main/resources/META-INF/gradle/incremental.annotation.processors @@ -0,0 +1 @@ +io.avaje.http.generator.javalin.JavalinProcessor,aggregating diff --git a/http-generator-jex/src/main/resources/META-INF/gradle/incremental.annotation.processors b/http-generator-jex/src/main/resources/META-INF/gradle/incremental.annotation.processors new file mode 100644 index 000000000..92c7deb3c --- /dev/null +++ b/http-generator-jex/src/main/resources/META-INF/gradle/incremental.annotation.processors @@ -0,0 +1 @@ +io.avaje.http.generator.jex.JexProcessor,aggregating From b68be8ca19e5e977c89b05f2797dfd2f10020648 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Wed, 24 Aug 2022 20:04:00 +1200 Subject: [PATCH 0316/1323] Bump test avaje-inject version --- tests/test-client/pom.xml | 2 +- tests/test-jex/pom.xml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index 0a77cce20..3119cf47c 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -16,7 +16,7 @@ true 1.6 - 8.3 + 8.9 diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 1b3ad8cc0..10c3993e9 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -16,10 +16,10 @@ true org.example.myapp.Main - 2.0 + 2.2 2.0.8 2.12.6.1 - 8.3 + 8.9 1.18-SNAPSHOT From e5dd22e912ade8bca25445710d57876907f83122 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Wed, 24 Aug 2022 20:05:56 +1200 Subject: [PATCH 0317/1323] Bump parent poms --- http-hibernate-validator/pom.xml | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/http-hibernate-validator/pom.xml b/http-hibernate-validator/pom.xml index 762528249..0ad273c35 100644 --- a/http-hibernate-validator/pom.xml +++ b/http-hibernate-validator/pom.xml @@ -9,7 +9,7 @@ org.avaje java8-oss - 3.8 + 3.9 diff --git a/pom.xml b/pom.xml index fa88a2a79..638f72a94 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ org.avaje java11-oss - 3.8 + 3.9 io.avaje From 8fdaebd6b336ac1f4645c127ce329b0aee5a5d41 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 20 Sep 2022 16:27:39 +1200 Subject: [PATCH 0318/1323] #88 - Helidon Nima support initial --- .../http/generator/core/PathSegments.java | 4 + http-generator-nima/pom.xml | 46 +++++++ .../helidon/nima/ControllerMethodWriter.java | 115 ++++++++++++++++++ .../helidon/nima/ControllerWriter.java | 94 ++++++++++++++ .../helidon/nima/NimaPlatformAdapter.java | 115 ++++++++++++++++++ .../generator/helidon/nima/NimaProcessor.java | 21 ++++ .../gradle/incremental.annotation.processors | 1 + .../javax.annotation.processing.Processor | 1 + pom.xml | 1 + tests/pom.xml | 13 +- .../src/main/resources/public/openapi.json | 60 +++++++++ tests/test-nima/pom.xml | 95 +++++++++++++++ .../java/org/example/HelloController.java | 21 ++++ .../src/main/java/org/example/Main.java | 51 ++++++++ .../src/main/java/org/example/Person.java | 23 ++++ 15 files changed, 660 insertions(+), 1 deletion(-) create mode 100644 http-generator-nima/pom.xml create mode 100644 http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java create mode 100644 http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java create mode 100644 http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/NimaPlatformAdapter.java create mode 100644 http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/NimaProcessor.java create mode 100644 http-generator-nima/src/main/resources/META-INF/gradle/incremental.annotation.processors create mode 100644 http-generator-nima/src/main/resources/META-INF/services/javax.annotation.processing.Processor create mode 100644 tests/test-nima/pom.xml create mode 100644 tests/test-nima/src/main/java/org/example/HelloController.java create mode 100644 tests/test-nima/src/main/java/org/example/Main.java create mode 100644 tests/test-nima/src/main/java/org/example/Person.java diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/PathSegments.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/PathSegments.java index c6c5036f0..2f84a23eb 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/PathSegments.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/PathSegments.java @@ -126,6 +126,10 @@ private String fullPath(String prefix, String suffix) { return chunks.fullPath(prefix, suffix); } + public boolean isEmpty() { + return segments.isEmpty(); + } + public static class Segment { private final String name; diff --git a/http-generator-nima/pom.xml b/http-generator-nima/pom.xml new file mode 100644 index 000000000..c2ddf5485 --- /dev/null +++ b/http-generator-nima/pom.xml @@ -0,0 +1,46 @@ + + + + avaje-http-generator-parent + io.avaje + 1.18-SNAPSHOT + + 4.0.0 + + avaje-http-nima-generator + + + 17 + 17 + UTF-8 + + + + + + io.avaje + avaje-http-generator-core + ${project.version} + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.10.1 + + 11 + 11 + + -proc:none + + + + + + diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java new file mode 100644 index 000000000..e8cf095b2 --- /dev/null +++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java @@ -0,0 +1,115 @@ +package io.avaje.http.generator.helidon.nima; + +import io.avaje.http.api.MediaType; +import io.avaje.http.generator.core.*; + +import java.util.List; + +/** + * Write code to register Web route for a given controller method. + */ +class ControllerMethodWriter { + + private final MethodReader method; + private final Append writer; + private final WebMethod webMethod; + private final ProcessingContext ctx; + + ControllerMethodWriter(MethodReader method, Append writer, ProcessingContext ctx) { + this.method = method; + this.writer = writer; + this.webMethod = method.getWebMethod(); + this.ctx = ctx; + } + + void writeRule() { + final String fullPath = method.getFullPath(); +// final String bodyType = method.getBodyType(); +// if (bodyType != null) { +// writer.append(" rules.%s(\"%s\", Handler.create(%s.class, this::_%s));", webMethod.name().toLowerCase(), fullPath, bodyType, method.simpleName()).eol(); +// } else if (method.isFormBody()) { +// writer.append(" rules.%s(\"%s\", Handler.create(%s.class, this::_%s));", webMethod.name().toLowerCase(), fullPath, "FormParams", method.simpleName()).eol(); +// } else { + writer.append(" rules.%s(\"%s\", this::_%s);", webMethod.name().toLowerCase(), fullPath, method.simpleName()).eol(); +// } + } + + void writeHandler(boolean requestScoped) { + writer.append(" private void _%s(ServerRequest req, ServerResponse res", method.simpleName()); + + writer.append(") {").eol(); +// if (!method.isVoid()) { +// writeContextReturn(); +// } + + final String bodyType = method.getBodyType(); + if (bodyType != null) { + writer.append(" // body - %s %s", bodyType, method.getBodyName()).eol(); + }// else if (method.isFormBody()) { + // writer.append(", %s %s", "FormParams", "formParams"); + //} + + final PathSegments segments = method.getPathSegments(); + if (!segments.isEmpty()) { + writer.append(" var pathParams = req.path().pathParameters();").eol(); + + } + List matrixSegments = segments.matrixSegments(); + for (PathSegments.Segment matrixSegment : matrixSegments) { + matrixSegment.writeCreateSegment(writer, ctx.platform()); + } + + final List params = method.getParams(); + for (MethodParam param : params) { + param.writeCtxGet(writer, segments); + } + writer.append(" "); + if (!method.isVoid()) { + writer.append("var result = "); + //writer.append("res.send("); + } + + if (method.includeValidate()) { + for (MethodParam param : params) { + param.writeValidate(writer); + } + } + if (requestScoped) { + writer.append("factory.create(req, res)."); + } else { + writer.append("controller."); + } + writer.append(method.simpleName()).append("("); + for (int i = 0; i < params.size(); i++) { + if (i > 0) { + writer.append(", "); + } + params.get(i).buildParamName(writer); + } + writer.append(");").eol(); + if (!method.isVoid()) { + writeContextReturn(); + writer.append(" res.send(result);").eol(); + } + writer.append(" }").eol().eol(); + } + + private void writeContextReturn() { + final String produces = method.getProduces(); + if (produces == null) { + // let it be automatically set + } else if (MediaType.APPLICATION_JSON.equalsIgnoreCase(produces)) { + writer.append(" res.writerContext().contentType(io.helidon.common.http.MediaType.APPLICATION_JSON);").eol(); + } else if (MediaType.TEXT_HTML.equalsIgnoreCase(produces)) { + writer.append(" res.writerContext().contentType(io.helidon.common.http.MediaType.TEXT_HTML);").eol(); + } else if (MediaType.TEXT_PLAIN.equalsIgnoreCase(produces)) { + writer.append(" res.writerContext().contentType(io.helidon.common.http.MediaType.TEXT_PLAIN);").eol(); + } else { + writer.append( "res.writerContext().contentType(io.helidon.common.http.MediaType.parse(\"%s\"));", produces).eol(); + } + } + + public void buildApiDocumentation() { + method.buildApiDoc(); + } +} diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java new file mode 100644 index 000000000..86119870c --- /dev/null +++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java @@ -0,0 +1,94 @@ +package io.avaje.http.generator.helidon.nima; + +import io.avaje.http.generator.core.*; + +import java.io.IOException; +import java.util.List; +import java.util.stream.Collectors; + +/** + * Write Helidon specific web route adapter (a Helidon Service). + */ +class ControllerWriter extends BaseControllerWriter { + + private static final String AT_GENERATED = "@Generated(\"avaje-helidon-nima-generator\")"; + + ControllerWriter(ControllerReader reader, ProcessingContext ctx) throws IOException { + super(reader, ctx); + //reader.addImportType("io.helidon.common.http.FormParams"); + reader.addImportType("io.helidon.nima.webserver.http.HttpRules"); + reader.addImportType("io.helidon.nima.webserver.http.HttpRouting"); + reader.addImportType("io.helidon.nima.webserver.http.ServerRequest"); + reader.addImportType("io.helidon.nima.webserver.http.ServerResponse"); + //reader.addImportType("io.helidon.nima.webserver.Routing"); + //reader.addImportType("java.util.function.Supplier"); + reader.addImportType("io.helidon.nima.webserver.http.HttpService"); + } + + void write() { + writePackage(); + writeImports(); + writeClassStart(); + writeAddRoutes(); + writeClassEnd(); + } + + private List getWriterMethods() { + return reader.getMethods().stream() + .filter(MethodReader::isWebMethod) + .map(it -> new ControllerMethodWriter(it, writer, ctx)) + .collect(Collectors.toList()); + } + + private void writeAddRoutes() { + final List methods = getWriterMethods(); + writeRoutes(methods); + for (ControllerMethodWriter methodWriter : methods) { + methodWriter.writeHandler(isRequestScoped()); + } + } + + private void writeRoutes(List methods) { + writer.append(" @Override").eol(); + writer.append(" public void routing(HttpRules rules) {").eol(); + //writer.append(" var rules = HttpRouting.builder();").eol(); + for (ControllerMethodWriter methodWriter : methods) { + methodWriter.writeRule(); + if (!reader.isDocHidden()) { + methodWriter.buildApiDocumentation(); + } + } + //writer.append(" return rules.build();").eol().eol(); + writer.append(" }").eol().eol(); + } + + private void writeClassStart() { + writer.append(AT_GENERATED).eol(); + writer.append("@Component").eol(); + writer.append("public class ").append(shortName).append("$Route implements HttpService {").eol().eol(); + + String controllerName = "controller"; + String controllerType = shortName; + if (isRequestScoped()) { + controllerName = "factory"; + controllerType += Constants.FACTORY_SUFFIX; + } + writer.append(" private final %s %s;", controllerType, controllerName).eol(); + if (reader.isIncludeValidator()) { + writer.append(" private final Validator validator;").eol(); + } + writer.eol(); + + writer.append(" public %s$Route(%s %s", shortName, controllerType, controllerName); + if (reader.isIncludeValidator()) { + writer.append(", Validator validator"); + } + writer.append(") {").eol(); + writer.append(" this.%s = %s;", controllerName, controllerName).eol(); + if (reader.isIncludeValidator()) { + writer.append(" this.validator = validator;").eol(); + } + writer.append(" }").eol().eol(); + } + +} diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/NimaPlatformAdapter.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/NimaPlatformAdapter.java new file mode 100644 index 000000000..995668c7b --- /dev/null +++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/NimaPlatformAdapter.java @@ -0,0 +1,115 @@ +package io.avaje.http.generator.helidon.nima; + +import io.avaje.http.generator.core.Append; +import io.avaje.http.generator.core.ControllerReader; +import io.avaje.http.generator.core.ParamType; +import io.avaje.http.generator.core.PlatformAdapter; + +import java.util.List; + +class NimaPlatformAdapter implements PlatformAdapter { + + static final String NIMA_REQ = "io.helidon.nima.webserver.http.ServerRequest"; + static final String NIMA_RES = "io.helidon.nima.webserver.http.ServerResponse"; + static final String HELIDON_FORMPARAMS = "io.helidon.common.http.FormParams"; + + @Override + public boolean isContextType(String rawType) { + return NIMA_REQ.equals(rawType) || NIMA_RES.equals(rawType) || HELIDON_FORMPARAMS.equals(rawType); + } + + @Override + public String platformVariable(String rawType) { + if (NIMA_REQ.equals(rawType)) { + return "req"; + } + if (NIMA_RES.equals(rawType)) { + return "res"; + } + if (HELIDON_FORMPARAMS.equals(rawType)) { + return "formParams"; + } + return "unknownVariable for: "+rawType; + } + + @Override + public boolean isBodyMethodParam() { + return true; + } + + @Override + public String bodyAsClass(String shortType) { + return "body"; + } + + @Override + public String indent() { + return " "; + } + + @Override + public void controllerRoles(List roles, ControllerReader controller) { + addRoleImports(roles, controller); + } + + @Override + public void methodRoles(List roles, ControllerReader controller) { + addRoleImports(roles, controller); + } + + private void addRoleImports(List roles, ControllerReader controller) { + // nothing here yet + } + + @Override + public void writeReadParameter(Append writer, ParamType paramType, String paramName) { + switch (paramType) { + case PATHPARAM: + writer.append("pathParams.first(\"%s\").get()", paramName); + break; + case QUERYPARAM: + writer.append("req.query().first(\"%s\").orElse(null)", paramName); + break; + case FORMPARAM: + writer.append("formParams.first(\"%s\").orElse(null)", paramName); + break; + case HEADER: + writer.append("req.headers().value(Http.Header.create(\"%s\").orElse(null)", paramName); + break; + case COOKIE: + writer.append("req.headers().cookies().first(\"%s\").orElse(null)", paramName); + break; + case BODY: + case BEANPARAM: + case FORM: + default: + writer.append("null // TODO req.%s().param(\"%s\")", paramType.getType(), paramName); + } + } + + @Override + public void writeReadParameter(Append writer, ParamType paramType, String paramName, String paramDefault) { + switch (paramType) { + case PATHPARAM: + writer.append("pathParams.first(\"%s\").orElse(\"%s\")", paramName, paramDefault); + break; + case QUERYPARAM: + writer.append("req.query().first(\"%s\").orElse(\"%s\")", paramName, paramDefault); + break; + case FORMPARAM: + writer.append("formParams.first(\"%s\").orElse(\"%s\")", paramName, paramDefault); + break; + case HEADER: + writer.append("req.headers().value(Http.Header.create(\"%s\").orElse(\"%s\")", paramName, paramDefault); + break; + case COOKIE: + writer.append("req.headers().cookies().first(\"%s\").orElse(\"%s\")", paramName, paramDefault); + break; + case BODY: + case BEANPARAM: + case FORM: + default: + writer.append("null // TODO req.%s().param(\"%s\")", paramType.getType(), paramName); + } + } +} diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/NimaProcessor.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/NimaProcessor.java new file mode 100644 index 000000000..c9e47b029 --- /dev/null +++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/NimaProcessor.java @@ -0,0 +1,21 @@ +package io.avaje.http.generator.helidon.nima; + +import io.avaje.http.generator.core.BaseProcessor; +import io.avaje.http.generator.core.ControllerReader; +import io.avaje.http.generator.core.PlatformAdapter; +import io.avaje.http.generator.core.ProcessingContext; + +import java.io.IOException; + +public class NimaProcessor extends BaseProcessor { + + @Override + protected PlatformAdapter providePlatformAdapter() { + return new NimaPlatformAdapter(); + } + + @Override + public void writeControllerAdapter(ProcessingContext ctx, ControllerReader reader) throws IOException { + new ControllerWriter(reader, ctx).write(); + } +} diff --git a/http-generator-nima/src/main/resources/META-INF/gradle/incremental.annotation.processors b/http-generator-nima/src/main/resources/META-INF/gradle/incremental.annotation.processors new file mode 100644 index 000000000..cbda140e4 --- /dev/null +++ b/http-generator-nima/src/main/resources/META-INF/gradle/incremental.annotation.processors @@ -0,0 +1 @@ +io.avaje.http.generator.helidon.nima.HelidonProcessor,aggregating diff --git a/http-generator-nima/src/main/resources/META-INF/services/javax.annotation.processing.Processor b/http-generator-nima/src/main/resources/META-INF/services/javax.annotation.processing.Processor new file mode 100644 index 000000000..97697d264 --- /dev/null +++ b/http-generator-nima/src/main/resources/META-INF/services/javax.annotation.processing.Processor @@ -0,0 +1 @@ +io.avaje.http.generator.helidon.nima.NimaProcessor diff --git a/pom.xml b/pom.xml index 638f72a94..5ec5342dd 100644 --- a/pom.xml +++ b/pom.xml @@ -38,6 +38,7 @@ http-generator-jex http-generator-helidon http-generator-client + http-generator-nima diff --git a/tests/pom.xml b/tests/pom.xml index 6d4af8a3b..99792e459 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -15,9 +15,20 @@ test-helidon test-javalin test-jex - test-client + + + jdk19plus + + [19,20] + + + test-nima + + + + diff --git a/tests/test-javalin/src/main/resources/public/openapi.json b/tests/test-javalin/src/main/resources/public/openapi.json index 3bc47760e..fe92fc8f0 100644 --- a/tests/test-javalin/src/main/resources/public/openapi.json +++ b/tests/test-javalin/src/main/resources/public/openapi.json @@ -134,6 +134,66 @@ } } }, + "/baz/checkparams/{id}" : { + "get" : { + "tags" : [ ], + "summary" : "", + "description" : "", + "parameters" : [ { + "name" : "id", + "in" : "path", + "required" : true, + "schema" : { + "type" : "integer", + "format" : "int32", + "nullable" : false + } + }, { + "name" : "p1", + "in" : "query", + "schema" : { + "type" : "string" + } + }, { + "name" : "p2", + "in" : "query", + "schema" : { + "type" : "number" + } + }, { + "name" : "p3", + "in" : "query", + "schema" : { + "type" : "integer", + "format" : "int32" + } + }, { + "name" : "p4", + "in" : "query", + "schema" : { + "type" : "number" + } + }, { + "name" : "body", + "in" : "query", + "schema" : { + "type" : "string" + } + } ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, "/baz/findbyname/{name}" : { "get" : { "tags" : [ ], diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml new file mode 100644 index 000000000..45adbd2bf --- /dev/null +++ b/tests/test-nima/pom.xml @@ -0,0 +1,95 @@ + + + 4.0.0 + + avaje-http-generator-parent + io.avaje + 1.18-SNAPSHOT + ../../pom.xml + + + test-nima + 1 + + + 19 + 19 + UTF-8 + + + + + + io.avaje + avaje-inject + 8.9 + + + + io.avaje + avaje-http-api + 1.18-SNAPSHOT + + + io.helidon.nima.webserver + helidon-nima-webserver + 4.0.0-ALPHA1 + + + io.helidon.nima.http.media + helidon-nima-http-media-jsonb + 4.0.0-ALPHA1 + + + + + + + + + + + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.10.1 + + 19 + + + io.avaje + avaje-http-nima-generator + 1.18-SNAPSHOT + + + io.avaje + avaje-inject-generator + 8.9 + + + + + + io.repaint.maven + tiles-maven-plugin + 2.22 + true + + + org.avaje.tile:lib-classpath:1.1 + + + + + + + + diff --git a/tests/test-nima/src/main/java/org/example/HelloController.java b/tests/test-nima/src/main/java/org/example/HelloController.java new file mode 100644 index 000000000..79491f744 --- /dev/null +++ b/tests/test-nima/src/main/java/org/example/HelloController.java @@ -0,0 +1,21 @@ +package org.example; + +import io.avaje.http.api.Controller; +import io.avaje.http.api.Get; + +@Controller +public class HelloController { + + @Get("hello") + String helloWorld() { + return "Hello world"; + } + + @Get("person/{name}/{sortBy}") + Person person(String name, String sortBy) { + var p = new Person(); + p.setId(42); + p.setName("asdasd"); + return p; + } +} diff --git a/tests/test-nima/src/main/java/org/example/Main.java b/tests/test-nima/src/main/java/org/example/Main.java new file mode 100644 index 000000000..f8c37b9a7 --- /dev/null +++ b/tests/test-nima/src/main/java/org/example/Main.java @@ -0,0 +1,51 @@ +package org.example; + +import io.avaje.inject.BeanScope; +import io.helidon.nima.webserver.Routing; +import io.helidon.nima.webserver.WebServer; +import io.helidon.nima.webserver.http.HttpRouting; +import io.helidon.nima.webserver.http.HttpService; + +import java.util.List; + +public class Main { + + public static void main(String[] args) { + + BeanScope scope = BeanScope.builder().build(); + List list = scope.list(HttpService.class); + HttpRouting.Builder builder = HttpRouting.builder(); + for (HttpService httpService : list) { + httpService.routing(builder); + } + HttpRouting httpRouting = builder.build(); + + + WebServer.builder() + //.addRouting(httpRouting) + .routing(Main::routing) + .port(8081) + .start(); + + System.out.println("started"); + } + + private static Routing routing(HttpRouting.Builder route) { + return route + .get("/", (req, res) -> { + res.send("hello world"); + }) + .get("/hi", (req, res) -> { + res.header("my-header", "hi-header"); + //res.send("hi!!"); + + var p = new Person(); + p.setId(42); + p.setName("asdasd"); + + // + res.send(p); + }) + .build(); + } +} diff --git a/tests/test-nima/src/main/java/org/example/Person.java b/tests/test-nima/src/main/java/org/example/Person.java new file mode 100644 index 000000000..4959f219e --- /dev/null +++ b/tests/test-nima/src/main/java/org/example/Person.java @@ -0,0 +1,23 @@ +package org.example; + +public class Person { + + long id; + String name; + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} From c4d91b39546d0a40abaeea079fd1e78cbacb137a Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Wed, 28 Sep 2022 12:12:52 -0500 Subject: [PATCH 0319/1323] Now get type from array Type/mirror --- .../io/avaje/http/generator/core/openapi/SchemaDocBuilder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/SchemaDocBuilder.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/SchemaDocBuilder.java index 81fa64cd7..22b1b1403 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/SchemaDocBuilder.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/SchemaDocBuilder.java @@ -177,7 +177,7 @@ private Schema buildIterableSchema(TypeMirror type) { private Schema buildArraySchema(TypeMirror type) { - ArrayType arrayType = types.getArrayType(type); + ArrayType arrayType = (ArrayType) type; Schema itemSchema = toSchema(arrayType.getComponentType()); ArraySchema arraySchema = new ArraySchema(); From cba0c516e4e5c3c4494b880185a120caf9f6b022 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Thu, 29 Sep 2022 17:21:29 +1300 Subject: [PATCH 0320/1323] Tweak test for Helidon Nima support initial --- .../test-nima/src/main/java/org/example/HelloController.java | 2 +- tests/test-nima/src/main/java/org/example/Main.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/test-nima/src/main/java/org/example/HelloController.java b/tests/test-nima/src/main/java/org/example/HelloController.java index 79491f744..fbff3ec17 100644 --- a/tests/test-nima/src/main/java/org/example/HelloController.java +++ b/tests/test-nima/src/main/java/org/example/HelloController.java @@ -15,7 +15,7 @@ String helloWorld() { Person person(String name, String sortBy) { var p = new Person(); p.setId(42); - p.setName("asdasd"); + p.setName(name + " hello" + " sortBy:" + sortBy); return p; } } diff --git a/tests/test-nima/src/main/java/org/example/Main.java b/tests/test-nima/src/main/java/org/example/Main.java index f8c37b9a7..c1711a8b7 100644 --- a/tests/test-nima/src/main/java/org/example/Main.java +++ b/tests/test-nima/src/main/java/org/example/Main.java @@ -22,8 +22,8 @@ public static void main(String[] args) { WebServer.builder() - //.addRouting(httpRouting) - .routing(Main::routing) + .addRouting(httpRouting) + //.routing(Main::routing) .port(8081) .start(); From f563e24e4a4e5c2afa371c3432aa341a21598e47 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Wed, 28 Sep 2022 23:39:23 -0500 Subject: [PATCH 0321/1323] Add more MediaTypes for byte[] responses; --- .../java/io/avaje/http/api/MediaType.java | 34 +++++++++++++++++-- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/http-api/src/main/java/io/avaje/http/api/MediaType.java b/http-api/src/main/java/io/avaje/http/api/MediaType.java index 52f60d695..931719c55 100644 --- a/http-api/src/main/java/io/avaje/http/api/MediaType.java +++ b/http-api/src/main/java/io/avaje/http/api/MediaType.java @@ -35,7 +35,6 @@ public interface MediaType { */ String APPLICATION_FORM_URLENCODED = "application/x-www-form-urlencoded"; - /** * A {@code String} constant representing {@value #MULTIPART_FORM_DATA} media type. */ @@ -51,7 +50,6 @@ public interface MediaType { */ String TEXT_PLAIN = "text/plain"; - /** * A {@code String} constant representing {@value #TEXT_XML} media type. */ @@ -71,5 +69,35 @@ public interface MediaType { * {@link String} representation of {@value #APPLICATION_JSON_PATCH_JSON} media type.. */ String APPLICATION_JSON_PATCH_JSON = "application/json-patch+json"; - + + /** + * {@link String} representation of {@value #APPLICATION_PDF} media type. + */ + String APPLICATION_PDF = "application/pdf"; + + /** + * {@link String} representation of {@value #IMAGE_GIF} media type. + */ + String IMAGE_GIF = "image/gif"; + + /** + * {@link String} representation of {@value #IMAGE_JPEG} media type. + */ + String IMAGE_JPEG = "image/jpeg"; + + /** + * {@link String} representation of {@value #IMAGE_PNG} media type. + */ + String IMAGE_PNG = "image/png"; + + /** + * {@link String} representation of {@value #MULTIPART_MIXED} media type. + */ + String MULTIPART_MIXED = "multipart/mixed"; + + /** + * {@link String} representation of {@value #MULTIPART_RELATED} media type. + */ + String MULTIPART_RELATED = "multipart/related"; + } From ad412ed625082b546cca58775627b2f4e6b57393 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Wed, 12 Oct 2022 14:45:29 -0500 Subject: [PATCH 0322/1323] Add Helidon Example to README --- README.md | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 65 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 84359f626..c8a9bf136 100644 --- a/README.md +++ b/README.md @@ -44,7 +44,7 @@ class WidgetController(private val hello: HelloComponent) { ``` -## Generated source +## Generated source (Javalin) The annotation processor will generate a `$Route` for the controller like below. @@ -55,7 +55,7 @@ get all the WebRoutes and register them with Javalin using. fun main(args: Array) { // get all the webRoutes - val webRoutes = ApplicationScope.list(WebRoutes::class.java) + val webRoutes = BeanScope.builder().build().list(WebRoutes::class.java) val javalin = Javalin.create() @@ -76,7 +76,7 @@ fun main(args: Array) { ``` -### The generated WidgetController$Route.java is: +### (Javalin) The generated WidgetController$Route.java is: ```java @@ -117,6 +117,68 @@ public class WidgetController$Route implements WebRoutes { } ``` +## Generated source (Helidon SE) + +The annotation processor will generate a `$Route` for the controller like below. + +Note that this class implements the Helidon Service interface, which means we can +get all the Services and register them with Helidon `RoutingBuilder`. + +``` +var routes = BeanScope.builder().build().list(Service.class); +var routingBuilder = Routing.builder().register(routes.stream().toArray(Service[]::new)); +WebServer.builder() + .addMediaSupport(JacksonSupport.create()) + .routing(routingBuilder) + .build() + .start(); +``` +### (Helidon SE) The generated WidgetController$Route.java is: + +```java +package org.example.hello; + +import static io.avaje.http.api.PathTypeConversion.*; + +import io.avaje.http.api.*; +import io.helidon.common.http.FormParams; +import io.helidon.webserver.Handler; +import io.helidon.webserver.Routing; +import io.helidon.webserver.ServerRequest; +import io.helidon.webserver.ServerResponse; +import io.helidon.webserver.Service; +import jakarta.inject.Singleton; +import org.example.hello.WidgetController; + +@Generated("io.dinject.helidon-generator") +@Singleton +public class WidgetController$Route implements Service { + + private final WidgetController controller; + + public WidgetController$Route(WidgetController controller) { + this.controller = controller; + } + + @Override + public void update(Routing.Rules rules) { + + rules.get("/widgets/:id", this::_getById); + rules.post("/widgets", this::_getAll); + } + + private void _getById(ServerRequest req, ServerResponse res) { + int id = asInt(req.path().param("id")); + res.send(controller.getById(id)); + } + + private void _getAll(ServerRequest req, ServerResponse res) { + res.send(controller.getAll()); + } + +} +``` + Note that this APT processor works with both Java and Kotlin. From e30e2046cb21b693f3d165e3f387cb556658c319 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Fri, 14 Oct 2022 12:50:32 -0400 Subject: [PATCH 0323/1323] fix nima media type/use JDK 19 --- .gitignore | 6 +++ http-generator-nima/pom.xml | 9 ++-- .../helidon/nima/ControllerMethodWriter.java | 54 +++++++++++-------- 3 files changed, 42 insertions(+), 27 deletions(-) diff --git a/.gitignore b/.gitignore index 0c9d542d8..a8b2ebbcb 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,9 @@ build/ .idea/ *.iml .gradle +http-generator-nima/.settings/org.eclipse.m2e.core.prefs +http-generator-nima/.settings/org.eclipse.jdt.core.prefs +http-generator-nima/.settings/org.eclipse.jdt.apt.core.prefs +http-generator-nima/.settings/org.eclipse.core.resources.prefs +http-generator-nima/.project +http-generator-nima/.classpath diff --git a/http-generator-nima/pom.xml b/http-generator-nima/pom.xml index c2ddf5485..a6cdc056c 100644 --- a/http-generator-nima/pom.xml +++ b/http-generator-nima/pom.xml @@ -12,8 +12,9 @@ avaje-http-nima-generator - 17 - 17 + 19 + 19 + 19 UTF-8 @@ -34,8 +35,8 @@ maven-compiler-plugin 3.10.1 - 11 - 11 + 19 + 19 -proc:none diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java index e8cf095b2..e1352a118 100644 --- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java +++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java @@ -1,9 +1,12 @@ package io.avaje.http.generator.helidon.nima; import io.avaje.http.api.MediaType; -import io.avaje.http.generator.core.*; - -import java.util.List; +import io.avaje.http.generator.core.Append; +import io.avaje.http.generator.core.MethodParam; +import io.avaje.http.generator.core.MethodReader; +import io.avaje.http.generator.core.PathSegments; +import io.avaje.http.generator.core.ProcessingContext; +import io.avaje.http.generator.core.WebMethod; /** * Write code to register Web route for a given controller method. @@ -18,12 +21,12 @@ class ControllerMethodWriter { ControllerMethodWriter(MethodReader method, Append writer, ProcessingContext ctx) { this.method = method; this.writer = writer; - this.webMethod = method.getWebMethod(); + webMethod = method.getWebMethod(); this.ctx = ctx; } void writeRule() { - final String fullPath = method.getFullPath(); + final var fullPath = method.getFullPath(); // final String bodyType = method.getBodyType(); // if (bodyType != null) { // writer.append(" rules.%s(\"%s\", Handler.create(%s.class, this::_%s));", webMethod.name().toLowerCase(), fullPath, bodyType, method.simpleName()).eol(); @@ -42,25 +45,25 @@ void writeHandler(boolean requestScoped) { // writeContextReturn(); // } - final String bodyType = method.getBodyType(); + final var bodyType = method.getBodyType(); if (bodyType != null) { writer.append(" // body - %s %s", bodyType, method.getBodyName()).eol(); }// else if (method.isFormBody()) { // writer.append(", %s %s", "FormParams", "formParams"); //} - final PathSegments segments = method.getPathSegments(); + final var segments = method.getPathSegments(); if (!segments.isEmpty()) { writer.append(" var pathParams = req.path().pathParameters();").eol(); } - List matrixSegments = segments.matrixSegments(); - for (PathSegments.Segment matrixSegment : matrixSegments) { + final var matrixSegments = segments.matrixSegments(); + for (final PathSegments.Segment matrixSegment : matrixSegments) { matrixSegment.writeCreateSegment(writer, ctx.platform()); } - final List params = method.getParams(); - for (MethodParam param : params) { + final var params = method.getParams(); + for (final MethodParam param : params) { param.writeCtxGet(writer, segments); } writer.append(" "); @@ -70,7 +73,7 @@ void writeHandler(boolean requestScoped) { } if (method.includeValidate()) { - for (MethodParam param : params) { + for (final MethodParam param : params) { param.writeValidate(writer); } } @@ -80,7 +83,7 @@ void writeHandler(boolean requestScoped) { writer.append("controller."); } writer.append(method.simpleName()).append("("); - for (int i = 0; i < params.size(); i++) { + for (var i = 0; i < params.size(); i++) { if (i > 0) { writer.append(", "); } @@ -95,17 +98,22 @@ void writeHandler(boolean requestScoped) { } private void writeContextReturn() { - final String produces = method.getProduces(); + final var produces = method.getProduces(); + + final var contentTypeString = + " res.headers().contentType(io.helidon.common.http.HttpMediaType."; + if (produces == null) { - // let it be automatically set - } else if (MediaType.APPLICATION_JSON.equalsIgnoreCase(produces)) { - writer.append(" res.writerContext().contentType(io.helidon.common.http.MediaType.APPLICATION_JSON);").eol(); - } else if (MediaType.TEXT_HTML.equalsIgnoreCase(produces)) { - writer.append(" res.writerContext().contentType(io.helidon.common.http.MediaType.TEXT_HTML);").eol(); - } else if (MediaType.TEXT_PLAIN.equalsIgnoreCase(produces)) { - writer.append(" res.writerContext().contentType(io.helidon.common.http.MediaType.TEXT_PLAIN);").eol(); - } else { - writer.append( "res.writerContext().contentType(io.helidon.common.http.MediaType.parse(\"%s\"));", produces).eol(); + return; + } + + switch (produces.toLowerCase()) { + case MediaType.APPLICATION_JSON -> writer + .append(contentTypeString + "APPLICATION_JSON);") + .eol(); + case MediaType.TEXT_HTML -> writer.append(contentTypeString + "TEXT_HTML);").eol(); + case MediaType.TEXT_PLAIN -> writer.append(contentTypeString + "TEXT_PLAIN);").eol(); + default -> writer.append(contentTypeString + "create(\"%s\"));", produces).eol(); } } From ca625c42236ba3fa169d9434df4c32dd47d12e2d Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Fri, 14 Oct 2022 13:06:26 -0400 Subject: [PATCH 0324/1323] Update ControllerMethodWriter.java --- .../http/generator/helidon/nima/ControllerMethodWriter.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java index e1352a118..1f2c51bb4 100644 --- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java +++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java @@ -100,13 +100,13 @@ void writeHandler(boolean requestScoped) { private void writeContextReturn() { final var produces = method.getProduces(); - final var contentTypeString = - " res.headers().contentType(io.helidon.common.http.HttpMediaType."; - if (produces == null) { return; } + final var contentTypeString = + " res.headers().contentType(io.helidon.common.http.HttpMediaType."; + switch (produces.toLowerCase()) { case MediaType.APPLICATION_JSON -> writer .append(contentTypeString + "APPLICATION_JSON);") From 4bb56183fca61f03eb2c2cb75f9b82b0a88e79bc Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Fri, 14 Oct 2022 13:36:56 -0400 Subject: [PATCH 0325/1323] fix pipeline --- .github/workflows/build.yml | 47 ++++++++++++++++++++----------------- 1 file changed, 26 insertions(+), 21 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e921ac573..5d02d8dc4 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,10 +1,8 @@ name: Build on: [push, pull_request, workflow_dispatch] - jobs: build: - runs-on: ${{ matrix.os }} permissions: contents: read @@ -12,25 +10,32 @@ jobs: strategy: fail-fast: false matrix: - java_version: [11,17] + java_version: [11, 17, 19] os: [ubuntu-latest] steps: - - uses: actions/checkout@v2 - - name: Set up Java - uses: actions/setup-java@v2 - with: - java-version: ${{ matrix.java_version }} - distribution: 'zulu' - - name: Maven cache - uses: actions/cache@v2 - env: - cache-name: maven-cache - with: - path: - ~/.m2 - key: build-${{ env.cache-name }} - - name: Maven version - run: mvn --version - - name: Build with Maven - run: mvn clean test + - uses: actions/checkout@v2 + - name: Set up Java + uses: actions/setup-java@v2 + with: + java-version: ${{ matrix.java_version }} + distribution: "zulu" + - name: Maven cache + uses: actions/cache@v2 + env: + cache-name: maven-cache + with: + path: ~/.m2 + key: build-${{ env.cache-name }} + - name: Maven version + run: mvn --version + - name: Build with Maven + env: + JAVA_VERSION: ${{ matrix.java_version }} + run: | + if (( JAVA_VERSION < 19 )); + then + mvn clean test -pl "!:avaje-http-nima-generator" + else + mvn clean test + fi From 5afad6241c0e3e0c66c994d36e32627d4087ba2d Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sat, 15 Oct 2022 12:26:16 -0400 Subject: [PATCH 0326/1323] jsonb support --- .../helidon/nima/ControllerMethodWriter.java | 22 ++++- .../helidon/nima/ControllerWriter.java | 98 +++++++++++++++---- .../generator/helidon/nima/NimaProcessor.java | 16 ++- 3 files changed, 107 insertions(+), 29 deletions(-) diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java index 1f2c51bb4..603a40b1a 100644 --- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java +++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java @@ -1,5 +1,7 @@ package io.avaje.http.generator.helidon.nima; +import java.util.Optional; + import io.avaje.http.api.MediaType; import io.avaje.http.generator.core.Append; import io.avaje.http.generator.core.MethodParam; @@ -17,12 +19,14 @@ class ControllerMethodWriter { private final Append writer; private final WebMethod webMethod; private final ProcessingContext ctx; + private final boolean useJsonB; - ControllerMethodWriter(MethodReader method, Append writer, ProcessingContext ctx) { + ControllerMethodWriter(MethodReader method, Append writer, ProcessingContext ctx, boolean useJsonB) { this.method = method; this.writer = writer; webMethod = method.getWebMethod(); this.ctx = ctx; + this.useJsonB=useJsonB; } void writeRule() { @@ -92,18 +96,28 @@ void writeHandler(boolean requestScoped) { writer.append(");").eol(); if (!method.isVoid()) { writeContextReturn(); - writer.append(" res.send(result);").eol(); + if (useJsonB && (method.getProduces() == null + || method.getProduces().toLowerCase().contains("json"))) { + + writer + .append(" %sMethodReturnJsonType.toJson(result, res.outputStream());", method.simpleName()) + .eol(); + + } else { + writer.append(" res.send(result);").eol(); + } } writer.append(" }").eol().eol(); } private void writeContextReturn() { - final var produces = method.getProduces(); + final var producesOp = Optional.ofNullable(method.getProduces()); - if (produces == null) { + if (producesOp.isEmpty() && !useJsonB) { return; } + final var produces = producesOp.orElse(MediaType.APPLICATION_JSON); final var contentTypeString = " res.headers().contentType(io.helidon.common.http.HttpMediaType."; diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java index 86119870c..d9fca32e2 100644 --- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java +++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java @@ -1,28 +1,47 @@ package io.avaje.http.generator.helidon.nima; -import io.avaje.http.generator.core.*; - import java.io.IOException; import java.util.List; +import java.util.function.Predicate; import java.util.stream.Collectors; -/** - * Write Helidon specific web route adapter (a Helidon Service). - */ +import io.avaje.http.generator.core.BaseControllerWriter; +import io.avaje.http.generator.core.Constants; +import io.avaje.http.generator.core.ControllerReader; +import io.avaje.http.generator.core.MethodReader; +import io.avaje.http.generator.core.ProcessingContext; + +/** Write Helidon specific web route adapter (a Helidon Service). */ class ControllerWriter extends BaseControllerWriter { private static final String AT_GENERATED = "@Generated(\"avaje-helidon-nima-generator\")"; + private final boolean useJsonB; + private List jsonBMethodList; - ControllerWriter(ControllerReader reader, ProcessingContext ctx) throws IOException { + ControllerWriter(ControllerReader reader, ProcessingContext ctx, boolean jsonB) + throws IOException { super(reader, ctx); - //reader.addImportType("io.helidon.common.http.FormParams"); + useJsonB = jsonB; + if (useJsonB) { + reader.addImportType("io.avaje.jsonb.Jsonb"); + reader.addImportType("io.avaje.jsonb.JsonType"); + jsonBMethodList = + reader.getMethods().stream() + .filter(MethodReader::isWebMethod) + .filter(Predicate.not(MethodReader::isVoid)) + .filter( + m -> m.getProduces() == null || m.getProduces().toLowerCase().contains("json")) + .toList(); + } + // reader.addImportType("io.helidon.common.http.FormParams"); reader.addImportType("io.helidon.nima.webserver.http.HttpRules"); reader.addImportType("io.helidon.nima.webserver.http.HttpRouting"); reader.addImportType("io.helidon.nima.webserver.http.ServerRequest"); reader.addImportType("io.helidon.nima.webserver.http.ServerResponse"); - //reader.addImportType("io.helidon.nima.webserver.Routing"); - //reader.addImportType("java.util.function.Supplier"); + // reader.addImportType("io.helidon.nima.webserver.Routing"); + // reader.addImportType("java.util.function.Supplier"); reader.addImportType("io.helidon.nima.webserver.http.HttpService"); + } void write() { @@ -35,15 +54,15 @@ void write() { private List getWriterMethods() { return reader.getMethods().stream() - .filter(MethodReader::isWebMethod) - .map(it -> new ControllerMethodWriter(it, writer, ctx)) - .collect(Collectors.toList()); + .filter(MethodReader::isWebMethod) + .map(it -> new ControllerMethodWriter(it, writer, ctx,useJsonB)) + .collect(Collectors.toList()); } private void writeAddRoutes() { - final List methods = getWriterMethods(); + final var methods = getWriterMethods(); writeRoutes(methods); - for (ControllerMethodWriter methodWriter : methods) { + for (final ControllerMethodWriter methodWriter : methods) { methodWriter.writeHandler(isRequestScoped()); } } @@ -51,44 +70,81 @@ private void writeAddRoutes() { private void writeRoutes(List methods) { writer.append(" @Override").eol(); writer.append(" public void routing(HttpRules rules) {").eol(); - //writer.append(" var rules = HttpRouting.builder();").eol(); - for (ControllerMethodWriter methodWriter : methods) { + // writer.append(" var rules = HttpRouting.builder();").eol(); + for (final ControllerMethodWriter methodWriter : methods) { methodWriter.writeRule(); if (!reader.isDocHidden()) { methodWriter.buildApiDocumentation(); } } - //writer.append(" return rules.build();").eol().eol(); + // writer.append(" return rules.build();").eol().eol(); writer.append(" }").eol().eol(); } private void writeClassStart() { writer.append(AT_GENERATED).eol(); writer.append("@Component").eol(); - writer.append("public class ").append(shortName).append("$Route implements HttpService {").eol().eol(); + writer + .append("public class ") + .append(shortName) + .append("$Route implements HttpService {") + .eol() + .eol(); - String controllerName = "controller"; - String controllerType = shortName; + var controllerName = "controller"; + var controllerType = shortName; if (isRequestScoped()) { controllerName = "factory"; controllerType += Constants.FACTORY_SUFFIX; } writer.append(" private final %s %s;", controllerType, controllerName).eol(); + if (reader.isIncludeValidator()) { writer.append(" private final Validator validator;").eol(); } + + if (useJsonB) { + writer.append(" private final Jsonb jsonB;").eol(); + jsonBMethodList.forEach( + m -> { + writer + .append( + " private final JsonType<%s> %sMethodReturnJsonType;", + m.getReturnType().toString(), + m.simpleName()) + .eol(); + }); + } + writer.eol(); writer.append(" public %s$Route(%s %s", shortName, controllerType, controllerName); if (reader.isIncludeValidator()) { writer.append(", Validator validator"); } + + if (useJsonB) { + writer.append(", Jsonb jsonB"); + } + writer.append(") {").eol(); writer.append(" this.%s = %s;", controllerName, controllerName).eol(); if (reader.isIncludeValidator()) { writer.append(" this.validator = validator;").eol(); } + + if (useJsonB) { + writer.append(" this.jsonB = jsonB;").eol(); + jsonBMethodList.forEach( + m -> { + writer + .append( + " this.%sMethodReturnJsonType = jsonB.type(%s.class);", + m.simpleName(), m.getReturnType().toString()) + .eol(); + }); + } + writer.append(" }").eol().eol(); } - } diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/NimaProcessor.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/NimaProcessor.java index c9e47b029..187c26692 100644 --- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/NimaProcessor.java +++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/NimaProcessor.java @@ -1,12 +1,12 @@ package io.avaje.http.generator.helidon.nima; +import java.io.IOException; + import io.avaje.http.generator.core.BaseProcessor; import io.avaje.http.generator.core.ControllerReader; import io.avaje.http.generator.core.PlatformAdapter; import io.avaje.http.generator.core.ProcessingContext; -import java.io.IOException; - public class NimaProcessor extends BaseProcessor { @Override @@ -15,7 +15,15 @@ protected PlatformAdapter providePlatformAdapter() { } @Override - public void writeControllerAdapter(ProcessingContext ctx, ControllerReader reader) throws IOException { - new ControllerWriter(reader, ctx).write(); + public void writeControllerAdapter(ProcessingContext ctx, ControllerReader reader) + throws IOException { + boolean jsonB; + try { + Class.forName("io.avaje.jsonb.Jsonb"); + jsonB = true; + } catch (final ClassNotFoundException e) { + jsonB = false; + } + new ControllerWriter(reader, ctx, jsonB).write(); } } From 7d840c6b7e393d6c0746c8ef7ff78c78f6644843 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sat, 15 Oct 2022 13:12:13 -0400 Subject: [PATCH 0327/1323] support byte[] --- .../helidon/nima/ControllerMethodWriter.java | 54 +++++++++++-------- .../helidon/nima/ControllerWriter.java | 29 +++++----- 2 files changed, 45 insertions(+), 38 deletions(-) diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java index 603a40b1a..196ecbc64 100644 --- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java +++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java @@ -10,9 +10,7 @@ import io.avaje.http.generator.core.ProcessingContext; import io.avaje.http.generator.core.WebMethod; -/** - * Write code to register Web route for a given controller method. - */ +/** Write code to register Web route for a given controller method. */ class ControllerMethodWriter { private final MethodReader method; @@ -21,45 +19,51 @@ class ControllerMethodWriter { private final ProcessingContext ctx; private final boolean useJsonB; - ControllerMethodWriter(MethodReader method, Append writer, ProcessingContext ctx, boolean useJsonB) { + ControllerMethodWriter( + MethodReader method, Append writer, ProcessingContext ctx, boolean useJsonB) { this.method = method; this.writer = writer; webMethod = method.getWebMethod(); this.ctx = ctx; - this.useJsonB=useJsonB; + this.useJsonB = useJsonB; } void writeRule() { final var fullPath = method.getFullPath(); -// final String bodyType = method.getBodyType(); -// if (bodyType != null) { -// writer.append(" rules.%s(\"%s\", Handler.create(%s.class, this::_%s));", webMethod.name().toLowerCase(), fullPath, bodyType, method.simpleName()).eol(); -// } else if (method.isFormBody()) { -// writer.append(" rules.%s(\"%s\", Handler.create(%s.class, this::_%s));", webMethod.name().toLowerCase(), fullPath, "FormParams", method.simpleName()).eol(); -// } else { - writer.append(" rules.%s(\"%s\", this::_%s);", webMethod.name().toLowerCase(), fullPath, method.simpleName()).eol(); -// } + // final String bodyType = method.getBodyType(); + // if (bodyType != null) { + // writer.append(" rules.%s(\"%s\", Handler.create(%s.class, this::_%s));", + // webMethod.name().toLowerCase(), fullPath, bodyType, method.simpleName()).eol(); + // } else if (method.isFormBody()) { + // writer.append(" rules.%s(\"%s\", Handler.create(%s.class, this::_%s));", + // webMethod.name().toLowerCase(), fullPath, "FormParams", method.simpleName()).eol(); + // } else { + writer + .append( + " rules.%s(\"%s\", this::_%s);", + webMethod.name().toLowerCase(), fullPath, method.simpleName()) + .eol(); + // } } void writeHandler(boolean requestScoped) { writer.append(" private void _%s(ServerRequest req, ServerResponse res", method.simpleName()); writer.append(") {").eol(); -// if (!method.isVoid()) { -// writeContextReturn(); -// } + // if (!method.isVoid()) { + // writeContextReturn(); + // } final var bodyType = method.getBodyType(); if (bodyType != null) { writer.append(" // body - %s %s", bodyType, method.getBodyName()).eol(); - }// else if (method.isFormBody()) { + } // else if (method.isFormBody()) { // writer.append(", %s %s", "FormParams", "formParams"); - //} + // } final var segments = method.getPathSegments(); if (!segments.isEmpty()) { writer.append(" var pathParams = req.path().pathParameters();").eol(); - } final var matrixSegments = segments.matrixSegments(); for (final PathSegments.Segment matrixSegment : matrixSegments) { @@ -73,7 +77,7 @@ void writeHandler(boolean requestScoped) { writer.append(" "); if (!method.isVoid()) { writer.append("var result = "); - //writer.append("res.send("); + // writer.append("res.send("); } if (method.includeValidate()) { @@ -96,11 +100,15 @@ void writeHandler(boolean requestScoped) { writer.append(");").eol(); if (!method.isVoid()) { writeContextReturn(); - if (useJsonB && (method.getProduces() == null - || method.getProduces().toLowerCase().contains("json"))) { + if (useJsonB + && !"byte[]".equals(method.getReturnType().toString()) + && (method.getProduces() == null + || method.getProduces().toLowerCase().contains("json"))) { writer - .append(" %sMethodReturnJsonType.toJson(result, res.outputStream());", method.simpleName()) + .append( + " %sMethodReturnJsonType.toJson(result, res.outputStream());", + method.simpleName()) .eol(); } else { diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java index d9fca32e2..eb3426ee5 100644 --- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java +++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java @@ -29,6 +29,7 @@ class ControllerWriter extends BaseControllerWriter { reader.getMethods().stream() .filter(MethodReader::isWebMethod) .filter(Predicate.not(MethodReader::isVoid)) + .filter(m -> !"byte[]".equals(m.getReturnType().toString())) .filter( m -> m.getProduces() == null || m.getProduces().toLowerCase().contains("json")) .toList(); @@ -41,7 +42,6 @@ class ControllerWriter extends BaseControllerWriter { // reader.addImportType("io.helidon.nima.webserver.Routing"); // reader.addImportType("java.util.function.Supplier"); reader.addImportType("io.helidon.nima.webserver.http.HttpService"); - } void write() { @@ -55,7 +55,7 @@ void write() { private List getWriterMethods() { return reader.getMethods().stream() .filter(MethodReader::isWebMethod) - .map(it -> new ControllerMethodWriter(it, writer, ctx,useJsonB)) + .map(it -> new ControllerMethodWriter(it, writer, ctx, useJsonB)) .collect(Collectors.toList()); } @@ -104,17 +104,16 @@ private void writeClassStart() { } if (useJsonB) { - writer.append(" private final Jsonb jsonB;").eol(); - jsonBMethodList.forEach( - m -> { - writer - .append( - " private final JsonType<%s> %sMethodReturnJsonType;", - m.getReturnType().toString(), - m.simpleName()) - .eol(); - }); - } + writer.append(" private final Jsonb jsonB;").eol(); + jsonBMethodList.forEach( + m -> { + writer + .append( + " private final JsonType<%s> %sMethodReturnJsonType;", + m.getReturnType().toString(), m.simpleName()) + .eol(); + }); + } writer.eol(); @@ -124,8 +123,8 @@ private void writeClassStart() { } if (useJsonB) { - writer.append(", Jsonb jsonB"); - } + writer.append(", Jsonb jsonB"); + } writer.append(") {").eol(); writer.append(" this.%s = %s;", controllerName, controllerName).eol(); From 40a8a1ad67ce243de0e10ed3350b2258909c9e85 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sat, 15 Oct 2022 15:11:37 -0400 Subject: [PATCH 0328/1323] handle collections --- .../helidon/nima/ControllerMethodWriter.java | 4 +- .../helidon/nima/ControllerWriter.java | 86 ++++++++++++++----- 2 files changed, 67 insertions(+), 23 deletions(-) diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java index 196ecbc64..3f4d348e6 100644 --- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java +++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java @@ -106,9 +106,7 @@ void writeHandler(boolean requestScoped) { || method.getProduces().toLowerCase().contains("json"))) { writer - .append( - " %sMethodReturnJsonType.toJson(result, res.outputStream());", - method.simpleName()) + .append(" res.send(%sMethodReturnJsonType.toJsonBytes(result));", method.simpleName()) .eol(); } else { diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java index eb3426ee5..6469270b6 100644 --- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java +++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java @@ -3,7 +3,8 @@ import java.io.IOException; import java.util.List; import java.util.function.Predicate; -import java.util.stream.Collectors; + +import javax.lang.model.type.DeclaredType; import io.avaje.http.generator.core.BaseControllerWriter; import io.avaje.http.generator.core.Constants; @@ -56,7 +57,7 @@ private List getWriterMethods() { return reader.getMethods().stream() .filter(MethodReader::isWebMethod) .map(it -> new ControllerMethodWriter(it, writer, ctx, useJsonB)) - .collect(Collectors.toList()); + .toList(); } private void writeAddRoutes() { @@ -104,15 +105,7 @@ private void writeClassStart() { } if (useJsonB) { - writer.append(" private final Jsonb jsonB;").eol(); - jsonBMethodList.forEach( - m -> { - writer - .append( - " private final JsonType<%s> %sMethodReturnJsonType;", - m.getReturnType().toString(), m.simpleName()) - .eol(); - }); + writeJsonBTypeFields(); } writer.eol(); @@ -133,17 +126,70 @@ private void writeClassStart() { } if (useJsonB) { - writer.append(" this.jsonB = jsonB;").eol(); - jsonBMethodList.forEach( - m -> { - writer - .append( - " this.%sMethodReturnJsonType = jsonB.type(%s.class);", - m.simpleName(), m.getReturnType().toString()) - .eol(); - }); + writeJsonBTypeAssignments(); } writer.append(" }").eol().eol(); } + + public void writeJsonBTypeFields() { + for (final MethodReader methodReader : jsonBMethodList) { + if (methodReader.getReturnType() instanceof final DeclaredType fullType) { + final var typeArgs = fullType.getTypeArguments(); + final var typeArgSize = typeArgs.size(); + + writer.append(" private final JsonType<"); + switch (typeArgSize) { + case 1 -> { + if (fullType.toString().contains("java.util.Set")) + writer.append("java.util.Set<%s>>", typeArgs.get(0)); + else writer.append("java.util.List<%s>>", typeArgs.get(0)); + } + case 2 -> writer.append("java.util.Map>", typeArgs.get(1)); + default -> writer.append("%s>", fullType); + } + writer.append(" %sMethodReturnJsonType;", methodReader.simpleName()).eol(); + } else { + throw new UnsupportedOperationException( + "Only Objects and Strings are supported with Jsonb Return Types"); + } + } + } + + public void writeJsonBTypeAssignments() { + + for (final MethodReader methodReader : jsonBMethodList) { + if (methodReader.getReturnType() instanceof final DeclaredType fullType) { + final var typeArgs = fullType.getTypeArguments(); + final var typeArgSize = typeArgs.size(); + final var jsonType = + switch (typeArgSize) { + case 1 -> typeArgs.get(0); + case 2 -> typeArgs.get(1); + default -> fullType; + }; + + writer.append( + " this.%sMethodReturnJsonType = jsonB.type(%s.class)", + methodReader.simpleName(), jsonType); + final var returnType = fullType.toString(); + if (typeArgSize != 0) { + writer.append("."); + if (returnType.contains("java.util.List")) writer.append("list"); + else if (returnType.contains("java.util.Map")) writer.append("map"); + else if (returnType.contains("java.util.Set")) writer.append("set"); + else { + throw new UnsupportedOperationException( + "Only java.util Map, Set and List are supported JsonB Controller Collection Return Types"); + } + writer.append("()"); + } + writer.append(";").eol(); + + } else { + throw new UnsupportedOperationException( + "Only Objects and Strings are supported with Jsonb Controller Return Types"); + } + } + } } From 49ecbb2397bf0a8e9eb968721e45eb315f265667 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sat, 15 Oct 2022 16:57:01 -0400 Subject: [PATCH 0329/1323] output stream --- .../http/generator/helidon/nima/ControllerMethodWriter.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java index 3f4d348e6..196ecbc64 100644 --- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java +++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java @@ -106,7 +106,9 @@ void writeHandler(boolean requestScoped) { || method.getProduces().toLowerCase().contains("json"))) { writer - .append(" res.send(%sMethodReturnJsonType.toJsonBytes(result));", method.simpleName()) + .append( + " %sMethodReturnJsonType.toJson(result, res.outputStream());", + method.simpleName()) .eol(); } else { From 429987b1b058192659d2f73e7618ed09024729a4 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sat, 15 Oct 2022 16:58:38 -0400 Subject: [PATCH 0330/1323] can deserialize body --- .../helidon/nima/ControllerMethodWriter.java | 10 +++- .../helidon/nima/ControllerWriter.java | 60 +++++++++++++++++-- 2 files changed, 63 insertions(+), 7 deletions(-) diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java index 196ecbc64..7a20ed054 100644 --- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java +++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java @@ -56,7 +56,15 @@ void writeHandler(boolean requestScoped) { final var bodyType = method.getBodyType(); if (bodyType != null) { - writer.append(" // body - %s %s", bodyType, method.getBodyName()).eol(); + if (useJsonB) { + + writer + .append( + " var %s = %sMethodBodyJsonType.fromJson(req.content().inputStream());", + method.getBodyName(), method.simpleName()) + .eol(); + + } else writer.append(" // body - %s %s", bodyType, method.getBodyName()).eol(); } // else if (method.isFormBody()) { // writer.append(", %s %s", "FormParams", "formParams"); // } diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java index 6469270b6..53d02ca27 100644 --- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java +++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java @@ -2,6 +2,7 @@ import java.io.IOException; import java.util.List; +import java.util.Optional; import java.util.function.Predicate; import javax.lang.model.type.DeclaredType; @@ -9,6 +10,7 @@ import io.avaje.http.generator.core.BaseControllerWriter; import io.avaje.http.generator.core.Constants; import io.avaje.http.generator.core.ControllerReader; +import io.avaje.http.generator.core.MethodParam; import io.avaje.http.generator.core.MethodReader; import io.avaje.http.generator.core.ProcessingContext; @@ -134,6 +136,20 @@ private void writeClassStart() { public void writeJsonBTypeFields() { for (final MethodReader methodReader : jsonBMethodList) { + // body types + if (methodReader.getBodyType() != null) { + methodReader.getParams().stream() + .filter(MethodParam::isBody) + .forEach( + param -> { + writer + .append( + " private final JsonType<%s> %sMethodBodyJsonType;", + param.getUType().full(), methodReader.simpleName()) + .eol(); + }); + } + // return types if (methodReader.getReturnType() instanceof final DeclaredType fullType) { final var typeArgs = fullType.getTypeArguments(); final var typeArgSize = typeArgs.size(); @@ -151,7 +167,7 @@ public void writeJsonBTypeFields() { writer.append(" %sMethodReturnJsonType;", methodReader.simpleName()).eol(); } else { throw new UnsupportedOperationException( - "Only Objects and Strings are supported with Jsonb Return Types"); + "Only Objects are supported with Jsonb Return Types"); } } } @@ -159,6 +175,36 @@ public void writeJsonBTypeFields() { public void writeJsonBTypeAssignments() { for (final MethodReader methodReader : jsonBMethodList) { + // body types + if (methodReader.getBodyType() != null) { + methodReader.getParams().stream() + .filter(MethodParam::isBody) + .forEach( + p -> { + final var type = p.getUType(); + final var jsonType = + Optional.ofNullable(type.param1()) + .or(() -> Optional.ofNullable(type.param0())) + .orElseGet(type::full); + writer.append( + " this.%sMethodBodyJsonType = jsonB.type(%s.class)", + methodReader.simpleName(), jsonType); + + if (type.param0() != null) { + writer.append("."); + switch (type.mainType()) { + case "java.util.List" -> writer.append("list"); + case "java.util.Map" -> writer.append("map"); + case "java.util.Set" -> writer.append("set"); + default -> throw new UnsupportedOperationException( + "Only java.util Map, Set and List are supported JsonB Controller Body Return Types"); + } + writer.append("()"); + } + writer.append(";").eol(); + }); + } + // return types if (methodReader.getReturnType() instanceof final DeclaredType fullType) { final var typeArgs = fullType.getTypeArguments(); final var typeArgSize = typeArgs.size(); @@ -175,13 +221,15 @@ public void writeJsonBTypeAssignments() { final var returnType = fullType.toString(); if (typeArgSize != 0) { writer.append("."); - if (returnType.contains("java.util.List")) writer.append("list"); - else if (returnType.contains("java.util.Map")) writer.append("map"); - else if (returnType.contains("java.util.Set")) writer.append("set"); - else { - throw new UnsupportedOperationException( + + switch (returnType.substring(0, 13)) { + case "java.util.Lis" -> writer.append("list"); + case "java.util.Map" -> writer.append("map"); + case "java.util.Set" -> writer.append("set"); + default -> throw new UnsupportedOperationException( "Only java.util Map, Set and List are supported JsonB Controller Collection Return Types"); } + writer.append("()"); } writer.append(";").eol(); From 4e13e20289badc85c5ec95397e3f49ed9a0127cb Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sat, 15 Oct 2022 17:27:46 -0400 Subject: [PATCH 0331/1323] add default helidon deserialization --- .../helidon/nima/ControllerMethodWriter.java | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java index 7a20ed054..c60d670e0 100644 --- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java +++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java @@ -64,7 +64,24 @@ void writeHandler(boolean requestScoped) { method.getBodyName(), method.simpleName()) .eol(); - } else writer.append(" // body - %s %s", bodyType, method.getBodyName()).eol(); + } else { + // use default helidon content negotiation + method.getParams().stream() + .filter(MethodParam::isBody) + .forEach( + param -> { + final var type = param.getUType(); + writer.append(" var %s = req.content().as(", method.getBodyName()); + + if (type.param0() != null) { + writer.append("new io.helidon.common.GenericType<%s>() {}", type.full()); + } else { + writer.append("%s.class", type.full()); + } + + writer.append(");").eol(); + }); + } } // else if (method.isFormBody()) { // writer.append(", %s %s", "FormParams", "formParams"); // } From 952604eba21d81daa9c9ecaf28dac812377911fa Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sat, 15 Oct 2022 17:44:48 -0400 Subject: [PATCH 0332/1323] default jsonB --- .gitignore | 4 ++++ .../avaje/http/generator/helidon/nima/ControllerWriter.java | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index a8b2ebbcb..be9939a77 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,7 @@ http-generator-nima/.settings/org.eclipse.jdt.apt.core.prefs http-generator-nima/.settings/org.eclipse.core.resources.prefs http-generator-nima/.project http-generator-nima/.classpath +*.prefs +tests/test-nima/.classpath +tests/test-nima/.factorypath +tests/test-nima/.project diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java index 53d02ca27..47a9a9464 100644 --- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java +++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java @@ -118,7 +118,7 @@ private void writeClassStart() { } if (useJsonB) { - writer.append(", Jsonb jsonB"); + writer.append(", Optional jsonbOp"); } writer.append(") {").eol(); @@ -173,7 +173,7 @@ public void writeJsonBTypeFields() { } public void writeJsonBTypeAssignments() { - + writer.append(" final var jsonB = jsonbOp.orElseGet(()->Jsonb.builder().build())").eol(); for (final MethodReader methodReader : jsonBMethodList) { // body types if (methodReader.getBodyType() != null) { From 03dc61bb0fb909d1964f9e3a4410c5e7e105122a Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sat, 15 Oct 2022 17:45:02 -0400 Subject: [PATCH 0333/1323] nima jsonb tests --- .../helidon/nima/ControllerWriter.java | 2 +- tests/test-nima-jsonb/.classpath | 44 ++++++++ tests/test-nima-jsonb/.factorypath | 15 +++ tests/test-nima-jsonb/.project | 23 ++++ tests/test-nima-jsonb/pom.xml | 102 ++++++++++++++++++ .../java/org/example/HelloController.java | 21 ++++ .../src/main/java/org/example/Main.java | 31 ++++++ .../src/main/java/org/example/Person.java | 23 ++++ .../src/main/java/org/example/Main.java | 34 ++---- 9 files changed, 267 insertions(+), 28 deletions(-) create mode 100644 tests/test-nima-jsonb/.classpath create mode 100644 tests/test-nima-jsonb/.factorypath create mode 100644 tests/test-nima-jsonb/.project create mode 100644 tests/test-nima-jsonb/pom.xml create mode 100644 tests/test-nima-jsonb/src/main/java/org/example/HelloController.java create mode 100644 tests/test-nima-jsonb/src/main/java/org/example/Main.java create mode 100644 tests/test-nima-jsonb/src/main/java/org/example/Person.java diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java index 47a9a9464..77df9f7c2 100644 --- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java +++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java @@ -173,7 +173,7 @@ public void writeJsonBTypeFields() { } public void writeJsonBTypeAssignments() { - writer.append(" final var jsonB = jsonbOp.orElseGet(()->Jsonb.builder().build())").eol(); + writer.append(" final var jsonB = jsonbOp.orElseGet(()->Jsonb.builder().build());").eol(); for (final MethodReader methodReader : jsonBMethodList) { // body types if (methodReader.getBodyType() != null) { diff --git a/tests/test-nima-jsonb/.classpath b/tests/test-nima-jsonb/.classpath new file mode 100644 index 000000000..aeb867648 --- /dev/null +++ b/tests/test-nima-jsonb/.classpath @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/test-nima-jsonb/.factorypath b/tests/test-nima-jsonb/.factorypath new file mode 100644 index 000000000..2ec5a1739 --- /dev/null +++ b/tests/test-nima-jsonb/.factorypath @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/tests/test-nima-jsonb/.project b/tests/test-nima-jsonb/.project new file mode 100644 index 000000000..14b9f0648 --- /dev/null +++ b/tests/test-nima-jsonb/.project @@ -0,0 +1,23 @@ + + + test-nima + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.jdt.core.javanature + org.eclipse.m2e.core.maven2Nature + + diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml new file mode 100644 index 000000000..7270b4870 --- /dev/null +++ b/tests/test-nima-jsonb/pom.xml @@ -0,0 +1,102 @@ + + + 4.0.0 + + avaje-http-generator-parent + io.avaje + 1.18-SNAPSHOT + ../../pom.xml + + + test-nima-jsonb + 1 + + + 19 + 19 + UTF-8 + + + + + + io.avaje + avaje-inject + 8.9 + + + io.avaje + avaje-http-api + 1.18-SNAPSHOT + + + io.avaje + avaje-jsonb + 1.0-RC2 + + + io.helidon.nima.webserver + helidon-nima-webserver + 4.0.0-ALPHA1 + + + io.helidon.nima.http.media + helidon-nima-http-media-jsonb + 4.0.0-ALPHA1 + + + + + + + + + + + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.10.1 + + 19 + + + io.avaje + avaje-http-nima-generator + 1.18-SNAPSHOT + + + io.avaje + avaje-inject-generator + 8.9 + + + io.avaje + avaje-jsonb-generator + 1.0-RC2 + + + + + + io.repaint.maven + tiles-maven-plugin + 2.22 + true + + + org.avaje.tile:lib-classpath:1.1 + + + + + + + + diff --git a/tests/test-nima-jsonb/src/main/java/org/example/HelloController.java b/tests/test-nima-jsonb/src/main/java/org/example/HelloController.java new file mode 100644 index 000000000..fbff3ec17 --- /dev/null +++ b/tests/test-nima-jsonb/src/main/java/org/example/HelloController.java @@ -0,0 +1,21 @@ +package org.example; + +import io.avaje.http.api.Controller; +import io.avaje.http.api.Get; + +@Controller +public class HelloController { + + @Get("hello") + String helloWorld() { + return "Hello world"; + } + + @Get("person/{name}/{sortBy}") + Person person(String name, String sortBy) { + var p = new Person(); + p.setId(42); + p.setName(name + " hello" + " sortBy:" + sortBy); + return p; + } +} diff --git a/tests/test-nima-jsonb/src/main/java/org/example/Main.java b/tests/test-nima-jsonb/src/main/java/org/example/Main.java new file mode 100644 index 000000000..4ec2d7148 --- /dev/null +++ b/tests/test-nima-jsonb/src/main/java/org/example/Main.java @@ -0,0 +1,31 @@ +package org.example; + +import java.util.List; + +import io.avaje.inject.BeanScope; +import io.helidon.nima.webserver.WebServer; +import io.helidon.nima.webserver.http.HttpRouting; +import io.helidon.nima.webserver.http.HttpService; + +public class Main { + + public static void main(String[] args) { + + final var scope = BeanScope.builder().build(); + final List list = scope.list(HttpService.class); + final var builder = HttpRouting.builder(); + for (final HttpService httpService : list) { + httpService.routing(builder); + } + final var httpRouting = builder.build(); + + + WebServer.builder() + .addRouting(httpRouting) + //.routing(Main::routing) + .port(8081) + .start(); + + System.out.println("started"); + } +} diff --git a/tests/test-nima-jsonb/src/main/java/org/example/Person.java b/tests/test-nima-jsonb/src/main/java/org/example/Person.java new file mode 100644 index 000000000..4959f219e --- /dev/null +++ b/tests/test-nima-jsonb/src/main/java/org/example/Person.java @@ -0,0 +1,23 @@ +package org.example; + +public class Person { + + long id; + String name; + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/tests/test-nima/src/main/java/org/example/Main.java b/tests/test-nima/src/main/java/org/example/Main.java index c1711a8b7..4ec2d7148 100644 --- a/tests/test-nima/src/main/java/org/example/Main.java +++ b/tests/test-nima/src/main/java/org/example/Main.java @@ -1,24 +1,23 @@ package org.example; +import java.util.List; + import io.avaje.inject.BeanScope; -import io.helidon.nima.webserver.Routing; import io.helidon.nima.webserver.WebServer; import io.helidon.nima.webserver.http.HttpRouting; import io.helidon.nima.webserver.http.HttpService; -import java.util.List; - public class Main { public static void main(String[] args) { - BeanScope scope = BeanScope.builder().build(); - List list = scope.list(HttpService.class); - HttpRouting.Builder builder = HttpRouting.builder(); - for (HttpService httpService : list) { + final var scope = BeanScope.builder().build(); + final List list = scope.list(HttpService.class); + final var builder = HttpRouting.builder(); + for (final HttpService httpService : list) { httpService.routing(builder); } - HttpRouting httpRouting = builder.build(); + final var httpRouting = builder.build(); WebServer.builder() @@ -29,23 +28,4 @@ public static void main(String[] args) { System.out.println("started"); } - - private static Routing routing(HttpRouting.Builder route) { - return route - .get("/", (req, res) -> { - res.send("hello world"); - }) - .get("/hi", (req, res) -> { - res.header("my-header", "hi-header"); - //res.send("hi!!"); - - var p = new Person(); - p.setId(42); - p.setName("asdasd"); - - // - res.send(p); - }) - .build(); - } } From 2989f894183187d9a43d88047d6ef17a4d5aba9b Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sat, 15 Oct 2022 17:58:25 -0400 Subject: [PATCH 0334/1323] fix default jsonb --- .../avaje/http/generator/helidon/nima/ControllerWriter.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java index 77df9f7c2..a4f7c7506 100644 --- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java +++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java @@ -28,6 +28,7 @@ class ControllerWriter extends BaseControllerWriter { if (useJsonB) { reader.addImportType("io.avaje.jsonb.Jsonb"); reader.addImportType("io.avaje.jsonb.JsonType"); + reader.addImportType("java.util.Optional"); jsonBMethodList = reader.getMethods().stream() .filter(MethodReader::isWebMethod) @@ -45,6 +46,7 @@ class ControllerWriter extends BaseControllerWriter { // reader.addImportType("io.helidon.nima.webserver.Routing"); // reader.addImportType("java.util.function.Supplier"); reader.addImportType("io.helidon.nima.webserver.http.HttpService"); + reader.addImportType("jakarta.inject.Inject"); } void write() { @@ -71,6 +73,7 @@ private void writeAddRoutes() { } private void writeRoutes(List methods) { + writer.append(" @Override").eol(); writer.append(" public void routing(HttpRules rules) {").eol(); // writer.append(" var rules = HttpRouting.builder();").eol(); @@ -112,6 +115,7 @@ private void writeClassStart() { writer.eol(); + writer.append(" @Inject").eol(); writer.append(" public %s$Route(%s %s", shortName, controllerType, controllerName); if (reader.isIncludeValidator()) { writer.append(", Validator validator"); From 45e7a728e309f4a1813f1ae8926f21ead0e56d6f Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sat, 15 Oct 2022 18:33:28 -0400 Subject: [PATCH 0335/1323] Revert "default jsonB" --- .../http/generator/helidon/nima/ControllerWriter.java | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java index a4f7c7506..53d02ca27 100644 --- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java +++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java @@ -28,7 +28,6 @@ class ControllerWriter extends BaseControllerWriter { if (useJsonB) { reader.addImportType("io.avaje.jsonb.Jsonb"); reader.addImportType("io.avaje.jsonb.JsonType"); - reader.addImportType("java.util.Optional"); jsonBMethodList = reader.getMethods().stream() .filter(MethodReader::isWebMethod) @@ -46,7 +45,6 @@ class ControllerWriter extends BaseControllerWriter { // reader.addImportType("io.helidon.nima.webserver.Routing"); // reader.addImportType("java.util.function.Supplier"); reader.addImportType("io.helidon.nima.webserver.http.HttpService"); - reader.addImportType("jakarta.inject.Inject"); } void write() { @@ -73,7 +71,6 @@ private void writeAddRoutes() { } private void writeRoutes(List methods) { - writer.append(" @Override").eol(); writer.append(" public void routing(HttpRules rules) {").eol(); // writer.append(" var rules = HttpRouting.builder();").eol(); @@ -115,14 +112,13 @@ private void writeClassStart() { writer.eol(); - writer.append(" @Inject").eol(); writer.append(" public %s$Route(%s %s", shortName, controllerType, controllerName); if (reader.isIncludeValidator()) { writer.append(", Validator validator"); } if (useJsonB) { - writer.append(", Optional jsonbOp"); + writer.append(", Jsonb jsonB"); } writer.append(") {").eol(); @@ -177,7 +173,7 @@ public void writeJsonBTypeFields() { } public void writeJsonBTypeAssignments() { - writer.append(" final var jsonB = jsonbOp.orElseGet(()->Jsonb.builder().build());").eol(); + for (final MethodReader methodReader : jsonBMethodList) { // body types if (methodReader.getBodyType() != null) { From 46095c730f3bac00ac3aabc43c3d68ee10057889 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sat, 15 Oct 2022 19:43:53 -0400 Subject: [PATCH 0336/1323] enabled jsonb nima test --- .gitignore | 1 + tests/pom.xml | 2 +- tests/test-nima-jsonb/.factorypath | 2 ++ .../src/main/java/org/example/JsonBFactory.java | 13 +++++++++++++ .../src/main/java/org/example/Main.java | 12 ++++++------ 5 files changed, 23 insertions(+), 7 deletions(-) create mode 100644 tests/test-nima-jsonb/src/main/java/org/example/JsonBFactory.java diff --git a/.gitignore b/.gitignore index be9939a77..17da7ad09 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,4 @@ http-generator-nima/.classpath tests/test-nima/.classpath tests/test-nima/.factorypath tests/test-nima/.project +*.class diff --git a/tests/pom.xml b/tests/pom.xml index 99792e459..e01034c90 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -26,9 +26,9 @@ test-nima + test-nima-jsonb - diff --git a/tests/test-nima-jsonb/.factorypath b/tests/test-nima-jsonb/.factorypath index 2ec5a1739..c135caf74 100644 --- a/tests/test-nima-jsonb/.factorypath +++ b/tests/test-nima-jsonb/.factorypath @@ -12,4 +12,6 @@ + + diff --git a/tests/test-nima-jsonb/src/main/java/org/example/JsonBFactory.java b/tests/test-nima-jsonb/src/main/java/org/example/JsonBFactory.java new file mode 100644 index 000000000..7e535e68a --- /dev/null +++ b/tests/test-nima-jsonb/src/main/java/org/example/JsonBFactory.java @@ -0,0 +1,13 @@ +package org.example; + +import io.avaje.inject.Bean; +import io.avaje.inject.Factory; +import io.avaje.jsonb.Jsonb; + +@Factory +public class JsonBFactory { + @Bean + Jsonb jsonB() { + return Jsonb.builder().failOnUnknown(false).build(); + } +} diff --git a/tests/test-nima-jsonb/src/main/java/org/example/Main.java b/tests/test-nima-jsonb/src/main/java/org/example/Main.java index 4ec2d7148..07d52bcdf 100644 --- a/tests/test-nima-jsonb/src/main/java/org/example/Main.java +++ b/tests/test-nima-jsonb/src/main/java/org/example/Main.java @@ -3,6 +3,7 @@ import java.util.List; import io.avaje.inject.BeanScope; +import io.avaje.jsonb.Jsonb; import io.helidon.nima.webserver.WebServer; import io.helidon.nima.webserver.http.HttpRouting; import io.helidon.nima.webserver.http.HttpService; @@ -11,7 +12,7 @@ public class Main { public static void main(String[] args) { - final var scope = BeanScope.builder().build(); + final var scope = BeanScope.builder().beans(Jsonb.builder().build()).build(); final List list = scope.list(HttpService.class); final var builder = HttpRouting.builder(); for (final HttpService httpService : list) { @@ -19,12 +20,11 @@ public static void main(String[] args) { } final var httpRouting = builder.build(); - WebServer.builder() - .addRouting(httpRouting) - //.routing(Main::routing) - .port(8081) - .start(); + .addRouting(httpRouting) + // .routing(Main::routing) + .port(8081) + .start(); System.out.println("started"); } From d058f8849c25c57caefe981b6bd7c76eb9a5658a Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sat, 15 Oct 2022 20:02:44 -0400 Subject: [PATCH 0337/1323] breakup jsonb method --- .../helidon/nima/ControllerMethodWriter.java | 4 +- .../helidon/nima/ControllerWriter.java | 141 +++++++++--------- 2 files changed, 75 insertions(+), 70 deletions(-) diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java index c60d670e0..b12d51f4a 100644 --- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java +++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java @@ -102,7 +102,6 @@ void writeHandler(boolean requestScoped) { writer.append(" "); if (!method.isVoid()) { writer.append("var result = "); - // writer.append("res.send("); } if (method.includeValidate()) { @@ -132,8 +131,7 @@ void writeHandler(boolean requestScoped) { writer .append( - " %sMethodReturnJsonType.toJson(result, res.outputStream());", - method.simpleName()) + " %sReturnedJsonType.toJson(result, res.outputStream());", method.simpleName()) .eol(); } else { diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java index 53d02ca27..eb02371ca 100644 --- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java +++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java @@ -73,14 +73,13 @@ private void writeAddRoutes() { private void writeRoutes(List methods) { writer.append(" @Override").eol(); writer.append(" public void routing(HttpRules rules) {").eol(); - // writer.append(" var rules = HttpRouting.builder();").eol(); + for (final ControllerMethodWriter methodWriter : methods) { methodWriter.writeRule(); if (!reader.isDocHidden()) { methodWriter.buildApiDocumentation(); } } - // writer.append(" return rules.build();").eol().eol(); writer.append(" }").eol().eol(); } @@ -141,13 +140,12 @@ public void writeJsonBTypeFields() { methodReader.getParams().stream() .filter(MethodParam::isBody) .forEach( - param -> { - writer - .append( - " private final JsonType<%s> %sMethodBodyJsonType;", - param.getUType().full(), methodReader.simpleName()) - .eol(); - }); + param -> + writer + .append( + " private final JsonType<%s> %sMethodBodyJsonType;", + param.getUType().full(), methodReader.simpleName()) + .eol()); } // return types if (methodReader.getReturnType() instanceof final DeclaredType fullType) { @@ -164,7 +162,7 @@ public void writeJsonBTypeFields() { case 2 -> writer.append("java.util.Map>", typeArgs.get(1)); default -> writer.append("%s>", fullType); } - writer.append(" %sMethodReturnJsonType;", methodReader.simpleName()).eol(); + writer.append(" %sReturnedJsonType;", methodReader.simpleName()).eol(); } else { throw new UnsupportedOperationException( "Only Objects are supported with Jsonb Return Types"); @@ -176,68 +174,77 @@ public void writeJsonBTypeAssignments() { for (final MethodReader methodReader : jsonBMethodList) { // body types - if (methodReader.getBodyType() != null) { - methodReader.getParams().stream() - .filter(MethodParam::isBody) - .forEach( - p -> { - final var type = p.getUType(); - final var jsonType = - Optional.ofNullable(type.param1()) - .or(() -> Optional.ofNullable(type.param0())) - .orElseGet(type::full); - writer.append( - " this.%sMethodBodyJsonType = jsonB.type(%s.class)", - methodReader.simpleName(), jsonType); - - if (type.param0() != null) { - writer.append("."); - switch (type.mainType()) { - case "java.util.List" -> writer.append("list"); - case "java.util.Map" -> writer.append("map"); - case "java.util.Set" -> writer.append("set"); - default -> throw new UnsupportedOperationException( - "Only java.util Map, Set and List are supported JsonB Controller Body Return Types"); - } - writer.append("()"); + writeBodyJsonType(methodReader); + writeReturnJsonType(methodReader); + } + } + + private void writeBodyJsonType(MethodReader methodReader) { + + if (methodReader.getBodyType() != null) { + methodReader.getParams().stream() + .filter(MethodParam::isBody) + .forEach( + p -> { + final var type = p.getUType(); + final var jsonType = + Optional.ofNullable(type.param1()) + .or(() -> Optional.ofNullable(type.param0())) + .orElseGet(type::full); + writer.append( + " this.%sMethodBodyJsonType = jsonB.type(%s.class)", + methodReader.simpleName(), jsonType); + + if (type.param0() != null) { + writer.append("."); + switch (type.mainType()) { + case "java.util.List" -> writer.append("list"); + case "java.util.Map" -> writer.append("map"); + case "java.util.Set" -> writer.append("set"); + default -> throw new UnsupportedOperationException( + "Only java.util Map, Set and List are supported JsonB Controller Body Return Types"); } - writer.append(";").eol(); - }); - } - // return types - if (methodReader.getReturnType() instanceof final DeclaredType fullType) { - final var typeArgs = fullType.getTypeArguments(); - final var typeArgSize = typeArgs.size(); - final var jsonType = - switch (typeArgSize) { - case 1 -> typeArgs.get(0); - case 2 -> typeArgs.get(1); - default -> fullType; - }; - - writer.append( - " this.%sMethodReturnJsonType = jsonB.type(%s.class)", - methodReader.simpleName(), jsonType); - final var returnType = fullType.toString(); - if (typeArgSize != 0) { - writer.append("."); - - switch (returnType.substring(0, 13)) { - case "java.util.Lis" -> writer.append("list"); - case "java.util.Map" -> writer.append("map"); - case "java.util.Set" -> writer.append("set"); - default -> throw new UnsupportedOperationException( - "Only java.util Map, Set and List are supported JsonB Controller Collection Return Types"); - } + writer.append("()"); + } + writer.append(";").eol(); + }); + } + } - writer.append("()"); + void writeReturnJsonType(MethodReader methodReader) { + + if (methodReader.getReturnType() instanceof final DeclaredType fullType) { + final var typeArgs = fullType.getTypeArguments(); + final var typeArgSize = typeArgs.size(); + final var jsonType = + switch (typeArgSize) { + case 1 -> typeArgs.get(0); + case 2 -> typeArgs.get(1); + default -> fullType; + }; + + writer.append( + " this.%sReturnedJsonType = jsonB.type(%s.class)", + methodReader.simpleName(), jsonType); + final var returnType = fullType.toString(); + if (typeArgSize != 0) { + writer.append("."); + + switch (returnType.substring(0, 13)) { + case "java.util.Lis" -> writer.append("list"); + case "java.util.Map" -> writer.append("map"); + case "java.util.Set" -> writer.append("set"); + default -> throw new UnsupportedOperationException( + "Only java.util Map, Set and List are supported JsonB Controller Collection Return Types"); } - writer.append(";").eol(); - } else { - throw new UnsupportedOperationException( - "Only Objects and Strings are supported with Jsonb Controller Return Types"); + writer.append("()"); } + writer.append(";").eol(); + + } else { + throw new UnsupportedOperationException( + "Only Objects and Strings are supported with Jsonb Controller Return Types"); } } } From 43208307264cc29627b9584aef93589b00996f56 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sat, 15 Oct 2022 20:06:09 -0400 Subject: [PATCH 0338/1323] rename body Json Type --- .../http/generator/helidon/nima/ControllerMethodWriter.java | 2 +- .../avaje/http/generator/helidon/nima/ControllerWriter.java | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java index b12d51f4a..d90a2177c 100644 --- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java +++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java @@ -60,7 +60,7 @@ void writeHandler(boolean requestScoped) { writer .append( - " var %s = %sMethodBodyJsonType.fromJson(req.content().inputStream());", + " var %s = %sBodyJsonType.fromJson(req.content().inputStream());", method.getBodyName(), method.simpleName()) .eol(); diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java index eb02371ca..e86ba12b7 100644 --- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java +++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java @@ -42,8 +42,6 @@ class ControllerWriter extends BaseControllerWriter { reader.addImportType("io.helidon.nima.webserver.http.HttpRouting"); reader.addImportType("io.helidon.nima.webserver.http.ServerRequest"); reader.addImportType("io.helidon.nima.webserver.http.ServerResponse"); - // reader.addImportType("io.helidon.nima.webserver.Routing"); - // reader.addImportType("java.util.function.Supplier"); reader.addImportType("io.helidon.nima.webserver.http.HttpService"); } @@ -192,7 +190,7 @@ private void writeBodyJsonType(MethodReader methodReader) { .or(() -> Optional.ofNullable(type.param0())) .orElseGet(type::full); writer.append( - " this.%sMethodBodyJsonType = jsonB.type(%s.class)", + " this.%sBodyJsonType = jsonB.type(%s.class)", methodReader.simpleName(), jsonType); if (type.param0() != null) { From ef8bae4810f52ede5db33a6189f0e14e81051a32 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sat, 15 Oct 2022 20:35:48 -0400 Subject: [PATCH 0339/1323] test compilation --- .../generator/helidon/nima/NimaProcessor.java | 23 ++- tests/test-nima-jsonb/pom.xml | 189 +++++++++--------- .../http/generator/NimaProcessorTest.java | 79 ++++++++ 3 files changed, 192 insertions(+), 99 deletions(-) create mode 100644 tests/test-nima-jsonb/src/test/java/io/avaje/http/generator/NimaProcessorTest.java diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/NimaProcessor.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/NimaProcessor.java index 187c26692..9162bec26 100644 --- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/NimaProcessor.java +++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/NimaProcessor.java @@ -9,6 +9,21 @@ public class NimaProcessor extends BaseProcessor { + boolean jsonB; + + public NimaProcessor() { + try { + Class.forName("io.avaje.jsonb.Jsonb"); + jsonB = true; + } catch (final ClassNotFoundException e) { + jsonB = false; + } + } + + public NimaProcessor(boolean b) { + jsonB = b; + } + @Override protected PlatformAdapter providePlatformAdapter() { return new NimaPlatformAdapter(); @@ -17,13 +32,7 @@ protected PlatformAdapter providePlatformAdapter() { @Override public void writeControllerAdapter(ProcessingContext ctx, ControllerReader reader) throws IOException { - boolean jsonB; - try { - Class.forName("io.avaje.jsonb.Jsonb"); - jsonB = true; - } catch (final ClassNotFoundException e) { - jsonB = false; - } + new ControllerWriter(reader, ctx, jsonB).write(); } } diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 7270b4870..015e45ad8 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -1,102 +1,107 @@ - 4.0.0 - - avaje-http-generator-parent - io.avaje - 1.18-SNAPSHOT - ../../pom.xml - + 4.0.0 + + avaje-http-generator-parent + io.avaje + 1.18-SNAPSHOT + ../../pom.xml + - test-nima-jsonb - 1 + test-nima-jsonb + 1 - - 19 - 19 - UTF-8 - + + 19 + 19 + UTF-8 + - - - io.avaje - avaje-inject - 8.9 - - - io.avaje - avaje-http-api - 1.18-SNAPSHOT - - - io.avaje - avaje-jsonb - 1.0-RC2 - - - io.helidon.nima.webserver - helidon-nima-webserver - 4.0.0-ALPHA1 - - - io.helidon.nima.http.media - helidon-nima-http-media-jsonb - 4.0.0-ALPHA1 - + + + io.avaje + avaje-inject + 8.9 + + + io.avaje + avaje-http-api + 1.18-SNAPSHOT + + + io.avaje + avaje-jsonb + 1.0-RC2 + + + io.helidon.nima.webserver + helidon-nima-webserver + 4.0.0-ALPHA2 + + + io.helidon.nima.http.media + helidon-nima-http-media-jsonb + 4.0.0-ALPHA2 + + + io.avaje + avaje-http-nima-generator + 1.18-SNAPSHOT + test + + + + + + + + + + + + - - - - - - - - - - - - - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.10.1 - - 19 - - - io.avaje - avaje-http-nima-generator - 1.18-SNAPSHOT - - - io.avaje - avaje-inject-generator - 8.9 - - - io.avaje - avaje-jsonb-generator - 1.0-RC2 - - - - - - io.repaint.maven - tiles-maven-plugin - 2.22 - true - - - org.avaje.tile:lib-classpath:1.1 - - - - - + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.10.1 + + 19 + + + io.avaje + avaje-http-nima-generator + 1.18-SNAPSHOT + + + io.avaje + avaje-inject-generator + 8.9 + + + io.avaje + avaje-jsonb-generator + 1.0-RC2 + + + + + + io.repaint.maven + tiles-maven-plugin + 2.22 + true + + + org.avaje.tile:lib-classpath:1.1 + + + + + diff --git a/tests/test-nima-jsonb/src/test/java/io/avaje/http/generator/NimaProcessorTest.java b/tests/test-nima-jsonb/src/test/java/io/avaje/http/generator/NimaProcessorTest.java new file mode 100644 index 000000000..de8967ad6 --- /dev/null +++ b/tests/test-nima-jsonb/src/test/java/io/avaje/http/generator/NimaProcessorTest.java @@ -0,0 +1,79 @@ +package io.avaje.http.generator; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.io.File; +import java.io.IOException; +import java.io.PrintWriter; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +import java.util.Set; + +import javax.tools.JavaFileObject; +import javax.tools.JavaFileObject.Kind; +import javax.tools.StandardLocation; +import javax.tools.ToolProvider; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; + +import io.avaje.http.generator.helidon.nima.NimaProcessor; + +class NimaProcessorTest { + + @AfterEach + void deleteGeneratedFiles() throws IOException { + + Paths.get("openapi.json").toAbsolutePath().toFile().delete(); + Files.walk(Paths.get("org").toAbsolutePath()) + .sorted(Comparator.reverseOrder()) + .map(Path::toFile) + .forEach(File::delete); + } + + @Test + void runAnnotationProcessor() throws Exception { + final var source = Paths.get("src").toAbsolutePath().toString(); + + final var files = getSourceFiles(source); + + final var compiler = ToolProvider.getSystemJavaCompiler(); + + final var task = + compiler.getTask( + new PrintWriter(System.out), null, null, List.of("--release=19"), null, files); + task.setProcessors(List.of(new NimaProcessor(false))); + + assertThat(task.call()).isTrue(); + } + + @Test + void runAnnotationProcessorWithJsonB() throws Exception { + final var source = Paths.get("src").toAbsolutePath().toString(); + + final var files = getSourceFiles(source); + + final var compiler = ToolProvider.getSystemJavaCompiler(); + + final var task = + compiler.getTask( + new PrintWriter(System.out), null, null, List.of("--release=19"), null, files); + task.setProcessors(List.of(new NimaProcessor())); + + assertThat(task.call()).isTrue(); + } + + private Iterable getSourceFiles(String source) throws Exception { + final var compiler = ToolProvider.getSystemJavaCompiler(); + final var files = compiler.getStandardFileManager(null, null, null); + + files.setLocation(StandardLocation.SOURCE_PATH, List.of(new File(source))); + + final Set fileKinds = Collections.singleton(Kind.SOURCE); + return files.list(StandardLocation.SOURCE_PATH, "", fileKinds, true); + } +} From 70ffe31fa9ca3bcfadff2cec617a474dfae59ae9 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sat, 15 Oct 2022 20:53:55 -0400 Subject: [PATCH 0340/1323] add bytes test --- .../helidon/nima/ControllerWriter.java | 2 +- .../main/java/org/example/HelloController.java | 17 ++++++++++++++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java index e86ba12b7..77632c59f 100644 --- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java +++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java @@ -141,7 +141,7 @@ public void writeJsonBTypeFields() { param -> writer .append( - " private final JsonType<%s> %sMethodBodyJsonType;", + " private final JsonType<%s> %sBodyJsonType;", param.getUType().full(), methodReader.simpleName()) .eol()); } diff --git a/tests/test-nima-jsonb/src/main/java/org/example/HelloController.java b/tests/test-nima-jsonb/src/main/java/org/example/HelloController.java index fbff3ec17..83d2555a8 100644 --- a/tests/test-nima-jsonb/src/main/java/org/example/HelloController.java +++ b/tests/test-nima-jsonb/src/main/java/org/example/HelloController.java @@ -2,10 +2,19 @@ import io.avaje.http.api.Controller; import io.avaje.http.api.Get; +import io.avaje.http.api.Post; +import io.avaje.http.api.Produces; @Controller public class HelloController { + @Produces("image/png") + @Get("/get") + byte[] testBytes() { + + return "not really an image but ok".getBytes(); + } + @Get("hello") String helloWorld() { return "Hello world"; @@ -13,9 +22,15 @@ String helloWorld() { @Get("person/{name}/{sortBy}") Person person(String name, String sortBy) { - var p = new Person(); + final var p = new Person(); p.setId(42); p.setName(name + " hello" + " sortBy:" + sortBy); return p; } + + @Post("person/update") + String add(Person newGuy) { + + return "New Guy Added"; + } } From f89db1308728180db9b3697e38f5d138cc983e73 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sat, 15 Oct 2022 20:59:57 -0400 Subject: [PATCH 0341/1323] more scenarios --- .../java/org/example/HelloController.java | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/tests/test-nima-jsonb/src/main/java/org/example/HelloController.java b/tests/test-nima-jsonb/src/main/java/org/example/HelloController.java index 83d2555a8..44fe96f49 100644 --- a/tests/test-nima-jsonb/src/main/java/org/example/HelloController.java +++ b/tests/test-nima-jsonb/src/main/java/org/example/HelloController.java @@ -1,9 +1,14 @@ package org.example; +import java.util.List; +import java.util.Map; +import java.util.Set; + import io.avaje.http.api.Controller; import io.avaje.http.api.Get; import io.avaje.http.api.Post; import io.avaje.http.api.Produces; +import io.avaje.http.api.Put; @Controller public class HelloController { @@ -28,9 +33,36 @@ Person person(String name, String sortBy) { return p; } + @Get("person/{sortBy}/list") + List personList(String sortBy) { + final var p = new Person(); + p.setId(42); + return List.of(p, p); + } + + @Get("person/{sortBy}/set") + Set personSet(String sortBy) { + final var p = new Person(); + p.setId(42); + return Set.of(p, p); + } + + @Get("person/{sortBy}/map") + Map personMap(String sortBy) { + final var p = new Person(); + p.setId(42); + return Map.of(sortBy, p); + } + @Post("person/update") String add(Person newGuy) { return "New Guy Added"; } + + @Put("person/update") + String addMultiple(List newGuys) { + + return "New Guys Added"; + } } From 634b4f2937035c2912ba7103bcb06cba056a6397 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sat, 15 Oct 2022 21:18:58 -0400 Subject: [PATCH 0342/1323] void body parameters --- .../helidon/nima/ControllerMethodWriter.java | 4 ++ .../helidon/nima/ControllerWriter.java | 42 ++++++++++++------- .../generator/helidon/nima/NimaProcessor.java | 4 +- .../java/org/example/HelloController.java | 6 +++ 4 files changed, 38 insertions(+), 18 deletions(-) diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java index d90a2177c..a6629f023 100644 --- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java +++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java @@ -102,6 +102,10 @@ void writeHandler(boolean requestScoped) { writer.append(" "); if (!method.isVoid()) { writer.append("var result = "); + } else if (method.isVoid() + && params.stream().noneMatch(p -> "ServerResponse".equals(p.getShortType()))) { + throw new IllegalStateException( + "Void controller methods must have a ServerResponse parameter"); } if (method.includeValidate()) { diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java index 77632c59f..b44df8ddc 100644 --- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java +++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java @@ -3,7 +3,6 @@ import java.io.IOException; import java.util.List; import java.util.Optional; -import java.util.function.Predicate; import javax.lang.model.type.DeclaredType; @@ -19,7 +18,6 @@ class ControllerWriter extends BaseControllerWriter { private static final String AT_GENERATED = "@Generated(\"avaje-helidon-nima-generator\")"; private final boolean useJsonB; - private List jsonBMethodList; ControllerWriter(ControllerReader reader, ProcessingContext ctx, boolean jsonB) throws IOException { @@ -28,14 +26,6 @@ class ControllerWriter extends BaseControllerWriter { if (useJsonB) { reader.addImportType("io.avaje.jsonb.Jsonb"); reader.addImportType("io.avaje.jsonb.JsonType"); - jsonBMethodList = - reader.getMethods().stream() - .filter(MethodReader::isWebMethod) - .filter(Predicate.not(MethodReader::isVoid)) - .filter(m -> !"byte[]".equals(m.getReturnType().toString())) - .filter( - m -> m.getProduces() == null || m.getProduces().toLowerCase().contains("json")) - .toList(); } // reader.addImportType("io.helidon.common.http.FormParams"); reader.addImportType("io.helidon.nima.webserver.http.HttpRules"); @@ -103,8 +93,18 @@ private void writeClassStart() { writer.append(" private final Validator validator;").eol(); } + List jsonMethods; if (useJsonB) { - writeJsonBTypeFields(); + jsonMethods = + reader.getMethods().stream() + .filter(MethodReader::isWebMethod) + .filter(m -> !"byte[]".equals(m.getReturnType().toString())) + .filter( + m -> m.getProduces() == null || m.getProduces().toLowerCase().contains("json")) + .toList(); + writeJsonBTypeFields(jsonMethods); + } else { + jsonMethods = null; } writer.eol(); @@ -125,14 +125,14 @@ private void writeClassStart() { } if (useJsonB) { - writeJsonBTypeAssignments(); + writeJsonBTypeAssignments(jsonMethods); } writer.append(" }").eol().eol(); } - public void writeJsonBTypeFields() { - for (final MethodReader methodReader : jsonBMethodList) { + public void writeJsonBTypeFields(List jsonMethods) { + for (final MethodReader methodReader : jsonMethods) { // body types if (methodReader.getBodyType() != null) { methodReader.getParams().stream() @@ -145,6 +145,11 @@ public void writeJsonBTypeFields() { param.getUType().full(), methodReader.simpleName()) .eol()); } + + if (methodReader.isVoid()) { + continue; + } + // return types if (methodReader.getReturnType() instanceof final DeclaredType fullType) { final var typeArgs = fullType.getTypeArguments(); @@ -168,11 +173,16 @@ public void writeJsonBTypeFields() { } } - public void writeJsonBTypeAssignments() { + public void writeJsonBTypeAssignments(List jsonMethods) { - for (final MethodReader methodReader : jsonBMethodList) { + for (final MethodReader methodReader : jsonMethods) { // body types writeBodyJsonType(methodReader); + + if (methodReader.isVoid()) { + continue; + } + writeReturnJsonType(methodReader); } } diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/NimaProcessor.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/NimaProcessor.java index 9162bec26..a141cda5f 100644 --- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/NimaProcessor.java +++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/NimaProcessor.java @@ -20,8 +20,8 @@ public NimaProcessor() { } } - public NimaProcessor(boolean b) { - jsonB = b; + public NimaProcessor(boolean useJsonb) { + jsonB = useJsonb; } @Override diff --git a/tests/test-nima-jsonb/src/main/java/org/example/HelloController.java b/tests/test-nima-jsonb/src/main/java/org/example/HelloController.java index 44fe96f49..f54280a35 100644 --- a/tests/test-nima-jsonb/src/main/java/org/example/HelloController.java +++ b/tests/test-nima-jsonb/src/main/java/org/example/HelloController.java @@ -9,6 +9,7 @@ import io.avaje.http.api.Post; import io.avaje.http.api.Produces; import io.avaje.http.api.Put; +import io.helidon.nima.webserver.http.ServerResponse; @Controller public class HelloController { @@ -20,6 +21,11 @@ byte[] testBytes() { return "not really an image but ok".getBytes(); } + @Get("/void") + void testVoid(Person p, ServerResponse res) { + res.send("success"); + } + @Get("hello") String helloWorld() { return "Hello world"; From f55087dd7064119409cb7ee2c4c740f1c32a4a6f Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sat, 15 Oct 2022 21:11:36 -0500 Subject: [PATCH 0343/1323] Update README.md --- README.md | 159 ++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 101 insertions(+), 58 deletions(-) diff --git a/README.md b/README.md index c8a9bf136..cb8688b50 100644 --- a/README.md +++ b/README.md @@ -6,79 +6,95 @@ Http server and client libraries and code generation. A jax-rs style controllers with annotations (`@Path`, `@Get` ...) that is lightweight by using source code generation (annotation processors) -to generate adapter code for Javalin and Helidon SE. +to generate adapter code for Javalin and Helidon SE/Nima. - Lightweight as in 65Kb library + generated source code -- Full use of Javalin or Helidon SE as desired +- Full use of Javalin or Helidon SE/Nima as desired -## Define a Controller +## Define a Controller (Note that these APT processors works with both Java and Kotlin.) ```java -package org.example.hello +package org.example.hello; -import io.avaje.http.api.Controller -import io.avaje.http.api.Get -import io.avaje.http.api.Path +import io.avaje.http.api.Controller; +import io.avaje.http.api.Get; +import io.avaje.http.api.Path; +import java.util.List; @Path("/widgets") @Controller -class WidgetController(private val hello: HelloComponent) { - - @Get("/:id") - fun getById(id : Int): Widget { - return Widget(id, "you got it${hello.hello()}") +public class WidgetController { + private final HelloComponent hello; + public WidgetController(HelloComponent hello) { + this.hello = hello; + } + + @Get("/{id}") + Widget getById(int id) { + return new Widget(id, "you got it"+ hello.hello()); } @Get - fun getAll(): MutableList { - - val list = mutableListOf() - list.add(Widget(1, "Rob")) - list.add(Widget(2, "Fi")) - - return list + List getAll() { + return List.of(new Widget(1, "Rob"), new Widget(2, "Fi")); } - data class Widget(var id: Int, var name: String) + record Widget(int id, String name){}; } ``` -## Generated source (Javalin) +## Usage with Javalin -The annotation processor will generate a `$Route` for the controller like below. - -Note that this class implements the WebRoutes interface, which means we can -get all the WebRoutes and register them with Javalin using. +The annotation processor will generate controller classes implementing the WebRoutes interface, which means we can +get all the WebRoutes and register them with Javalin using: ```java -fun main(args: Array) { +var routes = BeanScope.builder().build().list(WebRoutes.class); - // get all the webRoutes - val webRoutes = BeanScope.builder().build().list(WebRoutes::class.java) +Javalin.create() + .routes(() -> routes.forEach(WebRoutes::registerRoutes)) + .start(); +``` - val javalin = Javalin.create() - javalin.routes { - // register all the routes with Javalin - webRoutes.forEach { it.registerRoutes() } +## Usage with Helidon SE - // other routes etc as desired - ApiBuilder.get("/foo") { ctx -> - ctx.html("bar") - ctx.status(200) - } - ... - } +The annotation processor will generate controller classes implementing the Helidon Service interface, which we can use +get all the Services and register them with Helidon `RoutingBuilder`. + +```java +var routes = BeanScope.builder().build().list(Service.class); +var routingBuilder = Routing.builder().register(routes.stream().toArray(Service[]::new)); +WebServer.builder() + .addMediaSupport(JacksonSupport.create()) + .routing(routingBuilder) + .build() + .start(); +``` - javalin.start(7000) +## Usage with Helidon Nima + +The annotation processor will generate controller classes implementing the Helidon HttpService interface, which we can use +get all the services and register them with the Helidon `RoutingBuilder`. + +```java +var routes = BeanScope.builder().build().list(HttpService.class); +final var builder = HttpRouting.builder(); + +for (final HttpService httpService : routes) { + httpService.routing(builder); } +WebServer.builder() + .addRouting(builder.build()) + .build() + .start(); ``` +## Generated sources ### (Javalin) The generated WidgetController$Route.java is: - ```java package org.example.hello; @@ -102,7 +118,7 @@ public class WidgetController$Route implements WebRoutes { @Override public void registerRoutes() { - ApiBuilder.get("/widgets/:id", ctx -> { + ApiBuilder.get("/widgets/{id}", ctx -> { int id = asInt(ctx.pathParam("id")); ctx.json(controller.getById(id)); ctx.status(200); @@ -117,23 +133,52 @@ public class WidgetController$Route implements WebRoutes { } ``` -## Generated source (Helidon SE) +### (Helidon SE) The generated WidgetController$Route.java is: +```java +package org.example.hello; -The annotation processor will generate a `$Route` for the controller like below. +import static io.avaje.http.api.PathTypeConversion.*; -Note that this class implements the Helidon Service interface, which means we can -get all the Services and register them with Helidon `RoutingBuilder`. +import io.avaje.http.api.*; +import io.helidon.common.http.FormParams; +import io.helidon.webserver.Handler; +import io.helidon.webserver.Routing; +import io.helidon.webserver.ServerRequest; +import io.helidon.webserver.ServerResponse; +import io.helidon.webserver.Service; +import jakarta.inject.Singleton; +import org.example.hello.WidgetController; +@Generated("io.dinject.helidon-generator") +@Singleton +public class WidgetController$Route implements Service { + + private final WidgetController controller; + + public WidgetController$Route(WidgetController controller) { + this.controller = controller; + } + + @Override + public void update(Routing.Rules rules) { + + rules.get("/widgets/{id}", this::_getById); + rules.post("/widgets", this::_getAll); + } + + private void _getById(ServerRequest req, ServerResponse res) { + int id = asInt(req.path().param("id")); + res.send(controller.getById(id)); + } + + private void _getAll(ServerRequest req, ServerResponse res) { + res.send(controller.getAll()); + } + +} ``` -var routes = BeanScope.builder().build().list(Service.class); -var routingBuilder = Routing.builder().register(routes.stream().toArray(Service[]::new)); -WebServer.builder() - .addMediaSupport(JacksonSupport.create()) - .routing(routingBuilder) - .build() - .start(); -``` -### (Helidon SE) The generated WidgetController$Route.java is: + +### (Helidon Nima) The generated WidgetController$Route.java is: ```java package org.example.hello; @@ -163,7 +208,7 @@ public class WidgetController$Route implements Service { @Override public void update(Routing.Rules rules) { - rules.get("/widgets/:id", this::_getById); + rules.get("/widgets/{id}", this::_getById); rules.post("/widgets", this::_getAll); } @@ -179,6 +224,4 @@ public class WidgetController$Route implements Service { } ``` -Note that this APT processor works with both Java and Kotlin. - From 022a54f549b3031d57fce7b301c8a2847cbeab89 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sat, 15 Oct 2022 21:12:12 -0500 Subject: [PATCH 0344/1323] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index cb8688b50..7d55687aa 100644 --- a/README.md +++ b/README.md @@ -76,7 +76,7 @@ WebServer.builder() ## Usage with Helidon Nima The annotation processor will generate controller classes implementing the Helidon HttpService interface, which we can use -get all the services and register them with the Helidon `RoutingBuilder`. +get all the services and register them with the Helidon `HttpRouting`. ```java var routes = BeanScope.builder().build().list(HttpService.class); From 9bf2c50ddef1a0a9cf1aa0b0f224917e16de5d5a Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sat, 15 Oct 2022 22:59:40 -0400 Subject: [PATCH 0345/1323] support form parameters --- .../helidon/nima/ControllerMethodWriter.java | 21 +-- .../helidon/nima/ControllerWriter.java | 2 +- .../helidon/nima/NimaPlatformAdapter.java | 10 +- .../java/org/example/HelloController.java | 132 ++++++++++-------- .../src/main/java/org/example/MyForm.java | 8 ++ 5 files changed, 89 insertions(+), 84 deletions(-) create mode 100644 tests/test-nima-jsonb/src/main/java/org/example/MyForm.java diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java index a6629f023..76adab2bb 100644 --- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java +++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java @@ -6,6 +6,7 @@ import io.avaje.http.generator.core.Append; import io.avaje.http.generator.core.MethodParam; import io.avaje.http.generator.core.MethodReader; +import io.avaje.http.generator.core.ParamType; import io.avaje.http.generator.core.PathSegments; import io.avaje.http.generator.core.ProcessingContext; import io.avaje.http.generator.core.WebMethod; @@ -30,30 +31,17 @@ class ControllerMethodWriter { void writeRule() { final var fullPath = method.getFullPath(); - // final String bodyType = method.getBodyType(); - // if (bodyType != null) { - // writer.append(" rules.%s(\"%s\", Handler.create(%s.class, this::_%s));", - // webMethod.name().toLowerCase(), fullPath, bodyType, method.simpleName()).eol(); - // } else if (method.isFormBody()) { - // writer.append(" rules.%s(\"%s\", Handler.create(%s.class, this::_%s));", - // webMethod.name().toLowerCase(), fullPath, "FormParams", method.simpleName()).eol(); - // } else { writer .append( " rules.%s(\"%s\", this::_%s);", webMethod.name().toLowerCase(), fullPath, method.simpleName()) .eol(); - // } } void writeHandler(boolean requestScoped) { writer.append(" private void _%s(ServerRequest req, ServerResponse res", method.simpleName()); writer.append(") {").eol(); - // if (!method.isVoid()) { - // writeContextReturn(); - // } - final var bodyType = method.getBodyType(); if (bodyType != null) { if (useJsonB) { @@ -82,9 +70,10 @@ void writeHandler(boolean requestScoped) { writer.append(");").eol(); }); } - } // else if (method.isFormBody()) { - // writer.append(", %s %s", "FormParams", "formParams"); - // } + } else if (method.getParams().stream() + .anyMatch(p -> p.isForm() || ParamType.FORMPARAM.equals(p.getParamType()))) { + writer.append(" var formParams = req.content().as(Parameters.class);").eol(); + } final var segments = method.getPathSegments(); if (!segments.isEmpty()) { diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java index b44df8ddc..49660a023 100644 --- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java +++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java @@ -27,7 +27,7 @@ class ControllerWriter extends BaseControllerWriter { reader.addImportType("io.avaje.jsonb.Jsonb"); reader.addImportType("io.avaje.jsonb.JsonType"); } - // reader.addImportType("io.helidon.common.http.FormParams"); + reader.addImportType("io.helidon.common.parameters.Parameters"); reader.addImportType("io.helidon.nima.webserver.http.HttpRules"); reader.addImportType("io.helidon.nima.webserver.http.HttpRouting"); reader.addImportType("io.helidon.nima.webserver.http.ServerRequest"); diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/NimaPlatformAdapter.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/NimaPlatformAdapter.java index 995668c7b..c65148a72 100644 --- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/NimaPlatformAdapter.java +++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/NimaPlatformAdapter.java @@ -1,17 +1,17 @@ package io.avaje.http.generator.helidon.nima; +import java.util.List; + import io.avaje.http.generator.core.Append; import io.avaje.http.generator.core.ControllerReader; import io.avaje.http.generator.core.ParamType; import io.avaje.http.generator.core.PlatformAdapter; -import java.util.List; - class NimaPlatformAdapter implements PlatformAdapter { static final String NIMA_REQ = "io.helidon.nima.webserver.http.ServerRequest"; static final String NIMA_RES = "io.helidon.nima.webserver.http.ServerResponse"; - static final String HELIDON_FORMPARAMS = "io.helidon.common.http.FormParams"; + static final String HELIDON_FORMPARAMS = "io.helidon.common.parameters.Parameters"; @Override public boolean isContextType(String rawType) { @@ -79,9 +79,7 @@ public void writeReadParameter(Append writer, ParamType paramType, String paramN case COOKIE: writer.append("req.headers().cookies().first(\"%s\").orElse(null)", paramName); break; - case BODY: - case BEANPARAM: - case FORM: + case BODY, BEANPARAM, FORM: default: writer.append("null // TODO req.%s().param(\"%s\")", paramType.getType(), paramName); } diff --git a/tests/test-nima-jsonb/src/main/java/org/example/HelloController.java b/tests/test-nima-jsonb/src/main/java/org/example/HelloController.java index f54280a35..077506559 100644 --- a/tests/test-nima-jsonb/src/main/java/org/example/HelloController.java +++ b/tests/test-nima-jsonb/src/main/java/org/example/HelloController.java @@ -1,74 +1,84 @@ package org.example; -import java.util.List; -import java.util.Map; -import java.util.Set; - import io.avaje.http.api.Controller; -import io.avaje.http.api.Get; +import io.avaje.http.api.Form; import io.avaje.http.api.Post; -import io.avaje.http.api.Produces; -import io.avaje.http.api.Put; -import io.helidon.nima.webserver.http.ServerResponse; @Controller public class HelloController { - @Produces("image/png") - @Get("/get") - byte[] testBytes() { - - return "not really an image but ok".getBytes(); +// @Produces("image/png") +// @Get("/get") +// byte[] testBytes() { +// +// return "not really an image but ok".getBytes(); +// } +// +// @Get("/void") +// void testVoid(Person p, ServerResponse res) { +// res.send("success"); +// } +// +// @Get("/helidon") +// void testHelidon(ServerRequest req, ServerResponse res) { +// +// res.send("success"); +// } +// +// @Get("hello") +// String helloWorld() { +// return "Hello world"; +// } +// +// @Get("person/{name}/{sortBy}") +// Person person(String name, String sortBy) { +// final var p = new Person(); +// p.setId(42); +// p.setName(name + " hello" + " sortBy:" + sortBy); +// return p; +// } +// +// @Get("person/{sortBy}/list") +// List personList(String sortBy) { +// final var p = new Person(); +// p.setId(42); +// return List.of(p, p); +// } +// +// @Get("person/{sortBy}/set") +// Set personSet(String sortBy) { +// final var p = new Person(); +// p.setId(42); +// return Set.of(p, p); +// } +// +// @Get("person/{sortBy}/map") +// Map personMap(String sortBy) { +// final var p = new Person(); +// p.setId(42); +// return Map.of(sortBy, p); +// } +// +// @Post("person/update") +// String add(Person newGuy) { +// +// return "New Guy Added"; +// } +// +// @Put("person/update") +// String addMultiple(List newGuys) { +// return "New Guys Added"; +// } + @Form + @Post("form") + String form(String name, String email, String url) { + return name; } - @Get("/void") - void testVoid(Person p, ServerResponse res) { - res.send("success"); + @Form + @Post("formBean") + String formBean(MyForm form) { + return form.email; } - @Get("hello") - String helloWorld() { - return "Hello world"; - } - - @Get("person/{name}/{sortBy}") - Person person(String name, String sortBy) { - final var p = new Person(); - p.setId(42); - p.setName(name + " hello" + " sortBy:" + sortBy); - return p; - } - - @Get("person/{sortBy}/list") - List personList(String sortBy) { - final var p = new Person(); - p.setId(42); - return List.of(p, p); - } - - @Get("person/{sortBy}/set") - Set personSet(String sortBy) { - final var p = new Person(); - p.setId(42); - return Set.of(p, p); - } - - @Get("person/{sortBy}/map") - Map personMap(String sortBy) { - final var p = new Person(); - p.setId(42); - return Map.of(sortBy, p); - } - - @Post("person/update") - String add(Person newGuy) { - - return "New Guy Added"; - } - - @Put("person/update") - String addMultiple(List newGuys) { - - return "New Guys Added"; - } } diff --git a/tests/test-nima-jsonb/src/main/java/org/example/MyForm.java b/tests/test-nima-jsonb/src/main/java/org/example/MyForm.java new file mode 100644 index 000000000..3c3a75138 --- /dev/null +++ b/tests/test-nima-jsonb/src/main/java/org/example/MyForm.java @@ -0,0 +1,8 @@ +package org.example; + +public class MyForm { + + public String name; + public String email; + public String url; +} From 86aac66bb908cc6607f186d2d8adb84537c5651e Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sat, 15 Oct 2022 23:03:23 -0400 Subject: [PATCH 0346/1323] uncomment test --- .../java/org/example/HelloController.java | 133 ++++++++++-------- 1 file changed, 71 insertions(+), 62 deletions(-) diff --git a/tests/test-nima-jsonb/src/main/java/org/example/HelloController.java b/tests/test-nima-jsonb/src/main/java/org/example/HelloController.java index 077506559..bb944a41d 100644 --- a/tests/test-nima-jsonb/src/main/java/org/example/HelloController.java +++ b/tests/test-nima-jsonb/src/main/java/org/example/HelloController.java @@ -1,74 +1,83 @@ package org.example; +import java.util.List; +import java.util.Map; +import java.util.Set; + import io.avaje.http.api.Controller; import io.avaje.http.api.Form; +import io.avaje.http.api.Get; import io.avaje.http.api.Post; +import io.avaje.http.api.Produces; +import io.avaje.http.api.Put; +import io.helidon.nima.webserver.http.ServerRequest; +import io.helidon.nima.webserver.http.ServerResponse; @Controller public class HelloController { -// @Produces("image/png") -// @Get("/get") -// byte[] testBytes() { -// -// return "not really an image but ok".getBytes(); -// } -// -// @Get("/void") -// void testVoid(Person p, ServerResponse res) { -// res.send("success"); -// } -// -// @Get("/helidon") -// void testHelidon(ServerRequest req, ServerResponse res) { -// -// res.send("success"); -// } -// -// @Get("hello") -// String helloWorld() { -// return "Hello world"; -// } -// -// @Get("person/{name}/{sortBy}") -// Person person(String name, String sortBy) { -// final var p = new Person(); -// p.setId(42); -// p.setName(name + " hello" + " sortBy:" + sortBy); -// return p; -// } -// -// @Get("person/{sortBy}/list") -// List personList(String sortBy) { -// final var p = new Person(); -// p.setId(42); -// return List.of(p, p); -// } -// -// @Get("person/{sortBy}/set") -// Set personSet(String sortBy) { -// final var p = new Person(); -// p.setId(42); -// return Set.of(p, p); -// } -// -// @Get("person/{sortBy}/map") -// Map personMap(String sortBy) { -// final var p = new Person(); -// p.setId(42); -// return Map.of(sortBy, p); -// } -// -// @Post("person/update") -// String add(Person newGuy) { -// -// return "New Guy Added"; -// } -// -// @Put("person/update") -// String addMultiple(List newGuys) { -// return "New Guys Added"; -// } + @Produces("image/png") + @Get("/get") + byte[] testBytes() { + + return "not really an image but ok".getBytes(); + } + + @Get("/void") + void testVoid(Person p, ServerResponse res) { + res.send("success"); + } + + @Get("/helidon") + void testHelidon(ServerRequest req, ServerResponse res) { + + res.send("success"); + } + + @Get("hello") + String helloWorld() { + return "Hello world"; + } + + @Get("person/{name}/{sortBy}") + Person person(String name, String sortBy) { + final var p = new Person(); + p.setId(42); + p.setName(name + " hello" + " sortBy:" + sortBy); + return p; + } + + @Get("person/{sortBy}/list") + List personList(String sortBy) { + final var p = new Person(); + p.setId(42); + return List.of(p, p); + } + + @Get("person/{sortBy}/set") + Set personSet(String sortBy) { + final var p = new Person(); + p.setId(42); + return Set.of(p, p); + } + + @Get("person/{sortBy}/map") + Map personMap(String sortBy) { + final var p = new Person(); + p.setId(42); + return Map.of(sortBy, p); + } + + @Post("person/update") + String add(Person newGuy) { + + return "New Guy Added"; + } + + @Put("person/update") + String addMultiple(List newGuys) { + return "New Guys Added"; + } @Form @Post("form") String form(String name, String email, String url) { From c2e9c5ae4e5d961c9d33ec97c1e4c14f7593065c Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sat, 15 Oct 2022 23:06:42 -0500 Subject: [PATCH 0347/1323] add avaje-jsonb source --- README.md | 90 ++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 72 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 7d55687aa..59305d1ab 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ public class WidgetController { return new Widget(id, "you got it"+ hello.hello()); } - @Get + @Get() List getAll() { return List.of(new Widget(1, "Rob"), new Widget(2, "Fi")); } @@ -186,42 +186,96 @@ package org.example.hello; import static io.avaje.http.api.PathTypeConversion.*; import io.avaje.http.api.*; -import io.helidon.common.http.FormParams; -import io.helidon.webserver.Handler; -import io.helidon.webserver.Routing; -import io.helidon.webserver.ServerRequest; -import io.helidon.webserver.ServerResponse; -import io.helidon.webserver.Service; -import jakarta.inject.Singleton; +import io.avaje.inject.Component; +import io.helidon.nima.webserver.http.HttpRouting; +import io.helidon.nima.webserver.http.HttpRules; +import io.helidon.nima.webserver.http.HttpService; +import io.helidon.nima.webserver.http.ServerRequest; +import io.helidon.nima.webserver.http.ServerResponse; import org.example.hello.WidgetController; -@Generated("io.dinject.helidon-generator") -@Singleton -public class WidgetController$Route implements Service { +@Generated("avaje-helidon-nima-generator") +@Component +public class WidgetController$Route implements HttpService { private final WidgetController controller; - public WidgetController$Route(WidgetController controller) { this.controller = controller; } @Override - public void update(Routing.Rules rules) { - + public void routing(HttpRules rules) { rules.get("/widgets/{id}", this::_getById); - rules.post("/widgets", this::_getAll); + rules.get("/widgets", this::_getAll); } private void _getById(ServerRequest req, ServerResponse res) { - int id = asInt(req.path().param("id")); - res.send(controller.getById(id)); + var pathParams = req.path().pathParameters(); + int id = asInt(pathParams.first("id").get()); + var result = controller.getById(id); + res.send(result); } private void _getAll(ServerRequest req, ServerResponse res) { - res.send(controller.getAll()); + var pathParams = req.path().pathParameters(); + var result = controller.getAll(); + res.send(result); } } ``` +### (Helidon Nima with Avaje-Jsonb) The generated WidgetController$Route.java is: + +```java +package org.example.hello; + +import static io.avaje.http.api.PathTypeConversion.*; + +import io.avaje.http.api.*; +import io.avaje.inject.Component; +import io.helidon.nima.webserver.http.HttpRouting; +import io.helidon.nima.webserver.http.HttpRules; +import io.helidon.nima.webserver.http.HttpService; +import io.helidon.nima.webserver.http.ServerRequest; +import io.helidon.nima.webserver.http.ServerResponse; +import org.example.hello.WidgetController; + +@Generated("avaje-helidon-nima-generator") +@Component +public class WidgetController$Route implements HttpService { + + + private final WidgetController controller; + private final JsonType getByIdReturnedJsonType; + private final JsonType> getAllReturnedJsonType; + + public WidgetController$Route(WidgetController controller, Jsonb jsonB) { + this.controller = controller; + this.getByIdReturnedJsonType = jsonB.type(org.example.hello.WidgetController.Widget.class); + this.getAllReturnedJsonType = jsonB.type(org.example.hello.WidgetController.Widget.class).list(); + } + + @Override + public void routing(HttpRules rules) { + rules.get("/widgets/{id}", this::_getById); + rules.get("/widgets", this::_getAll); + } + + private void _getById(ServerRequest req, ServerResponse res) { + var pathParams = req.path().pathParameters(); + int id = asInt(pathParams.first("id").get()); + var result = controller.getById(id); + res.headers().contentType(io.helidon.common.http.HttpMediaType.APPLICATION_JSON); + getByIdReturnedJsonType.toJson(result, res.outputStream()); + } + private void _getAll(ServerRequest req, ServerResponse res) { + var pathParams = req.path().pathParameters(); + var result = controller.getAll(); + res.headers().contentType(io.helidon.common.http.HttpMediaType.APPLICATION_JSON); + getAllReturnedJsonType.toJson(result, res.outputStream()); + } + +} +``` From 4f7d80d99bc6e5b1c4bc3685e3c657e8e1045550 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Mon, 17 Oct 2022 13:46:40 +1300 Subject: [PATCH 0348/1323] Code style only changes - new lines etc --- .../helidon/nima/ControllerMethodWriter.java | 98 ++++++++----------- .../helidon/nima/ControllerWriter.java | 31 ++---- .../generator/helidon/nima/NimaProcessor.java | 6 +- 3 files changed, 48 insertions(+), 87 deletions(-) diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java index 76adab2bb..effacd527 100644 --- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java +++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java @@ -1,17 +1,13 @@ package io.avaje.http.generator.helidon.nima; +import io.avaje.http.api.MediaType; +import io.avaje.http.generator.core.*; + import java.util.Optional; -import io.avaje.http.api.MediaType; -import io.avaje.http.generator.core.Append; -import io.avaje.http.generator.core.MethodParam; -import io.avaje.http.generator.core.MethodReader; -import io.avaje.http.generator.core.ParamType; -import io.avaje.http.generator.core.PathSegments; -import io.avaje.http.generator.core.ProcessingContext; -import io.avaje.http.generator.core.WebMethod; - -/** Write code to register Web route for a given controller method. */ +/** + * Write code to register Web route for a given controller method. + */ class ControllerMethodWriter { private final MethodReader method; @@ -20,11 +16,10 @@ class ControllerMethodWriter { private final ProcessingContext ctx; private final boolean useJsonB; - ControllerMethodWriter( - MethodReader method, Append writer, ProcessingContext ctx, boolean useJsonB) { + ControllerMethodWriter(MethodReader method, Append writer, ProcessingContext ctx, boolean useJsonB) { this.method = method; this.writer = writer; - webMethod = method.getWebMethod(); + this.webMethod = method.getWebMethod(); this.ctx = ctx; this.useJsonB = useJsonB; } @@ -32,46 +27,40 @@ class ControllerMethodWriter { void writeRule() { final var fullPath = method.getFullPath(); writer - .append( - " rules.%s(\"%s\", this::_%s);", - webMethod.name().toLowerCase(), fullPath, method.simpleName()) - .eol(); + .append( + " rules.%s(\"%s\", this::_%s);", + webMethod.name().toLowerCase(), fullPath, method.simpleName()) + .eol(); } void writeHandler(boolean requestScoped) { - writer.append(" private void _%s(ServerRequest req, ServerResponse res", method.simpleName()); - - writer.append(") {").eol(); + writer.append(" private void _%s(ServerRequest req, ServerResponse res) {", method.simpleName()).eol(); final var bodyType = method.getBodyType(); if (bodyType != null) { if (useJsonB) { - writer - .append( - " var %s = %sBodyJsonType.fromJson(req.content().inputStream());", - method.getBodyName(), method.simpleName()) - .eol(); + .append( + " var %s = %sBodyJsonType.fromJson(req.content().inputStream());", + method.getBodyName(), method.simpleName()) + .eol(); } else { // use default helidon content negotiation method.getParams().stream() - .filter(MethodParam::isBody) - .forEach( - param -> { - final var type = param.getUType(); - writer.append(" var %s = req.content().as(", method.getBodyName()); - - if (type.param0() != null) { - writer.append("new io.helidon.common.GenericType<%s>() {}", type.full()); - } else { - writer.append("%s.class", type.full()); - } - - writer.append(");").eol(); - }); + .filter(MethodParam::isBody) + .forEach( + param -> { + final var type = param.getUType(); + writer.append(" var %s = req.content().as(", method.getBodyName()); + if (type.param0() != null) { + writer.append("new io.helidon.common.GenericType<%s>() {}", type.full()); + } else { + writer.append("%s.class", type.full()); + } + writer.append(");").eol(); + }); } - } else if (method.getParams().stream() - .anyMatch(p -> p.isForm() || ParamType.FORMPARAM.equals(p.getParamType()))) { + } else if (method.getParams().stream().anyMatch(p -> p.isForm() || ParamType.FORMPARAM.equals(p.getParamType()))) { writer.append(" var formParams = req.content().as(Parameters.class);").eol(); } @@ -91,10 +80,8 @@ void writeHandler(boolean requestScoped) { writer.append(" "); if (!method.isVoid()) { writer.append("var result = "); - } else if (method.isVoid() - && params.stream().noneMatch(p -> "ServerResponse".equals(p.getShortType()))) { - throw new IllegalStateException( - "Void controller methods must have a ServerResponse parameter"); + } else if (method.isVoid() && params.stream().noneMatch(p -> "ServerResponse".equals(p.getShortType()))) { + throw new IllegalStateException("Void controller methods must have a ServerResponse parameter"); } if (method.includeValidate()) { @@ -118,14 +105,14 @@ void writeHandler(boolean requestScoped) { if (!method.isVoid()) { writeContextReturn(); if (useJsonB - && !"byte[]".equals(method.getReturnType().toString()) - && (method.getProduces() == null - || method.getProduces().toLowerCase().contains("json"))) { + && !"byte[]".equals(method.getReturnType().toString()) + && (method.getProduces() == null + || method.getProduces().toLowerCase().contains("json"))) { writer - .append( - " %sReturnedJsonType.toJson(result, res.outputStream());", method.simpleName()) - .eol(); + .append( + " %sReturnedJsonType.toJson(result, res.outputStream());", method.simpleName()) + .eol(); } else { writer.append(" res.send(result);").eol(); @@ -136,19 +123,14 @@ void writeHandler(boolean requestScoped) { private void writeContextReturn() { final var producesOp = Optional.ofNullable(method.getProduces()); - if (producesOp.isEmpty() && !useJsonB) { return; } final var produces = producesOp.orElse(MediaType.APPLICATION_JSON); - final var contentTypeString = - " res.headers().contentType(io.helidon.common.http.HttpMediaType."; - + final var contentTypeString = " res.headers().contentType(io.helidon.common.http.HttpMediaType."; switch (produces.toLowerCase()) { - case MediaType.APPLICATION_JSON -> writer - .append(contentTypeString + "APPLICATION_JSON);") - .eol(); + case MediaType.APPLICATION_JSON -> writer.append(contentTypeString + "APPLICATION_JSON);").eol(); case MediaType.TEXT_HTML -> writer.append(contentTypeString + "TEXT_HTML);").eol(); case MediaType.TEXT_PLAIN -> writer.append(contentTypeString + "TEXT_PLAIN);").eol(); default -> writer.append(contentTypeString + "create(\"%s\"));", produces).eol(); diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java index 49660a023..535a75ad9 100644 --- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java +++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java @@ -19,10 +19,9 @@ class ControllerWriter extends BaseControllerWriter { private static final String AT_GENERATED = "@Generated(\"avaje-helidon-nima-generator\")"; private final boolean useJsonB; - ControllerWriter(ControllerReader reader, ProcessingContext ctx, boolean jsonB) - throws IOException { + ControllerWriter(ControllerReader reader, ProcessingContext ctx, boolean jsonB) throws IOException { super(reader, ctx); - useJsonB = jsonB; + this.useJsonB = jsonB; if (useJsonB) { reader.addImportType("io.avaje.jsonb.Jsonb"); reader.addImportType("io.avaje.jsonb.JsonType"); @@ -74,12 +73,7 @@ private void writeRoutes(List methods) { private void writeClassStart() { writer.append(AT_GENERATED).eol(); writer.append("@Component").eol(); - writer - .append("public class ") - .append(shortName) - .append("$Route implements HttpService {") - .eol() - .eol(); + writer.append("public class %s$Route implements HttpService {", shortName).eol().eol(); var controllerName = "controller"; var controllerType = shortName; @@ -99,35 +93,29 @@ private void writeClassStart() { reader.getMethods().stream() .filter(MethodReader::isWebMethod) .filter(m -> !"byte[]".equals(m.getReturnType().toString())) - .filter( - m -> m.getProduces() == null || m.getProduces().toLowerCase().contains("json")) + .filter(m -> m.getProduces() == null || m.getProduces().toLowerCase().contains("json")) .toList(); writeJsonBTypeFields(jsonMethods); } else { jsonMethods = null; } - writer.eol(); writer.append(" public %s$Route(%s %s", shortName, controllerType, controllerName); if (reader.isIncludeValidator()) { writer.append(", Validator validator"); } - if (useJsonB) { writer.append(", Jsonb jsonB"); } - writer.append(") {").eol(); writer.append(" this.%s = %s;", controllerName, controllerName).eol(); if (reader.isIncludeValidator()) { writer.append(" this.validator = validator;").eol(); } - if (useJsonB) { writeJsonBTypeAssignments(jsonMethods); } - writer.append(" }").eol().eol(); } @@ -167,28 +155,23 @@ public void writeJsonBTypeFields(List jsonMethods) { } writer.append(" %sReturnedJsonType;", methodReader.simpleName()).eol(); } else { - throw new UnsupportedOperationException( - "Only Objects are supported with Jsonb Return Types"); + throw new UnsupportedOperationException("Only Objects are supported with Jsonb Return Types"); } } } public void writeJsonBTypeAssignments(List jsonMethods) { - for (final MethodReader methodReader : jsonMethods) { // body types writeBodyJsonType(methodReader); - if (methodReader.isVoid()) { continue; } - writeReturnJsonType(methodReader); } } private void writeBodyJsonType(MethodReader methodReader) { - if (methodReader.getBodyType() != null) { methodReader.getParams().stream() .filter(MethodParam::isBody) @@ -220,7 +203,6 @@ private void writeBodyJsonType(MethodReader methodReader) { } void writeReturnJsonType(MethodReader methodReader) { - if (methodReader.getReturnType() instanceof final DeclaredType fullType) { final var typeArgs = fullType.getTypeArguments(); final var typeArgSize = typeArgs.size(); @@ -251,8 +233,7 @@ void writeReturnJsonType(MethodReader methodReader) { writer.append(";").eol(); } else { - throw new UnsupportedOperationException( - "Only Objects and Strings are supported with Jsonb Controller Return Types"); + throw new UnsupportedOperationException("Only Objects and Strings are supported with Jsonb Controller Return Types"); } } } diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/NimaProcessor.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/NimaProcessor.java index a141cda5f..44cccfaee 100644 --- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/NimaProcessor.java +++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/NimaProcessor.java @@ -9,7 +9,7 @@ public class NimaProcessor extends BaseProcessor { - boolean jsonB; + private boolean jsonB; public NimaProcessor() { try { @@ -30,9 +30,7 @@ protected PlatformAdapter providePlatformAdapter() { } @Override - public void writeControllerAdapter(ProcessingContext ctx, ControllerReader reader) - throws IOException { - + public void writeControllerAdapter(ProcessingContext ctx, ControllerReader reader) throws IOException { new ControllerWriter(reader, ctx, jsonB).write(); } } From 9051a1a8acb053fedbd17a2baf1a15b99ac6bbfc Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Mon, 17 Oct 2022 14:39:34 +1300 Subject: [PATCH 0349/1323] Nima ControllerMethodWriter - no functional change, extract helper methods --- .../helidon/nima/ControllerMethodWriter.java | 38 ++++++++++--------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java index effacd527..a5d4dd3d9 100644 --- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java +++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java @@ -3,6 +3,7 @@ import io.avaje.http.api.MediaType; import io.avaje.http.generator.core.*; +import java.util.List; import java.util.Optional; /** @@ -25,11 +26,8 @@ class ControllerMethodWriter { } void writeRule() { - final var fullPath = method.getFullPath(); - writer - .append( - " rules.%s(\"%s\", this::_%s);", - webMethod.name().toLowerCase(), fullPath, method.simpleName()) + writer.append(" rules.%s(\"%s\", this::_%s);", + webMethod.name().toLowerCase(), method.getFullPath(), method.simpleName()) .eol(); } @@ -60,7 +58,7 @@ void writeHandler(boolean requestScoped) { writer.append(");").eol(); }); } - } else if (method.getParams().stream().anyMatch(p -> p.isForm() || ParamType.FORMPARAM.equals(p.getParamType()))) { + } else if (usesFormParams()) { writer.append(" var formParams = req.content().as(Parameters.class);").eol(); } @@ -80,7 +78,7 @@ void writeHandler(boolean requestScoped) { writer.append(" "); if (!method.isVoid()) { writer.append("var result = "); - } else if (method.isVoid() && params.stream().noneMatch(p -> "ServerResponse".equals(p.getShortType()))) { + } else if (missingServerResponse(params)) { throw new IllegalStateException("Void controller methods must have a ServerResponse parameter"); } @@ -104,16 +102,8 @@ void writeHandler(boolean requestScoped) { writer.append(");").eol(); if (!method.isVoid()) { writeContextReturn(); - if (useJsonB - && !"byte[]".equals(method.getReturnType().toString()) - && (method.getProduces() == null - || method.getProduces().toLowerCase().contains("json"))) { - - writer - .append( - " %sReturnedJsonType.toJson(result, res.outputStream());", method.simpleName()) - .eol(); - + if (producesJson()) { + writer.append(" %sReturnedJsonType.toJson(result, res.outputStream());", method.simpleName()).eol(); } else { writer.append(" res.send(result);").eol(); } @@ -121,6 +111,20 @@ void writeHandler(boolean requestScoped) { writer.append(" }").eol().eol(); } + private boolean producesJson() { + return useJsonB + && !"byte[]".equals(method.getReturnType().toString()) + && (method.getProduces() == null || method.getProduces().toLowerCase().contains("json")); + } + + private boolean missingServerResponse(List params) { + return method.isVoid() && params.stream().noneMatch(p -> "ServerResponse".equals(p.getShortType())); + } + + private boolean usesFormParams() { + return method.getParams().stream().anyMatch(p -> p.isForm() || ParamType.FORMPARAM.equals(p.getParamType())); + } + private void writeContextReturn() { final var producesOp = Optional.ofNullable(method.getProduces()); if (producesOp.isEmpty() && !useJsonB) { From 11e9730fedd48d31519474ff9b229b30ac4676b3 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Mon, 17 Oct 2022 14:40:29 +1300 Subject: [PATCH 0350/1323] test-nima-jsonb - Add @Json annotation, Person and record type, tweak controller --- .../java/org/example/HelloController.java | 82 ++++++++++--------- .../src/main/java/org/example/Person.java | 21 +---- 2 files changed, 46 insertions(+), 57 deletions(-) diff --git a/tests/test-nima-jsonb/src/main/java/org/example/HelloController.java b/tests/test-nima-jsonb/src/main/java/org/example/HelloController.java index bb944a41d..1c043c259 100644 --- a/tests/test-nima-jsonb/src/main/java/org/example/HelloController.java +++ b/tests/test-nima-jsonb/src/main/java/org/example/HelloController.java @@ -1,93 +1,97 @@ package org.example; +import io.avaje.http.api.*; +import io.helidon.common.http.HttpMediaType; +import io.helidon.nima.webserver.http.ServerRequest; +import io.helidon.nima.webserver.http.ServerResponse; + import java.util.List; import java.util.Map; import java.util.Set; -import io.avaje.http.api.Controller; -import io.avaje.http.api.Form; -import io.avaje.http.api.Get; -import io.avaje.http.api.Post; -import io.avaje.http.api.Produces; -import io.avaje.http.api.Put; -import io.helidon.nima.webserver.http.ServerRequest; -import io.helidon.nima.webserver.http.ServerResponse; - @Controller public class HelloController { + @Produces(MediaType.TEXT_PLAIN) + @Get + String index() { + return "Hello world - index"; + } + + @Produces(MediaType.TEXT_PLAIN) + @Get("hello") + String helloWorld() { + return "Hello world"; + } + @Produces("image/png") @Get("/get") byte[] testBytes() { - return "not really an image but ok".getBytes(); } - @Get("/void") - void testVoid(Person p, ServerResponse res) { - res.send("success"); - } - @Get("/helidon") void testHelidon(ServerRequest req, ServerResponse res) { + res.headers().contentType(HttpMediaType.TEXT_PLAIN); + res.send("success path:" + req.path()); + } - res.send("success"); + @Get("/void") + void testVoid(ServerResponse res) { + res.send("GET-Returning-void"); } - @Get("hello") - String helloWorld() { - return "Hello world"; + // curl -v localhost:8081/person/jack + @Get("person/{name}") + Person person(String name) { + return new Person(42, name + " hello"); } - @Get("person/{name}/{sortBy}") - Person person(String name, String sortBy) { - final var p = new Person(); - p.setId(42); - p.setName(name + " hello" + " sortBy:" + sortBy); - return p; + // curl -X POST http://localhost:8081/person -H 'Content-Type: application/json' -d '{"id":942,"name":"Jimmy"}' + @Post("/person") + Person postPerson(Person body) { + return new Person(42, "Returning " + body.name()); } + // curl -v localhost:8081/person/foo/list @Get("person/{sortBy}/list") List personList(String sortBy) { - final var p = new Person(); - p.setId(42); - return List.of(p, p); + return List.of(new Person(42, "fooList"), new Person(43, "barList")); } + // curl -v localhost:8081/person/foo/set @Get("person/{sortBy}/set") Set personSet(String sortBy) { - final var p = new Person(); - p.setId(42); - return Set.of(p, p); + return Set.of(new Person(42, "fooSet"), new Person(43, "barSet")); } @Get("person/{sortBy}/map") Map personMap(String sortBy) { - final var p = new Person(); - p.setId(42); - return Map.of(sortBy, p); + return Map.of("one", new Person(42, "fooMap"), "two", new Person(43, "barMap")); } @Post("person/update") String add(Person newGuy) { - - return "New Guy Added"; + return "New Guy Added - " + newGuy; } @Put("person/update") String addMultiple(List newGuys) { return "New Guys Added"; } + + // curl -X POST http://localhost:8081/form -H "Content-Type: application/x-www-form-urlencoded" -d "name=Jimmy&email=jim@foo&url=notaurl" @Form @Post("form") String form(String name, String email, String url) { - return name; + return name + "-" + email + "-" + url; } - @Form + // curl -X POST http://localhost:8081/formBean -H "Content-Type: application/x-www-form-urlencoded" -d "name=FormBeanJimmy&email=jim@foo&url=notaurl" + @Form @Post("formBean") String formBean(MyForm form) { - return form.email; + return form.name + "-" + form.email + "-" + form.url; } } diff --git a/tests/test-nima-jsonb/src/main/java/org/example/Person.java b/tests/test-nima-jsonb/src/main/java/org/example/Person.java index 4959f219e..3f0b73270 100644 --- a/tests/test-nima-jsonb/src/main/java/org/example/Person.java +++ b/tests/test-nima-jsonb/src/main/java/org/example/Person.java @@ -1,23 +1,8 @@ package org.example; -public class Person { +import io.avaje.jsonb.Json; - long id; - String name; +@Json +public record Person(long id, String name) { - public long getId() { - return id; - } - - public void setId(long id) { - this.id = id; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } } From 471cf529c60b427e22862101a18f47b295515544 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Mon, 17 Oct 2022 15:26:33 +1300 Subject: [PATCH 0351/1323] test-nima-jsonb - Specify java.release in pom for javadoc plugin --- tests/test-nima-jsonb/pom.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 015e45ad8..2af18a2d1 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -12,7 +12,8 @@ 1 - 19 + 19 + 19 19 UTF-8 From 00a02ff07d73bdddd616d632b54f13d039509d8d Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Mon, 17 Oct 2022 17:01:30 +1300 Subject: [PATCH 0352/1323] nima-generator - import io.helidon.common.http.HttpMediaType in generated code --- .../http/generator/helidon/nima/ControllerMethodWriter.java | 2 +- .../io/avaje/http/generator/helidon/nima/ControllerWriter.java | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java index a5d4dd3d9..b287276d4 100644 --- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java +++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java @@ -132,7 +132,7 @@ private void writeContextReturn() { } final var produces = producesOp.orElse(MediaType.APPLICATION_JSON); - final var contentTypeString = " res.headers().contentType(io.helidon.common.http.HttpMediaType."; + final var contentTypeString = " res.headers().contentType(HttpMediaType."; switch (produces.toLowerCase()) { case MediaType.APPLICATION_JSON -> writer.append(contentTypeString + "APPLICATION_JSON);").eol(); case MediaType.TEXT_HTML -> writer.append(contentTypeString + "TEXT_HTML);").eol(); diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java index 535a75ad9..b5a2cd279 100644 --- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java +++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java @@ -26,6 +26,7 @@ class ControllerWriter extends BaseControllerWriter { reader.addImportType("io.avaje.jsonb.Jsonb"); reader.addImportType("io.avaje.jsonb.JsonType"); } + reader.addImportType("io.helidon.common.http.HttpMediaType"); reader.addImportType("io.helidon.common.parameters.Parameters"); reader.addImportType("io.helidon.nima.webserver.http.HttpRules"); reader.addImportType("io.helidon.nima.webserver.http.HttpRouting"); From c31eab5cdf3ffeef3cd0332f7159ab189b3b143b Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Mon, 17 Oct 2022 14:34:25 -0400 Subject: [PATCH 0353/1323] now doesn't generate Duplicate JsonTypes --- .gitignore | 1 + .../helidon/nima/ControllerMethodWriter.java | 49 ++++- .../helidon/nima/ControllerWriter.java | 191 +++++++++--------- .../generator/helidon/nima/JsonbType.java | 3 + 4 files changed, 134 insertions(+), 110 deletions(-) create mode 100644 http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/JsonbType.java diff --git a/.gitignore b/.gitignore index 17da7ad09..5b2b16770 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,4 @@ tests/test-nima/.classpath tests/test-nima/.factorypath tests/test-nima/.project *.class +tests/test-nima-jsonb/.classpath diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java index b287276d4..085122bc8 100644 --- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java +++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java @@ -1,11 +1,18 @@ package io.avaje.http.generator.helidon.nima; -import io.avaje.http.api.MediaType; -import io.avaje.http.generator.core.*; - import java.util.List; +import java.util.Map; import java.util.Optional; +import io.avaje.http.api.MediaType; +import io.avaje.http.generator.core.Append; +import io.avaje.http.generator.core.MethodParam; +import io.avaje.http.generator.core.MethodReader; +import io.avaje.http.generator.core.ParamType; +import io.avaje.http.generator.core.PathSegments; +import io.avaje.http.generator.core.ProcessingContext; +import io.avaje.http.generator.core.WebMethod; + /** * Write code to register Web route for a given controller method. */ @@ -16,13 +23,20 @@ class ControllerMethodWriter { private final WebMethod webMethod; private final ProcessingContext ctx; private final boolean useJsonB; - - ControllerMethodWriter(MethodReader method, Append writer, ProcessingContext ctx, boolean useJsonB) { + private final Map jsonTypes; + + ControllerMethodWriter( + MethodReader method, + Append writer, + ProcessingContext ctx, + boolean useJsonB, + Map jsonTypes) { this.method = method; this.writer = writer; - this.webMethod = method.getWebMethod(); + webMethod = method.getWebMethod(); this.ctx = ctx; this.useJsonB = useJsonB; + this.jsonTypes=jsonTypes; } void writeRule() { @@ -36,11 +50,20 @@ void writeHandler(boolean requestScoped) { final var bodyType = method.getBodyType(); if (bodyType != null) { if (useJsonB) { + + final var jsonbType = + method.getParams().stream() + .filter(MethodParam::isBody) + .findFirst() + .orElseThrow() + .getUType() + .full() + .transform(jsonTypes::get); writer - .append( - " var %s = %sBodyJsonType.fromJson(req.content().inputStream());", - method.getBodyName(), method.simpleName()) - .eol(); + .append( + " var %s = %sJsonType.fromJson(req.content().inputStream());", + method.getBodyName(), jsonbType.fieldName()) + .eol(); } else { // use default helidon content negotiation @@ -103,7 +126,11 @@ void writeHandler(boolean requestScoped) { if (!method.isVoid()) { writeContextReturn(); if (producesJson()) { - writer.append(" %sReturnedJsonType.toJson(result, res.outputStream());", method.simpleName()).eol(); + + final var jsonbType = method.getReturnType().toString().transform(jsonTypes::get); + writer + .append(" %sJsonType.toJson(result, res.outputStream());", jsonbType.fieldName()) + .eol(); } else { writer.append(" res.send(result);").eol(); } diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java index b5a2cd279..9ecbb622e 100644 --- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java +++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java @@ -1,7 +1,9 @@ package io.avaje.http.generator.helidon.nima; import java.io.IOException; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Optional; import javax.lang.model.type.DeclaredType; @@ -12,19 +14,25 @@ import io.avaje.http.generator.core.MethodParam; import io.avaje.http.generator.core.MethodReader; import io.avaje.http.generator.core.ProcessingContext; +import io.avaje.http.generator.core.UType; /** Write Helidon specific web route adapter (a Helidon Service). */ class ControllerWriter extends BaseControllerWriter { private static final String AT_GENERATED = "@Generated(\"avaje-helidon-nima-generator\")"; private final boolean useJsonB; + private final Map jsonTypes; - ControllerWriter(ControllerReader reader, ProcessingContext ctx, boolean jsonB) throws IOException { + ControllerWriter(ControllerReader reader, ProcessingContext ctx, boolean jsonB) + throws IOException { super(reader, ctx); - this.useJsonB = jsonB; + useJsonB = jsonB; if (useJsonB) { reader.addImportType("io.avaje.jsonb.Jsonb"); reader.addImportType("io.avaje.jsonb.JsonType"); + jsonTypes = new HashMap<>(); + } else { + jsonTypes = null; } reader.addImportType("io.helidon.common.http.HttpMediaType"); reader.addImportType("io.helidon.common.parameters.Parameters"); @@ -46,7 +54,7 @@ void write() { private List getWriterMethods() { return reader.getMethods().stream() .filter(MethodReader::isWebMethod) - .map(it -> new ControllerMethodWriter(it, writer, ctx, useJsonB)) + .map(it -> new ControllerMethodWriter(it, writer, ctx, useJsonB, jsonTypes)) .toList(); } @@ -88,17 +96,16 @@ private void writeClassStart() { writer.append(" private final Validator validator;").eol(); } - List jsonMethods; if (useJsonB) { - jsonMethods = + + final var jsonMethods = reader.getMethods().stream() .filter(MethodReader::isWebMethod) .filter(m -> !"byte[]".equals(m.getReturnType().toString())) - .filter(m -> m.getProduces() == null || m.getProduces().toLowerCase().contains("json")) + .filter( + m -> m.getProduces() == null || m.getProduces().toLowerCase().contains("json")) .toList(); writeJsonBTypeFields(jsonMethods); - } else { - jsonMethods = null; } writer.eol(); @@ -115,126 +122,112 @@ private void writeClassStart() { writer.append(" this.validator = validator;").eol(); } if (useJsonB) { - writeJsonBTypeAssignments(jsonMethods); + writeJsonBTypeAssignments(); } writer.append(" }").eol().eol(); } public void writeJsonBTypeFields(List jsonMethods) { for (final MethodReader methodReader : jsonMethods) { - // body types - if (methodReader.getBodyType() != null) { - methodReader.getParams().stream() - .filter(MethodParam::isBody) - .forEach( - param -> - writer - .append( - " private final JsonType<%s> %sBodyJsonType;", - param.getUType().full(), methodReader.simpleName()) - .eol()); - } + writeFieldJsonBodyType(methodReader); if (methodReader.isVoid()) { continue; } - - // return types - if (methodReader.getReturnType() instanceof final DeclaredType fullType) { - final var typeArgs = fullType.getTypeArguments(); - final var typeArgSize = typeArgs.size(); - - writer.append(" private final JsonType<"); - switch (typeArgSize) { - case 1 -> { - if (fullType.toString().contains("java.util.Set")) - writer.append("java.util.Set<%s>>", typeArgs.get(0)); - else writer.append("java.util.List<%s>>", typeArgs.get(0)); - } - case 2 -> writer.append("java.util.Map>", typeArgs.get(1)); - default -> writer.append("%s>", fullType); - } - writer.append(" %sReturnedJsonType;", methodReader.simpleName()).eol(); - } else { - throw new UnsupportedOperationException("Only Objects are supported with Jsonb Return Types"); - } + writeFieldJsonReturnType(methodReader); } - } - - public void writeJsonBTypeAssignments(List jsonMethods) { - for (final MethodReader methodReader : jsonMethods) { - // body types - writeBodyJsonType(methodReader); - if (methodReader.isVoid()) { - continue; - } - writeReturnJsonType(methodReader); - } - } - - private void writeBodyJsonType(MethodReader methodReader) { + } public void writeFieldJsonBodyType(MethodReader methodReader) { + // body types if (methodReader.getBodyType() != null) { methodReader.getParams().stream() .filter(MethodParam::isBody) .forEach( - p -> { - final var type = p.getUType(); - final var jsonType = - Optional.ofNullable(type.param1()) - .or(() -> Optional.ofNullable(type.param0())) - .orElseGet(type::full); - writer.append( - " this.%sBodyJsonType = jsonB.type(%s.class)", - methodReader.simpleName(), jsonType); - - if (type.param0() != null) { - writer.append("."); - switch (type.mainType()) { - case "java.util.List" -> writer.append("list"); - case "java.util.Map" -> writer.append("map"); - case "java.util.Set" -> writer.append("set"); - default -> throw new UnsupportedOperationException( - "Only java.util Map, Set and List are supported JsonB Controller Body Return Types"); - } - writer.append("()"); - } - writer.append(";").eol(); + param -> { + final var fullType = param.getUType().full(); + jsonTypes.computeIfAbsent( + fullType, + k -> { + final var baseType = getBaseType(param.getUType()); + final var fieldName = createFieldName(baseType, k); + writer.append("private final JsonType<%s> %sJsonType;", k, fieldName).eol(); + return new JsonbType(baseType, fieldName); + }); }); } } - void writeReturnJsonType(MethodReader methodReader) { + public void writeFieldJsonReturnType(MethodReader methodReader) { + + // return types if (methodReader.getReturnType() instanceof final DeclaredType fullType) { - final var typeArgs = fullType.getTypeArguments(); - final var typeArgSize = typeArgs.size(); - final var jsonType = - switch (typeArgSize) { - case 1 -> typeArgs.get(0); - case 2 -> typeArgs.get(1); - default -> fullType; - }; - - writer.append( - " this.%sReturnedJsonType = jsonB.type(%s.class)", - methodReader.simpleName(), jsonType); - final var returnType = fullType.toString(); - if (typeArgSize != 0) { - writer.append("."); + final var fullTypeString = fullType.toString(); + jsonTypes.computeIfAbsent( + fullTypeString, + k -> { + final var baseType = getBaseType(fullType); + final var fieldName = createFieldName(baseType, k); + writer.append("private final JsonType<%s> %sJsonType;", k, fieldName).eol(); + return new JsonbType(baseType, fieldName); + }); + } else { + throw new UnsupportedOperationException("Only Objects are supported with Jsonb Return Types"); + } + } + + public void writeJsonBTypeAssignments() { + for (final var entry : jsonTypes.entrySet()) { + final var fullType = entry.getKey(); + final var element = entry.getValue(); + final var fieldName = element.fieldName(); + final var baseType = element.baseType(); - switch (returnType.substring(0, 13)) { + writer.append(" this.%sJsonType = jsonB.type(%s.class)", fieldName, baseType); + + if (fullType.contains("<")) { + writer.append("."); + switch (fullType.substring(0, 13)) { case "java.util.Lis" -> writer.append("list"); case "java.util.Map" -> writer.append("map"); case "java.util.Set" -> writer.append("set"); default -> throw new UnsupportedOperationException( - "Only java.util Map, Set and List are supported JsonB Controller Collection Return Types"); + "Only java.util Map, Set and List are supported JsonB Controller Collection Types"); } - writer.append("()"); } writer.append(";").eol(); - - } else { - throw new UnsupportedOperationException("Only Objects and Strings are supported with Jsonb Controller Return Types"); } } + + public static String getBaseType(UType type) { + + return Optional.ofNullable(type.param1()) + .or(() -> Optional.ofNullable(type.param0())) + .orElseGet(type::full); + } + + private static String getBaseType(DeclaredType type) { + final var typeArgs = type.getTypeArguments(); + return switch (typeArgs.size()) { + case 1 -> typeArgs.get(0).toString(); + + case 2 -> typeArgs.get(1).toString(); + default -> type.toString(); + }; + } + + private static String createFieldName(String baseType, String fullType) { + final var shortType = + baseType + .substring(baseType.lastIndexOf('.') + 1) + .transform(str -> str.substring(0, 1).toLowerCase() + str.substring(1)); + + if (shortType.length() <= 13) return shortType; + + return switch (fullType.substring(0, 13)) { + case "java.util.Lis" -> "List"; + case "java.util.Map" -> "Map"; + case "java.util.Set" -> "Set"; + default -> ""; + }; + } } diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/JsonbType.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/JsonbType.java new file mode 100644 index 000000000..3ea73bf9b --- /dev/null +++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/JsonbType.java @@ -0,0 +1,3 @@ +package io.avaje.http.generator.helidon.nima; + +public record JsonbType(String baseType, String fieldName) {} From d7ac4f5e20355b7e7bf6d246f6f01b9d5845c55c Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Mon, 17 Oct 2022 14:48:43 -0400 Subject: [PATCH 0354/1323] fix field creation --- .../avaje/http/generator/helidon/nima/ControllerWriter.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java index 9ecbb622e..ad49cd60f 100644 --- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java +++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java @@ -221,13 +221,13 @@ private static String createFieldName(String baseType, String fullType) { .substring(baseType.lastIndexOf('.') + 1) .transform(str -> str.substring(0, 1).toLowerCase() + str.substring(1)); - if (shortType.length() <= 13) return shortType; + if (fullType.length() <= 13) return shortType; return switch (fullType.substring(0, 13)) { case "java.util.Lis" -> "List"; case "java.util.Map" -> "Map"; case "java.util.Set" -> "Set"; - default -> ""; + default -> shortType; }; } } From 532fc3b93676b929caef65f6ffce5377b4d227f1 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Mon, 17 Oct 2022 15:27:16 -0400 Subject: [PATCH 0355/1323] primitive return types --- .../helidon/nima/ControllerWriter.java | 20 ++++++++- .../java/org/example/HelloController.java | 41 +++++++++++++++---- 2 files changed, 50 insertions(+), 11 deletions(-) diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java index ad49cd60f..04310e104 100644 --- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java +++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java @@ -7,6 +7,7 @@ import java.util.Optional; import javax.lang.model.type.DeclaredType; +import javax.lang.model.type.PrimitiveType; import io.avaje.http.generator.core.BaseControllerWriter; import io.avaje.http.generator.core.Constants; @@ -136,7 +137,9 @@ public void writeJsonBTypeFields(List jsonMethods) { } writeFieldJsonReturnType(methodReader); } - } public void writeFieldJsonBodyType(MethodReader methodReader) { + } + + public void writeFieldJsonBodyType(MethodReader methodReader) { // body types if (methodReader.getBodyType() != null) { methodReader.getParams().stream() @@ -158,6 +161,8 @@ public void writeJsonBTypeFields(List jsonMethods) { public void writeFieldJsonReturnType(MethodReader methodReader) { + methodReader.getReturnType().getKind(); + // return types if (methodReader.getReturnType() instanceof final DeclaredType fullType) { final var fullTypeString = fullType.toString(); @@ -169,8 +174,19 @@ public void writeFieldJsonReturnType(MethodReader methodReader) { writer.append("private final JsonType<%s> %sJsonType;", k, fieldName).eol(); return new JsonbType(baseType, fieldName); }); + } else if (methodReader.getReturnType() instanceof final PrimitiveType fullType) { + + jsonTypes.computeIfAbsent( + fullType.toString(), + k -> { + final var baseType = + "int".equals(k) ? "Integer" : k.substring(0, 1).toUpperCase() + k.substring(1); + writer.append("private final JsonType<%s> %sJsonType;", baseType, k).eol(); + return new JsonbType(baseType, k); + }); } else { - throw new UnsupportedOperationException("Only Objects are supported with Jsonb Return Types"); + throw new UnsupportedOperationException( + "Only Primitives and Objects are supported with Jsonb Return Types"); } } diff --git a/tests/test-nima-jsonb/src/main/java/org/example/HelloController.java b/tests/test-nima-jsonb/src/main/java/org/example/HelloController.java index 1c043c259..a157b4fac 100644 --- a/tests/test-nima-jsonb/src/main/java/org/example/HelloController.java +++ b/tests/test-nima-jsonb/src/main/java/org/example/HelloController.java @@ -1,14 +1,20 @@ package org.example; -import io.avaje.http.api.*; -import io.helidon.common.http.HttpMediaType; -import io.helidon.nima.webserver.http.ServerRequest; -import io.helidon.nima.webserver.http.ServerResponse; - import java.util.List; import java.util.Map; import java.util.Set; +import io.avaje.http.api.Controller; +import io.avaje.http.api.Form; +import io.avaje.http.api.Get; +import io.avaje.http.api.MediaType; +import io.avaje.http.api.Post; +import io.avaje.http.api.Produces; +import io.avaje.http.api.Put; +import io.helidon.common.http.HttpMediaType; +import io.helidon.nima.webserver.http.ServerRequest; +import io.helidon.nima.webserver.http.ServerResponse; + @Controller public class HelloController { @@ -47,7 +53,13 @@ Person person(String name) { return new Person(42, name + " hello"); } - // curl -X POST http://localhost:8081/person -H 'Content-Type: application/json' -d '{"id":942,"name":"Jimmy"}' + @Get("person/{long}") + Person testLong(long id) { + return new Person(id, "Giorno hello"); + } + + // curl -X POST http://localhost:8081/person -H 'Content-Type: application/json' -d + // '{"id":942,"name":"Jimmy"}' @Post("/person") Person postPerson(Person body) { return new Person(42, "Returning " + body.name()); @@ -80,18 +92,29 @@ String addMultiple(List newGuys) { return "New Guys Added"; } - // curl -X POST http://localhost:8081/form -H "Content-Type: application/x-www-form-urlencoded" -d "name=Jimmy&email=jim@foo&url=notaurl" + @Put("person/int") + int testIntReturn() { + return 422; + } + + @Put("person/long") + long testLongReturn() { + return 69; + } + + // curl -X POST http://localhost:8081/form -H "Content-Type: application/x-www-form-urlencoded" -d + // "name=Jimmy&email=jim@foo&url=notaurl" @Form @Post("form") String form(String name, String email, String url) { return name + "-" + email + "-" + url; } - // curl -X POST http://localhost:8081/formBean -H "Content-Type: application/x-www-form-urlencoded" -d "name=FormBeanJimmy&email=jim@foo&url=notaurl" + // curl -X POST http://localhost:8081/formBean -H "Content-Type: + // application/x-www-form-urlencoded" -d "name=FormBeanJimmy&email=jim@foo&url=notaurl" @Form @Post("formBean") String formBean(MyForm form) { return form.name + "-" + form.email + "-" + form.url; } - } From 98df8c0084d45f68e54c1cf386b0514db46aefda Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Mon, 17 Oct 2022 15:50:42 -0400 Subject: [PATCH 0356/1323] rename k --- .../helidon/nima/ControllerWriter.java | 22 +++++++++---------- 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java index 04310e104..1d4982d70 100644 --- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java +++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java @@ -149,10 +149,10 @@ public void writeFieldJsonBodyType(MethodReader methodReader) { final var fullType = param.getUType().full(); jsonTypes.computeIfAbsent( fullType, - k -> { + type -> { final var baseType = getBaseType(param.getUType()); - final var fieldName = createFieldName(baseType, k); - writer.append("private final JsonType<%s> %sJsonType;", k, fieldName).eol(); + final var fieldName = createFieldName(baseType, type); + writer.append("private final JsonType<%s> %sJsonType;", type, fieldName).eol(); return new JsonbType(baseType, fieldName); }); }); @@ -161,28 +161,26 @@ public void writeFieldJsonBodyType(MethodReader methodReader) { public void writeFieldJsonReturnType(MethodReader methodReader) { - methodReader.getReturnType().getKind(); - // return types if (methodReader.getReturnType() instanceof final DeclaredType fullType) { final var fullTypeString = fullType.toString(); jsonTypes.computeIfAbsent( fullTypeString, - k -> { + type -> { final var baseType = getBaseType(fullType); - final var fieldName = createFieldName(baseType, k); - writer.append("private final JsonType<%s> %sJsonType;", k, fieldName).eol(); + final var fieldName = createFieldName(baseType, type); + writer.append("private final JsonType<%s> %sJsonType;", type, fieldName).eol(); return new JsonbType(baseType, fieldName); }); } else if (methodReader.getReturnType() instanceof final PrimitiveType fullType) { jsonTypes.computeIfAbsent( fullType.toString(), - k -> { + type -> { final var baseType = - "int".equals(k) ? "Integer" : k.substring(0, 1).toUpperCase() + k.substring(1); - writer.append("private final JsonType<%s> %sJsonType;", baseType, k).eol(); - return new JsonbType(baseType, k); + "int".equals(type) ? "Integer" : type.substring(0, 1).toUpperCase() + type.substring(1); + writer.append("private final JsonType<%s> %sJsonType;", baseType, type).eol(); + return new JsonbType(baseType, type); }); } else { throw new UnsupportedOperationException( From 99edb00fee17465b02d84237618271670b65e8f7 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Mon, 17 Oct 2022 15:51:58 -0400 Subject: [PATCH 0357/1323] Update ControllerWriter.java --- .../avaje/http/generator/helidon/nima/ControllerWriter.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java index 1d4982d70..716e60847 100644 --- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java +++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java @@ -178,7 +178,9 @@ public void writeFieldJsonReturnType(MethodReader methodReader) { fullType.toString(), type -> { final var baseType = - "int".equals(type) ? "Integer" : type.substring(0, 1).toUpperCase() + type.substring(1); + "int".equals(type) + ? "Integer" + : type.substring(0, 1).toUpperCase() + type.substring(1); writer.append("private final JsonType<%s> %sJsonType;", baseType, type).eol(); return new JsonbType(baseType, type); }); From e44937462dd7dda0b32a98a8bb74cc550a223da1 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Mon, 17 Oct 2022 15:58:16 -0400 Subject: [PATCH 0358/1323] Update ControllerMethodWriter.java --- .../helidon/nima/ControllerMethodWriter.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java index 085122bc8..7568ebace 100644 --- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java +++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java @@ -51,18 +51,19 @@ void writeHandler(boolean requestScoped) { if (bodyType != null) { if (useJsonB) { - final var jsonbType = + final var fieldName = method.getParams().stream() .filter(MethodParam::isBody) .findFirst() .orElseThrow() .getUType() .full() - .transform(jsonTypes::get); + .transform(jsonTypes::get) + .fieldName(); writer .append( " var %s = %sJsonType.fromJson(req.content().inputStream());", - method.getBodyName(), jsonbType.fieldName()) + method.getBodyName(), fieldName) .eol(); } else { @@ -127,10 +128,9 @@ void writeHandler(boolean requestScoped) { writeContextReturn(); if (producesJson()) { - final var jsonbType = method.getReturnType().toString().transform(jsonTypes::get); - writer - .append(" %sJsonType.toJson(result, res.outputStream());", jsonbType.fieldName()) - .eol(); + final var fieldName = + method.getReturnType().toString().transform(jsonTypes::get).fieldName(); + writer.append(" %sJsonType.toJson(result, res.outputStream());", fieldName).eol(); } else { writer.append(" res.send(result);").eol(); } From 67f79624aab9063b2b63e6d111932b1fd458c986 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Mon, 17 Oct 2022 23:45:47 -0400 Subject: [PATCH 0359/1323] don't need a whole record --- .gitignore | 15 ++++----------- .../helidon/nima/ControllerMethodWriter.java | 9 +++++---- .../helidon/nima/ControllerWriter.java | 17 ++++++++++------- .../http/generator/helidon/nima/JsonbType.java | 3 --- 4 files changed, 19 insertions(+), 25 deletions(-) delete mode 100644 http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/JsonbType.java diff --git a/.gitignore b/.gitignore index 5b2b16770..df115eb72 100644 --- a/.gitignore +++ b/.gitignore @@ -3,15 +3,8 @@ build/ .idea/ *.iml .gradle -http-generator-nima/.settings/org.eclipse.m2e.core.prefs -http-generator-nima/.settings/org.eclipse.jdt.core.prefs -http-generator-nima/.settings/org.eclipse.jdt.apt.core.prefs -http-generator-nima/.settings/org.eclipse.core.resources.prefs -http-generator-nima/.project -http-generator-nima/.classpath *.prefs -tests/test-nima/.classpath -tests/test-nima/.factorypath -tests/test-nima/.project -*.class -tests/test-nima-jsonb/.classpath +*.class* +*.factorypath +*.project +*.processors diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java index 7568ebace..6a4d8aff0 100644 --- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java +++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java @@ -1,5 +1,6 @@ package io.avaje.http.generator.helidon.nima; +import java.util.AbstractMap.SimpleImmutableEntry; import java.util.List; import java.util.Map; import java.util.Optional; @@ -23,14 +24,14 @@ class ControllerMethodWriter { private final WebMethod webMethod; private final ProcessingContext ctx; private final boolean useJsonB; - private final Map jsonTypes; + private final Map> jsonTypes; ControllerMethodWriter( MethodReader method, Append writer, ProcessingContext ctx, boolean useJsonB, - Map jsonTypes) { + Map> jsonTypes) { this.method = method; this.writer = writer; webMethod = method.getWebMethod(); @@ -59,7 +60,7 @@ void writeHandler(boolean requestScoped) { .getUType() .full() .transform(jsonTypes::get) - .fieldName(); + .getValue(); writer .append( " var %s = %sJsonType.fromJson(req.content().inputStream());", @@ -129,7 +130,7 @@ void writeHandler(boolean requestScoped) { if (producesJson()) { final var fieldName = - method.getReturnType().toString().transform(jsonTypes::get).fieldName(); + method.getReturnType().toString().transform(jsonTypes::get).getValue(); writer.append(" %sJsonType.toJson(result, res.outputStream());", fieldName).eol(); } else { writer.append(" res.send(result);").eol(); diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java index 716e60847..fd7bcad67 100644 --- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java +++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java @@ -1,6 +1,7 @@ package io.avaje.http.generator.helidon.nima; import java.io.IOException; +import java.util.AbstractMap.SimpleImmutableEntry; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -22,7 +23,7 @@ class ControllerWriter extends BaseControllerWriter { private static final String AT_GENERATED = "@Generated(\"avaje-helidon-nima-generator\")"; private final boolean useJsonB; - private final Map jsonTypes; + private final Map> jsonTypes; ControllerWriter(ControllerReader reader, ProcessingContext ctx, boolean jsonB) throws IOException { @@ -152,8 +153,10 @@ public void writeFieldJsonBodyType(MethodReader methodReader) { type -> { final var baseType = getBaseType(param.getUType()); final var fieldName = createFieldName(baseType, type); - writer.append("private final JsonType<%s> %sJsonType;", type, fieldName).eol(); - return new JsonbType(baseType, fieldName); + writer + .append("private final JsonType<%s> %sJsonType;", type, fieldName) + .eol(); + return new SimpleImmutableEntry<>(baseType, fieldName); }); }); } @@ -170,7 +173,7 @@ public void writeFieldJsonReturnType(MethodReader methodReader) { final var baseType = getBaseType(fullType); final var fieldName = createFieldName(baseType, type); writer.append("private final JsonType<%s> %sJsonType;", type, fieldName).eol(); - return new JsonbType(baseType, fieldName); + return new SimpleImmutableEntry<>(baseType, fieldName); }); } else if (methodReader.getReturnType() instanceof final PrimitiveType fullType) { @@ -182,7 +185,7 @@ public void writeFieldJsonReturnType(MethodReader methodReader) { ? "Integer" : type.substring(0, 1).toUpperCase() + type.substring(1); writer.append("private final JsonType<%s> %sJsonType;", baseType, type).eol(); - return new JsonbType(baseType, type); + return new SimpleImmutableEntry<>(baseType, type); }); } else { throw new UnsupportedOperationException( @@ -194,8 +197,8 @@ public void writeJsonBTypeAssignments() { for (final var entry : jsonTypes.entrySet()) { final var fullType = entry.getKey(); final var element = entry.getValue(); - final var fieldName = element.fieldName(); - final var baseType = element.baseType(); + final var baseType = element.getKey(); + final var fieldName = element.getValue(); writer.append(" this.%sJsonType = jsonB.type(%s.class)", fieldName, baseType); diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/JsonbType.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/JsonbType.java deleted file mode 100644 index 3ea73bf9b..000000000 --- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/JsonbType.java +++ /dev/null @@ -1,3 +0,0 @@ -package io.avaje.http.generator.helidon.nima; - -public record JsonbType(String baseType, String fieldName) {} From a77a2371d465116a5110890bac37845082f72926 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Mon, 17 Oct 2022 23:46:26 -0400 Subject: [PATCH 0360/1323] Update .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index df115eb72..1e7ecad3f 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ build/ *.factorypath *.project *.processors +*/bin/ From c6da43a2503c8da915f2e4ee8428f618d8bb931e Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 18 Oct 2022 21:56:22 +1300 Subject: [PATCH 0361/1323] nima-generator - Use UType to simplify Jsonb types and names --- .../io/avaje/http/generator/core/UType.java | 31 +++ .../io/avaje/http/generator/core/Util.java | 28 ++- .../avaje/http/generator/core/UtilTest.java | 21 ++ .../helidon/nima/ControllerMethodWriter.java | 31 +-- .../helidon/nima/ControllerWriter.java | 200 +++++------------- .../generator/helidon/nima/PrimitiveUtil.java | 24 +++ 6 files changed, 160 insertions(+), 175 deletions(-) create mode 100644 http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/PrimitiveUtil.java diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java index 788f3669f..eb3fb2cd8 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java @@ -16,6 +16,11 @@ public interface UType { */ String shortType(); + /** + * Return the short name. + */ + String shortName(); + /** * Return the main type (outer most type). */ @@ -40,6 +45,10 @@ default String param1() { */ String full(); + default boolean isGeneric() { + return false; + } + default String genericParams() { return ""; } @@ -56,6 +65,11 @@ public String shortType() { return "void"; } + @Override + public String shortName() { + return "void"; + } + @Override public String mainType() { return "java.lang.Void"; @@ -92,6 +106,11 @@ public String shortType() { return Util.shortName(rawType); } + @Override + public String shortName() { + return Util.initLower(shortType()); + } + @Override public String mainType() { return rawType; @@ -105,11 +124,13 @@ class Generic implements UType { final String rawType; final List allTypes; final String shortRawType; + final String shortName; Generic(String rawTypeInput) { this.rawType = rawTypeInput.replace(" ",""); // trim whitespace this.allTypes = Arrays.asList(rawType.split("[<|>|,]")); this.shortRawType = shortRawType(rawType, allTypes); + this.shortName = Util.name(shortRawType); } private String shortRawType(String rawType, List allTypes) { @@ -140,6 +161,11 @@ public Set importTypes() { return set; } + @Override + public boolean isGeneric() { + return true; + } + @Override public String genericParams() { final StringJoiner joiner = new StringJoiner(","); @@ -157,6 +183,11 @@ public String shortType() { return shortRawType; } + @Override + public String shortName() { + return shortName; + } + @Override public String mainType() { return allTypes.isEmpty() ? null : allTypes.get(0); diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/Util.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/Util.java index c948cef6e..09d47dc46 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/Util.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/Util.java @@ -70,10 +70,15 @@ public static String shortName(String fullType) { } } - public static String snakeCase(String name) { + /** + * Return a field or variable name to match the short type. + */ + public static String name(String name) { + return initLower(name.replaceAll("([,<>\\[\\]])", "")); + } + public static String snakeCase(String name) { StringBuilder sb = new StringBuilder(name.length() + 5); - int len = name.length(); for (int i = 0; i < len; i++) { char ch = name.charAt(i); @@ -89,11 +94,22 @@ public static String snakeCase(String name) { return sb.toString(); } - public static String initcap(String input) { + public static String initLower(String input) { if (input.length() < 2) { - return input.toUpperCase(); + return input.toLowerCase(); } else { - return Character.toUpperCase(input.charAt(0)) + input.substring(1); + StringBuilder sb = new StringBuilder(input.length()); + sb.append(Character.toLowerCase(input.charAt(0))); + int i = 1; + for (; i < input.length(); i++) { + if (Character.isUpperCase(input.charAt(i))) { + sb.append(Character.toLowerCase(input.charAt(i))); + } else { + sb.append(input.substring(i)); + break; + } + } + return sb.toString(); } } @@ -158,7 +174,7 @@ public static UType parseType(TypeMirror returnType) { if (returnType.getKind() == TypeKind.VOID) { return UType.VOID; } - return parse(returnType.toString());//typeDef(returnType)); + return parse(returnType.toString()); } private static class RoleReader extends SimpleAnnotationValueVisitor8, Object> { diff --git a/http-generator-core/src/test/java/io/avaje/http/generator/core/UtilTest.java b/http-generator-core/src/test/java/io/avaje/http/generator/core/UtilTest.java index c04da033d..25a922705 100644 --- a/http-generator-core/src/test/java/io/avaje/http/generator/core/UtilTest.java +++ b/http-generator-core/src/test/java/io/avaje/http/generator/core/UtilTest.java @@ -80,6 +80,7 @@ void parse_basic() { assertThat(type.importTypes()).containsExactly("org.example.Repo"); assertThat(type.shortType()).isEqualTo("Repo"); + assertThat(type.shortName()).isEqualTo("repo"); } @Test @@ -88,6 +89,7 @@ void parse_generic() { assertThat(type.importTypes()).containsExactly("java.util.List", "org.example.Repo"); assertThat(type.shortType()).isEqualTo("List"); + assertThat(type.shortName()).isEqualTo("listRepo"); } @Test @@ -128,6 +130,7 @@ void parse_CompletableFutureStreamBean() { assertThat(type.importTypes()).containsExactly("java.util.concurrent.CompletableFuture", "java.util.Stream", "org.example.Repo"); assertThat(type.shortType()).isEqualTo("CompletableFuture>"); + assertThat(type.shortName()).isEqualTo("completableFutureStreamRepo"); } @Test @@ -145,6 +148,7 @@ void parse_BodyHandler_Path() { assertThat(type.importTypes()).containsExactly("java.net.http.HttpResponse.BodyHandler", "java.util.Path"); assertThat(type.shortType()).isEqualTo("BodyHandler"); + assertThat(type.shortName()).isEqualTo("bodyHandlerPath"); assertThat(type.genericParams()).isEqualTo(""); } @@ -154,6 +158,7 @@ void parse_BodyHandler_Multi() { assertThat(type.importTypes()).containsExactly("java.net.http.HttpResponse.BodyHandler", "some.Foo"); assertThat(type.shortType()).isEqualTo("BodyHandler>"); + assertThat(type.shortName()).isEqualTo("bodyHandlerFooAB"); assertThat(type.genericParams()).isEqualTo(" "); } @@ -163,6 +168,22 @@ void parse_BodyHandler_Multi2() { assertThat(type.importTypes()).containsExactly("java.net.http.HttpResponse.BodyHandler", "some.Foo", "some.Bar"); assertThat(type.shortType()).isEqualTo("BodyHandler>>"); + assertThat(type.shortName()).isEqualTo("bodyHandlerFooABBCBarD"); assertThat(type.genericParams()).isEqualTo(" "); } + + @Test + void utypeShortName() { + UType type = Util.parse("java.util.Map"); + assertThat(type.shortName()).isEqualTo("mapStringPerson"); + assertThat(type.shortType()).isEqualTo("Map"); + } + + @Test + void shortName() { + assertThat(Util.name("List")).isEqualTo("listPerson"); + assertThat(Util.name("Set")).isEqualTo("setPerson"); + assertThat(Util.name("Map")).isEqualTo("mapStringPerson"); + } + } diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java index 6a4d8aff0..57b9e51b9 100644 --- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java +++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java @@ -1,19 +1,12 @@ package io.avaje.http.generator.helidon.nima; -import java.util.AbstractMap.SimpleImmutableEntry; +import io.avaje.http.api.MediaType; +import io.avaje.http.generator.core.*; + import java.util.List; import java.util.Map; import java.util.Optional; -import io.avaje.http.api.MediaType; -import io.avaje.http.generator.core.Append; -import io.avaje.http.generator.core.MethodParam; -import io.avaje.http.generator.core.MethodReader; -import io.avaje.http.generator.core.ParamType; -import io.avaje.http.generator.core.PathSegments; -import io.avaje.http.generator.core.ProcessingContext; -import io.avaje.http.generator.core.WebMethod; - /** * Write code to register Web route for a given controller method. */ @@ -24,14 +17,14 @@ class ControllerMethodWriter { private final WebMethod webMethod; private final ProcessingContext ctx; private final boolean useJsonB; - private final Map> jsonTypes; + private final Map jsonTypes; ControllerMethodWriter( MethodReader method, Append writer, ProcessingContext ctx, boolean useJsonB, - Map> jsonTypes) { + Map jsonTypes) { this.method = method; this.writer = writer; webMethod = method.getWebMethod(); @@ -51,19 +44,16 @@ void writeHandler(boolean requestScoped) { final var bodyType = method.getBodyType(); if (bodyType != null) { if (useJsonB) { - final var fieldName = method.getParams().stream() .filter(MethodParam::isBody) .findFirst() .orElseThrow() .getUType() - .full() - .transform(jsonTypes::get) - .getValue(); + .shortName(); writer .append( - " var %s = %sJsonType.fromJson(req.content().inputStream());", + " var %s = %sJsonType.fromJson(req.content().inputStream()); // RB1", method.getBodyName(), fieldName) .eol(); @@ -128,10 +118,9 @@ void writeHandler(boolean requestScoped) { if (!method.isVoid()) { writeContextReturn(); if (producesJson()) { - - final var fieldName = - method.getReturnType().toString().transform(jsonTypes::get).getValue(); - writer.append(" %sJsonType.toJson(result, res.outputStream());", fieldName).eol(); + UType uType = Util.parseType(method.getReturnType()); + final var fieldName = uType.shortName(); + writer.append(" %sJsonType.toJson(result, res.outputStream()); // RB0", fieldName).eol(); } else { writer.append(" res.send(result);").eol(); } diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java index fd7bcad67..d21994a43 100644 --- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java +++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java @@ -1,40 +1,26 @@ package io.avaje.http.generator.helidon.nima; import java.io.IOException; -import java.util.AbstractMap.SimpleImmutableEntry; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Optional; - -import javax.lang.model.type.DeclaredType; -import javax.lang.model.type.PrimitiveType; - -import io.avaje.http.generator.core.BaseControllerWriter; -import io.avaje.http.generator.core.Constants; -import io.avaje.http.generator.core.ControllerReader; -import io.avaje.http.generator.core.MethodParam; -import io.avaje.http.generator.core.MethodReader; -import io.avaje.http.generator.core.ProcessingContext; -import io.avaje.http.generator.core.UType; +import java.util.*; + +import javax.lang.model.type.TypeMirror; + +import io.avaje.http.generator.core.*; /** Write Helidon specific web route adapter (a Helidon Service). */ class ControllerWriter extends BaseControllerWriter { private static final String AT_GENERATED = "@Generated(\"avaje-helidon-nima-generator\")"; private final boolean useJsonB; - private final Map> jsonTypes; + private final Map jsonTypes = new LinkedHashMap<>(); - ControllerWriter(ControllerReader reader, ProcessingContext ctx, boolean jsonB) - throws IOException { + ControllerWriter(ControllerReader reader, ProcessingContext ctx, boolean jsonB) throws IOException { super(reader, ctx); - useJsonB = jsonB; + this.useJsonB = jsonB; if (useJsonB) { reader.addImportType("io.avaje.jsonb.Jsonb"); reader.addImportType("io.avaje.jsonb.JsonType"); - jsonTypes = new HashMap<>(); - } else { - jsonTypes = null; + initJsonTypes(reader); } reader.addImportType("io.helidon.common.http.HttpMediaType"); reader.addImportType("io.helidon.common.parameters.Parameters"); @@ -45,6 +31,32 @@ class ControllerWriter extends BaseControllerWriter { reader.addImportType("io.helidon.nima.webserver.http.HttpService"); } + private void initJsonTypes(ControllerReader reader) { + reader.getMethods().stream() + .filter(MethodReader::isWebMethod) + .filter(m -> !"byte[]".equals(m.getReturnType().toString())) + .filter(m -> m.getProduces() == null || m.getProduces().toLowerCase().contains("json")) + .forEach(methodReader -> { + addJsonBodyType(methodReader); + if (!methodReader.isVoid()) { + TypeMirror returnType = methodReader.getReturnType(); + addJsonBodyType(Util.parseType(returnType)); + } + }); + } + + private void addJsonBodyType(UType type) { + jsonTypes.put(type.full(), type); + } + + private void addJsonBodyType(MethodReader methodReader) { + if (methodReader.getBodyType() != null) { + methodReader.getParams().stream() + .filter(MethodParam::isBody) + .forEach(param -> addJsonBodyType(param.getUType())); + } + } + void write() { writePackage(); writeImports(); @@ -97,17 +109,8 @@ private void writeClassStart() { if (reader.isIncludeValidator()) { writer.append(" private final Validator validator;").eol(); } - - if (useJsonB) { - - final var jsonMethods = - reader.getMethods().stream() - .filter(MethodReader::isWebMethod) - .filter(m -> !"byte[]".equals(m.getReturnType().toString())) - .filter( - m -> m.getProduces() == null || m.getProduces().toLowerCase().contains("json")) - .toList(); - writeJsonBTypeFields(jsonMethods); + for (UType value : jsonTypes.values()) { + writer.append("private final JsonType<%s> %sJsonType; //RBx1", primitiveWrap(value.full()), value.shortName()).eol(); } writer.eol(); @@ -124,129 +127,30 @@ private void writeClassStart() { writer.append(" this.validator = validator;").eol(); } if (useJsonB) { - writeJsonBTypeAssignments(); - } - writer.append(" }").eol().eol(); - } - - public void writeJsonBTypeFields(List jsonMethods) { - for (final MethodReader methodReader : jsonMethods) { - - writeFieldJsonBodyType(methodReader); - if (methodReader.isVoid()) { - continue; + for (UType value : jsonTypes.values()) { + writer.append(" this.%sJsonType = jsonB.type(", value.shortName()); + writeJsonbType(value); } - writeFieldJsonReturnType(methodReader); - } - } - - public void writeFieldJsonBodyType(MethodReader methodReader) { - // body types - if (methodReader.getBodyType() != null) { - methodReader.getParams().stream() - .filter(MethodParam::isBody) - .forEach( - param -> { - final var fullType = param.getUType().full(); - jsonTypes.computeIfAbsent( - fullType, - type -> { - final var baseType = getBaseType(param.getUType()); - final var fieldName = createFieldName(baseType, type); - writer - .append("private final JsonType<%s> %sJsonType;", type, fieldName) - .eol(); - return new SimpleImmutableEntry<>(baseType, fieldName); - }); - }); } + writer.append(" }").eol().eol(); } - public void writeFieldJsonReturnType(MethodReader methodReader) { - - // return types - if (methodReader.getReturnType() instanceof final DeclaredType fullType) { - final var fullTypeString = fullType.toString(); - jsonTypes.computeIfAbsent( - fullTypeString, - type -> { - final var baseType = getBaseType(fullType); - final var fieldName = createFieldName(baseType, type); - writer.append("private final JsonType<%s> %sJsonType;", type, fieldName).eol(); - return new SimpleImmutableEntry<>(baseType, fieldName); - }); - } else if (methodReader.getReturnType() instanceof final PrimitiveType fullType) { - - jsonTypes.computeIfAbsent( - fullType.toString(), - type -> { - final var baseType = - "int".equals(type) - ? "Integer" - : type.substring(0, 1).toUpperCase() + type.substring(1); - writer.append("private final JsonType<%s> %sJsonType;", baseType, type).eol(); - return new SimpleImmutableEntry<>(baseType, type); - }); + private void writeJsonbType(UType type) { + if (!type.isGeneric()) { + writer.append("%s.class)", type.full()); } else { - throw new UnsupportedOperationException( - "Only Primitives and Objects are supported with Jsonb Return Types"); - } - } - - public void writeJsonBTypeAssignments() { - for (final var entry : jsonTypes.entrySet()) { - final var fullType = entry.getKey(); - final var element = entry.getValue(); - final var baseType = element.getKey(); - final var fieldName = element.getValue(); - - writer.append(" this.%sJsonType = jsonB.type(%s.class)", fieldName, baseType); - - if (fullType.contains("<")) { - writer.append("."); - switch (fullType.substring(0, 13)) { - case "java.util.Lis" -> writer.append("list"); - case "java.util.Map" -> writer.append("map"); - case "java.util.Set" -> writer.append("set"); - default -> throw new UnsupportedOperationException( - "Only java.util Map, Set and List are supported JsonB Controller Collection Types"); - } - writer.append("()"); + switch (type.mainType()) { + case "java.util.List" -> writer.append("%s.class).list()", type.param0()); + case "java.util.Set" -> writer.append("%s.class).set()", type.param0()); + case "java.util.Map" -> writer.append("%s.class).map()", type.param1()); + default -> throw new UnsupportedOperationException("Only java.util Map, Set and List are supported JsonB Controller Collection Types"); } - writer.append(";").eol(); } + writer.append("; // Rbx3").eol(); } - public static String getBaseType(UType type) { - - return Optional.ofNullable(type.param1()) - .or(() -> Optional.ofNullable(type.param0())) - .orElseGet(type::full); + private String primitiveWrap(String full) { + return PrimitiveUtil.wrap(full); } - private static String getBaseType(DeclaredType type) { - final var typeArgs = type.getTypeArguments(); - return switch (typeArgs.size()) { - case 1 -> typeArgs.get(0).toString(); - - case 2 -> typeArgs.get(1).toString(); - default -> type.toString(); - }; - } - - private static String createFieldName(String baseType, String fullType) { - final var shortType = - baseType - .substring(baseType.lastIndexOf('.') + 1) - .transform(str -> str.substring(0, 1).toLowerCase() + str.substring(1)); - - if (fullType.length() <= 13) return shortType; - - return switch (fullType.substring(0, 13)) { - case "java.util.Lis" -> "List"; - case "java.util.Map" -> "Map"; - case "java.util.Set" -> "Set"; - default -> shortType; - }; - } } diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/PrimitiveUtil.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/PrimitiveUtil.java new file mode 100644 index 000000000..c7c6e727c --- /dev/null +++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/PrimitiveUtil.java @@ -0,0 +1,24 @@ +package io.avaje.http.generator.helidon.nima; + +import java.util.HashMap; +import java.util.Map; + +final class PrimitiveUtil { + + static Map wrapperMap = new HashMap<>(); + static { + wrapperMap.put("char", "Character"); + wrapperMap.put("byte", "Byte"); + wrapperMap.put("int", "Integer"); + wrapperMap.put("long", "Long"); + wrapperMap.put("short", "Short"); + wrapperMap.put("double", "Double"); + wrapperMap.put("float", "Float"); + wrapperMap.put("boolean", "Boolean"); + } + + static String wrap(String shortName) { + String wrapped = wrapperMap.get(shortName); + return wrapped != null ? wrapped : shortName; + } +} From 6c90974056fb41e39bfc0bcd30540aeafc6b3bee Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 18 Oct 2022 22:17:20 +1300 Subject: [PATCH 0362/1323] nima-generator - tidy up only --- .../io/avaje/http/generator/core/UType.java | 8 +++++ .../helidon/nima/ControllerMethodWriter.java | 22 ++++-------- .../helidon/nima/ControllerWriter.java | 35 +++++++++---------- .../java/org/example/HelloController.java | 16 +++++---- tests/test-nima/pom.xml | 4 +-- 5 files changed, 42 insertions(+), 43 deletions(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java index eb3fb2cd8..dd2f2d4d6 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java @@ -1,9 +1,17 @@ package io.avaje.http.generator.core; +import javax.lang.model.type.TypeMirror; import java.util.*; public interface UType { + /** + * Create the UType from the given TypeMirror. + */ + static UType parse(TypeMirror type) { + return Util.parseType(type); + } + UType VOID = new VoidType(); /** diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java index 57b9e51b9..375c040db 100644 --- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java +++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java @@ -17,20 +17,13 @@ class ControllerMethodWriter { private final WebMethod webMethod; private final ProcessingContext ctx; private final boolean useJsonB; - private final Map jsonTypes; - - ControllerMethodWriter( - MethodReader method, - Append writer, - ProcessingContext ctx, - boolean useJsonB, - Map jsonTypes) { + + ControllerMethodWriter(MethodReader method, Append writer, ProcessingContext ctx, boolean useJsonB) { this.method = method; this.writer = writer; - webMethod = method.getWebMethod(); + this.webMethod = method.getWebMethod(); this.ctx = ctx; this.useJsonB = useJsonB; - this.jsonTypes=jsonTypes; } void writeRule() { @@ -52,9 +45,7 @@ void writeHandler(boolean requestScoped) { .getUType() .shortName(); writer - .append( - " var %s = %sJsonType.fromJson(req.content().inputStream()); // RB1", - method.getBodyName(), fieldName) + .append(" var %s = %sJsonType.fromJson(req.content().inputStream());", method.getBodyName(), fieldName) .eol(); } else { @@ -118,9 +109,8 @@ void writeHandler(boolean requestScoped) { if (!method.isVoid()) { writeContextReturn(); if (producesJson()) { - UType uType = Util.parseType(method.getReturnType()); - final var fieldName = uType.shortName(); - writer.append(" %sJsonType.toJson(result, res.outputStream()); // RB0", fieldName).eol(); + UType uType = UType.parse(method.getReturnType()); + writer.append(" %sJsonType.toJson(result, res.outputStream());", uType.shortName()).eol(); } else { writer.append(" res.send(result);").eol(); } diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java index d21994a43..ffeca77e6 100644 --- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java +++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java @@ -1,12 +1,12 @@ package io.avaje.http.generator.helidon.nima; -import java.io.IOException; -import java.util.*; - -import javax.lang.model.type.TypeMirror; - import io.avaje.http.generator.core.*; +import java.io.IOException; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + /** Write Helidon specific web route adapter (a Helidon Service). */ class ControllerWriter extends BaseControllerWriter { @@ -39,13 +39,12 @@ private void initJsonTypes(ControllerReader reader) { .forEach(methodReader -> { addJsonBodyType(methodReader); if (!methodReader.isVoid()) { - TypeMirror returnType = methodReader.getReturnType(); - addJsonBodyType(Util.parseType(returnType)); + addJsonType(UType.parse(methodReader.getReturnType())); } }); } - private void addJsonBodyType(UType type) { + private void addJsonType(UType type) { jsonTypes.put(type.full(), type); } @@ -53,7 +52,7 @@ private void addJsonBodyType(MethodReader methodReader) { if (methodReader.getBodyType() != null) { methodReader.getParams().stream() .filter(MethodParam::isBody) - .forEach(param -> addJsonBodyType(param.getUType())); + .forEach(param -> addJsonType(param.getUType())); } } @@ -65,15 +64,15 @@ void write() { writeClassEnd(); } - private List getWriterMethods() { + private List writerMethods() { return reader.getMethods().stream() .filter(MethodReader::isWebMethod) - .map(it -> new ControllerMethodWriter(it, writer, ctx, useJsonB, jsonTypes)) + .map(it -> new ControllerMethodWriter(it, writer, ctx, useJsonB)) .toList(); } private void writeAddRoutes() { - final var methods = getWriterMethods(); + final var methods = writerMethods(); writeRoutes(methods); for (final ControllerMethodWriter methodWriter : methods) { methodWriter.writeHandler(isRequestScoped()); @@ -109,8 +108,8 @@ private void writeClassStart() { if (reader.isIncludeValidator()) { writer.append(" private final Validator validator;").eol(); } - for (UType value : jsonTypes.values()) { - writer.append("private final JsonType<%s> %sJsonType; //RBx1", primitiveWrap(value.full()), value.shortName()).eol(); + for (UType type : jsonTypes.values()) { + writer.append(" private final JsonType<%s> %sJsonType;", primitiveWrap(type.full()), type.shortName()).eol(); } writer.eol(); @@ -127,9 +126,9 @@ private void writeClassStart() { writer.append(" this.validator = validator;").eol(); } if (useJsonB) { - for (UType value : jsonTypes.values()) { - writer.append(" this.%sJsonType = jsonB.type(", value.shortName()); - writeJsonbType(value); + for (UType type : jsonTypes.values()) { + writer.append(" this.%sJsonType = jsonB.type(", type.shortName()); + writeJsonbType(type); } } writer.append(" }").eol().eol(); @@ -146,7 +145,7 @@ private void writeJsonbType(UType type) { default -> throw new UnsupportedOperationException("Only java.util Map, Set and List are supported JsonB Controller Collection Types"); } } - writer.append("; // Rbx3").eol(); + writer.append(";").eol(); } private String primitiveWrap(String full) { diff --git a/tests/test-nima-jsonb/src/main/java/org/example/HelloController.java b/tests/test-nima-jsonb/src/main/java/org/example/HelloController.java index a157b4fac..5d25bca52 100644 --- a/tests/test-nima-jsonb/src/main/java/org/example/HelloController.java +++ b/tests/test-nima-jsonb/src/main/java/org/example/HelloController.java @@ -92,29 +92,31 @@ String addMultiple(List newGuys) { return "New Guys Added"; } - @Put("person/int") + @Put("test/int") int testIntReturn() { return 422; } - @Put("person/long") + @Put("test/long") long testLongReturn() { return 69; } - // curl -X POST http://localhost:8081/form -H "Content-Type: application/x-www-form-urlencoded" -d - // "name=Jimmy&email=jim@foo&url=notaurl" + // curl -X POST http://localhost:8081/form + // -H "Content-Type: application/x-www-form-urlencoded" + // -d "name=Jimmy&email=jim@foo&url=notaurl" @Form @Post("form") String form(String name, String email, String url) { return name + "-" + email + "-" + url; } - // curl -X POST http://localhost:8081/formBean -H "Content-Type: - // application/x-www-form-urlencoded" -d "name=FormBeanJimmy&email=jim@foo&url=notaurl" + // curl -X POST http://localhost:8081/formBean + // -H "Content-Type:application/x-www-form-urlencoded" + // -d "name=FormBeanJimmy&email=jim@foo&url=notaurl" @Form @Post("formBean") String formBean(MyForm form) { - return form.name + "-" + form.email + "-" + form.url; + return form.name + "|" + form.email + "|" + form.url; } } diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index 45adbd2bf..c53c869b0 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -35,12 +35,12 @@ io.helidon.nima.webserver helidon-nima-webserver - 4.0.0-ALPHA1 + 4.0.0-ALPHA2 io.helidon.nima.http.media helidon-nima-http-media-jsonb - 4.0.0-ALPHA1 + 4.0.0-ALPHA2 From 050dae0b149982d232acc6d02ddef5955d009d27 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 18 Oct 2022 22:25:53 +1300 Subject: [PATCH 0363/1323] [maven-release-plugin] prepare release avaje-http-generator-parent-1.18 --- http-api/pom.xml | 4 ++-- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 4 ++-- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-generator-nima/pom.xml | 6 ++---- pom.xml | 4 ++-- 8 files changed, 12 insertions(+), 14 deletions(-) diff --git a/http-api/pom.xml b/http-api/pom.xml index 9f3b81200..4e02cbc85 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-generator-parent - 1.18-SNAPSHOT + 1.18 .. @@ -12,7 +12,7 @@ scm:git:git@github.com:avaje/avaje-http.git - HEAD + avaje-http-generator-parent-1.18 diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index fa66a73c1..162efff3b 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -5,7 +5,7 @@ io.avaje avaje-http-generator-parent - 1.18-SNAPSHOT + 1.18 .. diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index a6582edfa..c587cc792 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-generator-parent - 1.18-SNAPSHOT + 1.18 .. @@ -33,7 +33,7 @@ io.avaje avaje-http-api - 1.18-SNAPSHOT + 1.18 diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index 13e04c778..47eabe8e9 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-generator-parent - 1.18-SNAPSHOT + 1.18 .. diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index 11bc5387c..44eccb32e 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-generator-parent - 1.18-SNAPSHOT + 1.18 .. diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index 4f86e778b..02d15145a 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-generator-parent - 1.18-SNAPSHOT + 1.18 .. diff --git a/http-generator-nima/pom.xml b/http-generator-nima/pom.xml index a6cdc056c..f1be43a85 100644 --- a/http-generator-nima/pom.xml +++ b/http-generator-nima/pom.xml @@ -1,11 +1,9 @@ - + avaje-http-generator-parent io.avaje - 1.18-SNAPSHOT + 1.18 4.0.0 diff --git a/pom.xml b/pom.xml index 5ec5342dd..442a6eeef 100644 --- a/pom.xml +++ b/pom.xml @@ -9,12 +9,12 @@ io.avaje avaje-http-generator-parent - 1.18-SNAPSHOT + 1.18 pom scm:git:git@github.com:avaje/avaje-http.git - HEAD + avaje-http-generator-parent-1.18 From d79255aee5c6d46bc30299674daf0f0a7fef9557 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 18 Oct 2022 22:25:59 +1300 Subject: [PATCH 0364/1323] [maven-release-plugin] prepare for next development iteration --- http-api/pom.xml | 4 ++-- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 4 ++-- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-generator-nima/pom.xml | 2 +- pom.xml | 4 ++-- 8 files changed, 11 insertions(+), 11 deletions(-) diff --git a/http-api/pom.xml b/http-api/pom.xml index 4e02cbc85..b13bc1242 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-generator-parent - 1.18 + 1.19-SNAPSHOT .. @@ -12,7 +12,7 @@ scm:git:git@github.com:avaje/avaje-http.git - avaje-http-generator-parent-1.18 + HEAD diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index 162efff3b..6bad232f4 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -5,7 +5,7 @@ io.avaje avaje-http-generator-parent - 1.18 + 1.19-SNAPSHOT .. diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index c587cc792..909e79b93 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-generator-parent - 1.18 + 1.19-SNAPSHOT .. @@ -33,7 +33,7 @@ io.avaje avaje-http-api - 1.18 + 1.19-SNAPSHOT diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index 47eabe8e9..818d866b1 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-generator-parent - 1.18 + 1.19-SNAPSHOT .. diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index 44eccb32e..8c4eb3d4e 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-generator-parent - 1.18 + 1.19-SNAPSHOT .. diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index 02d15145a..bde2581b2 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-generator-parent - 1.18 + 1.19-SNAPSHOT .. diff --git a/http-generator-nima/pom.xml b/http-generator-nima/pom.xml index f1be43a85..1a0a692f4 100644 --- a/http-generator-nima/pom.xml +++ b/http-generator-nima/pom.xml @@ -3,7 +3,7 @@ avaje-http-generator-parent io.avaje - 1.18 + 1.19-SNAPSHOT 4.0.0 diff --git a/pom.xml b/pom.xml index 442a6eeef..3fb84b90b 100644 --- a/pom.xml +++ b/pom.xml @@ -9,12 +9,12 @@ io.avaje avaje-http-generator-parent - 1.18 + 1.19-SNAPSHOT pom scm:git:git@github.com:avaje/avaje-http.git - avaje-http-generator-parent-1.18 + HEAD From 4b9ad12c066378b5bb40852a11d1eb1604490064 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 18 Oct 2022 22:32:26 +1300 Subject: [PATCH 0365/1323] Bump test modules to use 1.19-SNAPSHOT after release --- tests/test-client/pom.xml | 6 +++--- tests/test-helidon/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-jsonb/.factorypath | 4 ++-- tests/test-nima-jsonb/pom.xml | 8 ++++---- tests/test-nima/pom.xml | 6 +++--- 7 files changed, 15 insertions(+), 15 deletions(-) diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index 3119cf47c..4f619bea1 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -36,7 +36,7 @@ io.avaje avaje-http-api - 1.18-SNAPSHOT + 1.19-SNAPSHOT @@ -108,12 +108,12 @@ io.avaje avaje-http-client-generator - 1.18-SNAPSHOT + 1.19-SNAPSHOT io.avaje avaje-http-jex-generator - 1.18-SNAPSHOT + 1.19-SNAPSHOT io.avaje diff --git a/tests/test-helidon/pom.xml b/tests/test-helidon/pom.xml index 4024d9203..bacfe107f 100644 --- a/tests/test-helidon/pom.xml +++ b/tests/test-helidon/pom.xml @@ -17,7 +17,7 @@ true org.example.Main 2.3.0 - 1.18-SNAPSHOT + 1.19-SNAPSHOT diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 33791f54a..738aaa19f 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -20,7 +20,7 @@ 2.0.8 1.3.71 2.12.6.1 - 1.18-SNAPSHOT + 1.19-SNAPSHOT diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 10c3993e9..3ac277fe2 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -20,7 +20,7 @@ 2.0.8 2.12.6.1 8.9 - 1.18-SNAPSHOT + 1.19-SNAPSHOT diff --git a/tests/test-nima-jsonb/.factorypath b/tests/test-nima-jsonb/.factorypath index c135caf74..3a1d9fa8e 100644 --- a/tests/test-nima-jsonb/.factorypath +++ b/tests/test-nima-jsonb/.factorypath @@ -1,8 +1,8 @@ - + - + diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 2af18a2d1..47474ed70 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -4,7 +4,7 @@ avaje-http-generator-parent io.avaje - 1.18-SNAPSHOT + 1.19-SNAPSHOT ../../pom.xml @@ -28,7 +28,7 @@ io.avaje avaje-http-api - 1.18-SNAPSHOT + 1.19-SNAPSHOT io.avaje @@ -48,7 +48,7 @@ io.avaje avaje-http-nima-generator - 1.18-SNAPSHOT + 1.19-SNAPSHOT test @@ -75,7 +75,7 @@ io.avaje avaje-http-nima-generator - 1.18-SNAPSHOT + 1.19-SNAPSHOT io.avaje diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index c53c869b0..5e866083b 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -6,7 +6,7 @@ avaje-http-generator-parent io.avaje - 1.18-SNAPSHOT + 1.19-SNAPSHOT ../../pom.xml @@ -30,7 +30,7 @@ io.avaje avaje-http-api - 1.18-SNAPSHOT + 1.19-SNAPSHOT io.helidon.nima.webserver @@ -67,7 +67,7 @@ io.avaje avaje-http-nima-generator - 1.18-SNAPSHOT + 1.19-SNAPSHOT io.avaje From 8bbecb1164fa09cfca9f387ea32a388bc5fd9546 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Tue, 18 Oct 2022 11:01:20 -0400 Subject: [PATCH 0366/1323] fix headers --- .../http/generator/helidon/nima/NimaPlatformAdapter.java | 2 +- .../src/main/java/org/example/HelloController.java | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/NimaPlatformAdapter.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/NimaPlatformAdapter.java index c65148a72..95df0384e 100644 --- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/NimaPlatformAdapter.java +++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/NimaPlatformAdapter.java @@ -74,7 +74,7 @@ public void writeReadParameter(Append writer, ParamType paramType, String paramN writer.append("formParams.first(\"%s\").orElse(null)", paramName); break; case HEADER: - writer.append("req.headers().value(Http.Header.create(\"%s\").orElse(null)", paramName); + writer.append("req.headers().value(io.helidon.common.http.Http.Header.create(\"%s\")).orElse(null)", paramName); break; case COOKIE: writer.append("req.headers().cookies().first(\"%s\").orElse(null)", paramName); diff --git a/tests/test-nima-jsonb/src/main/java/org/example/HelloController.java b/tests/test-nima-jsonb/src/main/java/org/example/HelloController.java index 5d25bca52..485752448 100644 --- a/tests/test-nima-jsonb/src/main/java/org/example/HelloController.java +++ b/tests/test-nima-jsonb/src/main/java/org/example/HelloController.java @@ -7,6 +7,7 @@ import io.avaje.http.api.Controller; import io.avaje.http.api.Form; import io.avaje.http.api.Get; +import io.avaje.http.api.Header; import io.avaje.http.api.MediaType; import io.avaje.http.api.Post; import io.avaje.http.api.Produces; @@ -38,6 +39,7 @@ byte[] testBytes() { @Get("/helidon") void testHelidon(ServerRequest req, ServerResponse res) { + res.headers().contentType(HttpMediaType.TEXT_PLAIN); res.send("success path:" + req.path()); } @@ -47,6 +49,11 @@ void testVoid(ServerResponse res) { res.send("GET-Returning-void"); } + @Get("/header") + String testHeader(@Header String head) { + return head; + } + // curl -v localhost:8081/person/jack @Get("person/{name}") Person person(String name) { From 5cd1fc59576cbd49918774ce80181bdc42ea25e6 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Tue, 18 Oct 2022 14:22:38 -0400 Subject: [PATCH 0367/1323] start --- .../http/generator/core}/PrimitiveUtil.java | 8 +-- .../javalin/ControllerMethodWriter.java | 64 ++++++++++++------- .../generator/javalin/ControllerWriter.java | 34 ++++++---- .../generator/javalin/JavalinProcessor.java | 24 +++++-- .../helidon/nima/ControllerWriter.java | 17 +++-- 5 files changed, 100 insertions(+), 47 deletions(-) rename {http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima => http-generator-core/src/main/java/io/avaje/http/generator/core}/PrimitiveUtil.java (74%) diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/PrimitiveUtil.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/PrimitiveUtil.java similarity index 74% rename from http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/PrimitiveUtil.java rename to http-generator-core/src/main/java/io/avaje/http/generator/core/PrimitiveUtil.java index c7c6e727c..aa553aaac 100644 --- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/PrimitiveUtil.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/PrimitiveUtil.java @@ -1,9 +1,9 @@ -package io.avaje.http.generator.helidon.nima; +package io.avaje.http.generator.core; import java.util.HashMap; import java.util.Map; -final class PrimitiveUtil { +public final class PrimitiveUtil { static Map wrapperMap = new HashMap<>(); static { @@ -17,8 +17,8 @@ final class PrimitiveUtil { wrapperMap.put("boolean", "Boolean"); } - static String wrap(String shortName) { - String wrapped = wrapperMap.get(shortName); + public static String wrap(String shortName) { + final var wrapped = wrapperMap.get(shortName); return wrapped != null ? wrapped : shortName; } } diff --git a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java index bef0d34be..ff362f473 100644 --- a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java +++ b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java @@ -1,53 +1,57 @@ package io.avaje.http.generator.javalin; +import java.util.List; + import io.avaje.http.api.MediaType; import io.avaje.http.generator.core.Append; import io.avaje.http.generator.core.MethodParam; import io.avaje.http.generator.core.MethodReader; +import io.avaje.http.generator.core.ParamType; import io.avaje.http.generator.core.PathSegments; import io.avaje.http.generator.core.ProcessingContext; import io.avaje.http.generator.core.Util; import io.avaje.http.generator.core.WebMethod; -import java.util.List; - -/** - * Write code to register Web route for a given controller method. - */ +/** Write code to register Web route for a given controller method. */ class ControllerMethodWriter { private final MethodReader method; private final Append writer; private final WebMethod webMethod; private final ProcessingContext ctx; + private final boolean useJsonB; - ControllerMethodWriter(MethodReader method, Append writer, ProcessingContext ctx) { + ControllerMethodWriter( + MethodReader method, Append writer, ProcessingContext ctx, boolean useJsonB) { this.method = method; this.writer = writer; - this.webMethod = method.getWebMethod(); + webMethod = method.getWebMethod(); this.ctx = ctx; + this.useJsonB = useJsonB; } void write(boolean requestScoped) { - final PathSegments segments = method.getPathSegments(); - final String fullPath = segments.fullPath(); + final var segments = method.getPathSegments(); + final var fullPath = segments.fullPath(); - writer.append(" ApiBuilder.%s(\"%s\", ctx -> {", webMethod.name().toLowerCase(), fullPath).eol(); + writer + .append(" ApiBuilder.%s(\"%s\", ctx -> {", webMethod.name().toLowerCase(), fullPath) + .eol(); writer.append(" ctx.status(%s);", method.getStatusCode()).eol(); - List matrixSegments = segments.matrixSegments(); - for (PathSegments.Segment matrixSegment : matrixSegments) { + final var matrixSegments = segments.matrixSegments(); + for (final PathSegments.Segment matrixSegment : matrixSegments) { matrixSegment.writeCreateSegment(writer, ctx.platform()); } - final List params = method.getParams(); - for (MethodParam param : params) { + final var params = method.getParams(); + for (final MethodParam param : params) { param.writeCtxGet(writer, segments); } writer.append(" "); if (method.includeValidate()) { - for (MethodParam param : params) { + for (final MethodParam param : params) { param.writeValidate(writer); } } @@ -61,7 +65,7 @@ void write(boolean requestScoped) { writer.append("controller."); } writer.append(method.simpleName()).append("("); - for (int i = 0; i < params.size(); i++) { + for (var i = 0; i < params.size(); i++) { if (i > 0) { writer.append(", "); } @@ -74,10 +78,10 @@ void write(boolean requestScoped) { writer.append(";").eol(); writer.append(" }"); - List roles = method.roles(); + final var roles = method.roles(); if (!roles.isEmpty()) { writer.append(", "); - for (int i = 0; i < roles.size(); i++) { + for (var i = 0; i < roles.size(); i++) { if (i > 0) { writer.append(", "); } @@ -88,15 +92,31 @@ void write(boolean requestScoped) { } private void writeContextReturn() { - final String produces = method.getProduces(); - if (produces == null || produces.equalsIgnoreCase(MediaType.APPLICATION_JSON)) { + final var produces = method.getProduces(); + if (produces == null || MediaType.APPLICATION_JSON.equalsIgnoreCase(produces)) { writer.append("ctx.json("); - } else if (produces.equalsIgnoreCase(MediaType.TEXT_HTML)) { + } else if (MediaType.TEXT_HTML.equalsIgnoreCase(produces)) { writer.append("ctx.html("); - } else if (produces.equalsIgnoreCase(MediaType.TEXT_PLAIN)) { + } else if (MediaType.TEXT_PLAIN.equalsIgnoreCase(produces)) { writer.append("ctx.contentType(\"text/plain\").result("); } else { writer.append("ctx.contentType(\"%s\").result(", produces); } } + + private boolean producesJson() { + return useJsonB + && !"byte[]".equals(method.getReturnType().toString()) + && (method.getProduces() == null || method.getProduces().toLowerCase().contains("json")); + } + + private boolean missingServerResponse(List params) { + return method.isVoid() + && params.stream().noneMatch(p -> "ServerResponse".equals(p.getShortType())); + } + + private boolean usesFormParams() { + return method.getParams().stream() + .anyMatch(p -> p.isForm() || ParamType.FORMPARAM.equals(p.getParamType())); + } } diff --git a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java index 837f85c05..805ea9ac0 100644 --- a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java +++ b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java @@ -1,20 +1,26 @@ package io.avaje.http.generator.javalin; -import io.avaje.http.generator.core.*; - import java.io.IOException; -/** - * Write Javalin specific Controller WebRoute handling adapter. - */ +import io.avaje.http.generator.core.BaseControllerWriter; +import io.avaje.http.generator.core.Constants; +import io.avaje.http.generator.core.ControllerReader; +import io.avaje.http.generator.core.MethodReader; +import io.avaje.http.generator.core.ProcessingContext; + +/** Write Javalin specific Controller WebRoute handling adapter. */ class ControllerWriter extends BaseControllerWriter { private static final String AT_GENERATED = "@Generated(\"avaje-javalin-generator\")"; private static final String API_BUILDER = "io.javalin.apibuilder.ApiBuilder"; + private final boolean useJsonb; + + ControllerWriter(ControllerReader reader, ProcessingContext ctx, boolean useJsonb) + throws IOException { - ControllerWriter(ControllerReader reader, ProcessingContext ctx) throws IOException { super(reader, ctx); reader.addImportType(API_BUILDER); + this.useJsonb = useJsonb; } void write() { @@ -28,7 +34,7 @@ void write() { private void writeAddRoutes() { writer.append(" @Override").eol(); writer.append(" public void registerRoutes() {").eol().eol(); - for (MethodReader method : reader.getMethods()) { + for (final MethodReader method : reader.getMethods()) { if (method.isWebMethod()) { writeForMethod(method); } @@ -37,7 +43,7 @@ private void writeAddRoutes() { } private void writeForMethod(MethodReader method) { - new ControllerMethodWriter(method, writer, ctx).write(isRequestScoped()); + new ControllerMethodWriter(method, writer, ctx, useJsonb).write(isRequestScoped()); if (!reader.isDocHidden()) { method.buildApiDocumentation(ctx); } @@ -46,10 +52,15 @@ private void writeForMethod(MethodReader method) { private void writeClassStart() { writer.append(AT_GENERATED).eol(); writer.append("@Component").eol(); - writer.append("public class ").append(shortName).append("$Route implements WebRoutes {").eol().eol(); + writer + .append("public class ") + .append(shortName) + .append("$Route implements WebRoutes {") + .eol() + .eol(); - String controllerName = "controller"; - String controllerType = shortName; + var controllerName = "controller"; + var controllerType = shortName; if (isRequestScoped()) { controllerName = "factory"; controllerType += Constants.FACTORY_SUFFIX; @@ -72,5 +83,4 @@ private void writeClassStart() { } writer.append(" }").eol().eol(); } - } diff --git a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinProcessor.java b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinProcessor.java index db742db89..46e1d23bf 100644 --- a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinProcessor.java +++ b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinProcessor.java @@ -1,21 +1,37 @@ package io.avaje.http.generator.javalin; +import java.io.IOException; + import io.avaje.http.generator.core.BaseProcessor; import io.avaje.http.generator.core.ControllerReader; import io.avaje.http.generator.core.PlatformAdapter; import io.avaje.http.generator.core.ProcessingContext; -import java.io.IOException; - public class JavalinProcessor extends BaseProcessor { + private boolean useJsonB; + + public JavalinProcessor() { + try { + Class.forName("io.avaje.jsonb.Jsonb"); + useJsonB = true; + } catch (final ClassNotFoundException e) { + useJsonB = false; + } + } + + public JavalinProcessor(boolean useJsonb) { + useJsonB = useJsonb; + } + @Override protected PlatformAdapter providePlatformAdapter() { return new JavalinAdapter(); } @Override - public void writeControllerAdapter(ProcessingContext ctx, ControllerReader reader) throws IOException { - new ControllerWriter(reader, ctx).write(); + public void writeControllerAdapter(ProcessingContext ctx, ControllerReader reader) + throws IOException { + new ControllerWriter(reader, ctx, useJsonB).write(); } } diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java index ffeca77e6..9b50e5dbc 100644 --- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java +++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java @@ -1,12 +1,19 @@ package io.avaje.http.generator.helidon.nima; -import io.avaje.http.generator.core.*; - import java.io.IOException; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import io.avaje.http.generator.core.BaseControllerWriter; +import io.avaje.http.generator.core.Constants; +import io.avaje.http.generator.core.ControllerReader; +import io.avaje.http.generator.core.MethodParam; +import io.avaje.http.generator.core.MethodReader; +import io.avaje.http.generator.core.PrimitiveUtil; +import io.avaje.http.generator.core.ProcessingContext; +import io.avaje.http.generator.core.UType; + /** Write Helidon specific web route adapter (a Helidon Service). */ class ControllerWriter extends BaseControllerWriter { @@ -16,7 +23,7 @@ class ControllerWriter extends BaseControllerWriter { ControllerWriter(ControllerReader reader, ProcessingContext ctx, boolean jsonB) throws IOException { super(reader, ctx); - this.useJsonB = jsonB; + useJsonB = jsonB; if (useJsonB) { reader.addImportType("io.avaje.jsonb.Jsonb"); reader.addImportType("io.avaje.jsonb.JsonType"); @@ -108,7 +115,7 @@ private void writeClassStart() { if (reader.isIncludeValidator()) { writer.append(" private final Validator validator;").eol(); } - for (UType type : jsonTypes.values()) { + for (final UType type : jsonTypes.values()) { writer.append(" private final JsonType<%s> %sJsonType;", primitiveWrap(type.full()), type.shortName()).eol(); } writer.eol(); @@ -126,7 +133,7 @@ private void writeClassStart() { writer.append(" this.validator = validator;").eol(); } if (useJsonB) { - for (UType type : jsonTypes.values()) { + for (final UType type : jsonTypes.values()) { writer.append(" this.%sJsonType = jsonB.type(", type.shortName()); writeJsonbType(type); } From ebdff93942af3daac670d3bd0cb1be6bda76abfa Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Tue, 18 Oct 2022 14:49:14 -0400 Subject: [PATCH 0368/1323] create JsonB Util --- .../avaje/http/generator/core/JsonBUtil.java | 38 +++++++++++++++ .../http/generator/core/PrimitiveUtil.java | 5 +- .../helidon/nima/ControllerWriter.java | 47 ++++++------------- 3 files changed, 56 insertions(+), 34 deletions(-) create mode 100644 http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java new file mode 100644 index 000000000..c337f17dd --- /dev/null +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java @@ -0,0 +1,38 @@ +package io.avaje.http.generator.core; + +import java.util.LinkedHashMap; +import java.util.Map; + +public class JsonBUtil { + private JsonBUtil() {} + + private static final Map jsonTypes = new LinkedHashMap<>(); + + public static Map getJsonTypes(ControllerReader reader) { + reader.getMethods().stream() + .filter(MethodReader::isWebMethod) + .filter(m -> !"byte[]".equals(m.getReturnType().toString())) + .filter(m -> m.getProduces() == null || m.getProduces().toLowerCase().contains("json")) + .forEach( + methodReader -> { + addJsonBodyType(methodReader); + if (!methodReader.isVoid()) { + addJsonType(UType.parse(methodReader.getReturnType())); + } + }); + + return Map.copyOf(jsonTypes); + } + + private static void addJsonType(UType type) { + jsonTypes.put(type.full(), type); + } + + private static void addJsonBodyType(MethodReader methodReader) { + if (methodReader.getBodyType() != null) { + methodReader.getParams().stream() + .filter(MethodParam::isBody) + .forEach(param -> addJsonType(param.getUType())); + } + } +} diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/PrimitiveUtil.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/PrimitiveUtil.java index aa553aaac..b20a67bd5 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/PrimitiveUtil.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/PrimitiveUtil.java @@ -5,7 +5,10 @@ public final class PrimitiveUtil { - static Map wrapperMap = new HashMap<>(); + private PrimitiveUtil() {} + + static final Map wrapperMap = new HashMap<>(); + static { wrapperMap.put("char", "Character"); wrapperMap.put("byte", "Byte"); diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java index 9b50e5dbc..da7c06094 100644 --- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java +++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java @@ -1,14 +1,13 @@ package io.avaje.http.generator.helidon.nima; import java.io.IOException; -import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import io.avaje.http.generator.core.BaseControllerWriter; import io.avaje.http.generator.core.Constants; import io.avaje.http.generator.core.ControllerReader; -import io.avaje.http.generator.core.MethodParam; +import io.avaje.http.generator.core.JsonBUtil; import io.avaje.http.generator.core.MethodReader; import io.avaje.http.generator.core.PrimitiveUtil; import io.avaje.http.generator.core.ProcessingContext; @@ -19,15 +18,18 @@ class ControllerWriter extends BaseControllerWriter { private static final String AT_GENERATED = "@Generated(\"avaje-helidon-nima-generator\")"; private final boolean useJsonB; - private final Map jsonTypes = new LinkedHashMap<>(); + private final Map jsonTypes; - ControllerWriter(ControllerReader reader, ProcessingContext ctx, boolean jsonB) throws IOException { + ControllerWriter(ControllerReader reader, ProcessingContext ctx, boolean jsonB) + throws IOException { super(reader, ctx); useJsonB = jsonB; if (useJsonB) { reader.addImportType("io.avaje.jsonb.Jsonb"); reader.addImportType("io.avaje.jsonb.JsonType"); - initJsonTypes(reader); + jsonTypes = JsonBUtil.getJsonTypes(reader); + } else { + jsonTypes = null; } reader.addImportType("io.helidon.common.http.HttpMediaType"); reader.addImportType("io.helidon.common.parameters.Parameters"); @@ -38,31 +40,6 @@ class ControllerWriter extends BaseControllerWriter { reader.addImportType("io.helidon.nima.webserver.http.HttpService"); } - private void initJsonTypes(ControllerReader reader) { - reader.getMethods().stream() - .filter(MethodReader::isWebMethod) - .filter(m -> !"byte[]".equals(m.getReturnType().toString())) - .filter(m -> m.getProduces() == null || m.getProduces().toLowerCase().contains("json")) - .forEach(methodReader -> { - addJsonBodyType(methodReader); - if (!methodReader.isVoid()) { - addJsonType(UType.parse(methodReader.getReturnType())); - } - }); - } - - private void addJsonType(UType type) { - jsonTypes.put(type.full(), type); - } - - private void addJsonBodyType(MethodReader methodReader) { - if (methodReader.getBodyType() != null) { - methodReader.getParams().stream() - .filter(MethodParam::isBody) - .forEach(param -> addJsonType(param.getUType())); - } - } - void write() { writePackage(); writeImports(); @@ -116,7 +93,11 @@ private void writeClassStart() { writer.append(" private final Validator validator;").eol(); } for (final UType type : jsonTypes.values()) { - writer.append(" private final JsonType<%s> %sJsonType;", primitiveWrap(type.full()), type.shortName()).eol(); + writer + .append( + " private final JsonType<%s> %sJsonType;", + primitiveWrap(type.full()), type.shortName()) + .eol(); } writer.eol(); @@ -149,7 +130,8 @@ private void writeJsonbType(UType type) { case "java.util.List" -> writer.append("%s.class).list()", type.param0()); case "java.util.Set" -> writer.append("%s.class).set()", type.param0()); case "java.util.Map" -> writer.append("%s.class).map()", type.param1()); - default -> throw new UnsupportedOperationException("Only java.util Map, Set and List are supported JsonB Controller Collection Types"); + default -> throw new UnsupportedOperationException( + "Only java.util Map, Set and List are supported JsonB Controller Collection Types"); } } writer.append(";").eol(); @@ -158,5 +140,4 @@ private void writeJsonbType(UType type) { private String primitiveWrap(String full) { return PrimitiveUtil.wrap(full); } - } From d64812f5ba5e0ce6923efe0a5cb04bab2ea24ef2 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Tue, 18 Oct 2022 17:01:54 -0400 Subject: [PATCH 0369/1323] support --- .../client/ClientPlatformAdapter.java | 7 +- .../http/generator/core/ElementReader.java | 123 +++++++++--------- .../avaje/http/generator/core/JsonBUtil.java | 24 ++++ .../http/generator/core/PlatformAdapter.java | 2 +- .../helidon/HelidonPlatformAdapter.java | 7 +- .../javalin/ControllerMethodWriter.java | 47 +++---- .../generator/javalin/ControllerWriter.java | 38 +++++- .../generator/javalin/JavalinAdapter.java | 23 +++- .../generator/javalin/JavalinProcessor.java | 2 +- .../avaje/http/generator/jex/JexAdapter.java | 11 +- .../helidon/nima/ControllerMethodWriter.java | 18 ++- .../helidon/nima/ControllerWriter.java | 26 +--- .../helidon/nima/NimaPlatformAdapter.java | 3 +- tests/test-javalin/pom.xml | 2 +- .../src/main/java/org/example/myapp/Main.java | 35 ++--- .../java/org/example/myapp/web/AppRoles.java | 2 +- tests/test-nima-jsonb/.factorypath | 1 - 17 files changed, 209 insertions(+), 162 deletions(-) diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientPlatformAdapter.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientPlatformAdapter.java index 9a195c483..0880fe3c7 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientPlatformAdapter.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientPlatformAdapter.java @@ -1,11 +1,12 @@ package io.avaje.http.generator.client; +import java.util.List; + import io.avaje.http.generator.core.Append; import io.avaje.http.generator.core.ControllerReader; import io.avaje.http.generator.core.ParamType; import io.avaje.http.generator.core.PlatformAdapter; - -import java.util.List; +import io.avaje.http.generator.core.UType; class ClientPlatformAdapter implements PlatformAdapter { @@ -20,7 +21,7 @@ public String platformVariable(String rawType) { } @Override - public String bodyAsClass(String shortType) { + public String bodyAsClass(UType uType) { return null; } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java index adcb7c8dd..e1940c199 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java @@ -1,14 +1,19 @@ package io.avaje.http.generator.core; -import io.avaje.http.api.*; -import io.avaje.http.generator.core.openapi.MethodDocBuilder; -import io.avaje.http.generator.core.openapi.MethodParamDocBuilder; +import static io.avaje.http.generator.core.ParamType.RESPONSE_HANDLER; import javax.lang.model.element.Element; -import javax.lang.model.element.TypeElement; import javax.validation.Valid; -import static io.avaje.http.generator.core.ParamType.RESPONSE_HANDLER; +import io.avaje.http.api.BeanParam; +import io.avaje.http.api.Cookie; +import io.avaje.http.api.Default; +import io.avaje.http.api.Form; +import io.avaje.http.api.FormParam; +import io.avaje.http.api.Header; +import io.avaje.http.api.QueryParam; +import io.avaje.http.generator.core.openapi.MethodDocBuilder; +import io.avaje.http.generator.core.openapi.MethodParamDocBuilder; public class ElementReader { @@ -41,13 +46,13 @@ public class ElementReader { this.element = element; this.type = type; this.rawType = rawType; - this.shortType = Util.shortName(rawType); - this.contextType = ctx.platform().isContextType(rawType); - this.typeHandler = TypeMap.get(rawType); + shortType = Util.shortName(rawType); + contextType = ctx.platform().isContextType(rawType); + typeHandler = TypeMap.get(rawType); this.formMarker = formMarker; - this.varName = element.getSimpleName().toString(); - this.snakeName = Util.snakeCase(varName); - this.paramName = varName; + varName = element.getSimpleName().toString(); + snakeName = Util.snakeCase(varName); + paramName = varName; if (!contextType) { readAnnotations(element, defaultType); useValidation = useValidation(); @@ -61,7 +66,7 @@ private boolean useValidation() { if (typeHandler != null) { return false; } - TypeElement elementType = ctx.getTypeElement(rawType); + final var elementType = ctx.getTypeElement(rawType); return elementType != null && elementType.getAnnotation(Valid.class) != null; } @@ -70,53 +75,53 @@ private void readAnnotations(Element element, ParamType defaultType) { notNullKotlin = (element.getAnnotation(org.jetbrains.annotations.NotNull.class) != null); //notNullJavax = (element.getAnnotation(javax.validation.constraints.NotNull.class) != null); - Default defaultVal = element.getAnnotation(Default.class); + final var defaultVal = element.getAnnotation(Default.class); if (defaultVal != null) { - this.paramDefault = defaultVal.value(); + paramDefault = defaultVal.value(); } - Form form = element.getAnnotation(Form.class); + final var form = element.getAnnotation(Form.class); if (form != null) { - this.paramType = ParamType.FORM; + paramType = ParamType.FORM; return; } - BeanParam beanParam = element.getAnnotation(BeanParam.class); + final var beanParam = element.getAnnotation(BeanParam.class); if (beanParam != null) { - this.paramType = ParamType.BEANPARAM; + paramType = ParamType.BEANPARAM; return; } - QueryParam queryParam = element.getAnnotation(QueryParam.class); + final var queryParam = element.getAnnotation(QueryParam.class); if (queryParam != null) { - this.paramName = nameFrom(queryParam.value(), varName); - this.paramType = ParamType.QUERYPARAM; + paramName = nameFrom(queryParam.value(), varName); + paramType = ParamType.QUERYPARAM; return; } - FormParam formParam = element.getAnnotation(FormParam.class); + final var formParam = element.getAnnotation(FormParam.class); if (formParam != null) { - this.paramName = nameFrom(formParam.value(), varName); - this.paramType = ParamType.FORMPARAM; + paramName = nameFrom(formParam.value(), varName); + paramType = ParamType.FORMPARAM; return; } - Cookie cookieParam = element.getAnnotation(Cookie.class); + final var cookieParam = element.getAnnotation(Cookie.class); if (cookieParam != null) { - this.paramName = nameFrom(cookieParam.value(), varName); - this.paramType = ParamType.COOKIE; - this.paramDefault = null; + paramName = nameFrom(cookieParam.value(), varName); + paramType = ParamType.COOKIE; + paramDefault = null; return; } - Header headerParam = element.getAnnotation(Header.class); + final var headerParam = element.getAnnotation(Header.class); if (headerParam != null) { - this.paramName = nameFrom(headerParam.value(), Util.initcapSnake(snakeName)); - this.paramType = ParamType.HEADER; - this.paramDefault = null; + paramName = nameFrom(headerParam.value(), Util.initcapSnake(snakeName)); + paramType = ParamType.HEADER; + paramDefault = null; return; } if (paramType == null) { - this.impliedParamType = true; + impliedParamType = true; if (typeHandler != null) { // a scalar type that we know how to convert - this.paramType = defaultType; + paramType = defaultType; } else { - this.paramType = formMarker ? ParamType.FORM : ParamType.BODY; + paramType = formMarker ? ParamType.FORM : ParamType.BODY; } } } @@ -159,7 +164,7 @@ private String shortType() { void addImports(ControllerReader bean) { if (typeHandler != null) { - String importType = typeHandler.getImportType(); + final var importType = typeHandler.getImportType(); if (importType != null) { bean.addImportType(rawType); } @@ -197,16 +202,12 @@ void writeValidate(Append writer) { } void writeCtxGet(Append writer, PathSegments segments) { - if (isPlatformContext()) { - // no conversion for this parameter - return; - } - if (paramType == ParamType.BODY && ctx.platform().isBodyMethodParam()) { + if (isPlatformContext() || (paramType == ParamType.BODY && ctx.platform().isBodyMethodParam())) { // body passed as method parameter (Helidon) return; } - String shortType = shortType(); - writer.append("%s %s %s = ", ctx.platform().indent(), shortType, varName); + final var shortType = shortType(); + writer.append("%s var %s = ", ctx.platform().indent(), varName); if (setValue(writer, segments, shortType)) { writer.append(";").eol(); } @@ -235,11 +236,11 @@ private boolean setValue(Append writer, PathSegments segments, String shortType) return false; } if (impliedParamType) { - PathSegments.Segment segment = segments.segment(varName); + final var segment = segments.segment(varName); if (segment != null) { // path or matrix parameter - boolean requiredParam = segment.isRequired(varName); - String asMethod = (typeHandler == null) ? null : (requiredParam) ? typeHandler.asMethod() : typeHandler.toMethod(); + final var requiredParam = segment.isRequired(varName); + final var asMethod = (typeHandler == null) ? null : (requiredParam) ? typeHandler.asMethod() : typeHandler.toMethod(); if (asMethod != null) { writer.append(asMethod); } @@ -252,28 +253,26 @@ private boolean setValue(Append writer, PathSegments segments, String shortType) } } - String asMethod = (typeHandler == null) ? null : typeHandler.toMethod(); + final var asMethod = (typeHandler == null) ? null : typeHandler.toMethod(); if (asMethod != null) { writer.append(asMethod); } if (typeHandler == null) { // this is a body (POST, PATCH) - writer.append(ctx.platform().bodyAsClass(shortType)); + writer.append(ctx.platform().bodyAsClass(type)); + }else if (hasParamDefault()) { + ctx.platform().writeReadParameter(writer, paramType, paramName, paramDefault); } else { - if (hasParamDefault()) { - ctx.platform().writeReadParameter(writer, paramType, paramName, paramDefault); - } else { - boolean checkNull = notNullKotlin || (paramType == ParamType.FORMPARAM && typeHandler.isPrimitive()); - if (checkNull) { - writer.append("checkNull("); - } - ctx.platform().writeReadParameter(writer, paramType, paramName); - //writer.append("ctx.%s(\"%s\")", paramType, paramName); - if (checkNull) { - writer.append(", \"%s\")", paramName); - } + final var checkNull = notNullKotlin || (paramType == ParamType.FORMPARAM && typeHandler.isPrimitive()); + if (checkNull) { + writer.append("checkNull("); + } + ctx.platform().writeReadParameter(writer, paramType, paramName); + //writer.append("ctx.%s(\"%s\")", paramType, paramName); + if (checkNull) { + writer.append(", \"%s\")", paramName); } } @@ -284,8 +283,8 @@ private boolean setValue(Append writer, PathSegments segments, String shortType) } private void writeForm(Append writer, String shortType, String varName, ParamType defaultParamType) { - TypeElement formBeanType = ctx.getTypeElement(rawType); - BeanParamReader form = new BeanParamReader(ctx, formBeanType, varName, shortType, defaultParamType); + final var formBeanType = ctx.getTypeElement(rawType); + final var form = new BeanParamReader(ctx, formBeanType, varName, shortType, defaultParamType); form.write(writer); } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java index c337f17dd..71f2c685a 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java @@ -35,4 +35,28 @@ private static void addJsonBodyType(MethodReader methodReader) { .forEach(param -> addJsonType(param.getUType())); } } + + public static void writeJsonbType(UType type, Append writer) { + + writer.append(" this.%sJsonType = jsonB.type(", type.shortName()); + if (!type.isGeneric()) { + writer.append("%s.class)", type.full()); + } else { + switch (type.mainType()) { + case "java.util.List": + writer.append("%s.class).list()", type.param0()); + break; + case "java.util.Set": + writer.append("%s.class).set()", type.param0()); + break; + case "java.util.Map": + writer.append("%s.class).map()", type.param1()); + break; + default: + throw new UnsupportedOperationException( + "Only java.util Map, Set and List are supported JsonB Controller Collection Types"); + } + } + writer.append(";").eol(); + } } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/PlatformAdapter.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/PlatformAdapter.java index abef69a64..fb135c9e2 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/PlatformAdapter.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/PlatformAdapter.java @@ -21,7 +21,7 @@ public interface PlatformAdapter { /** * Return platform specific code to return the body content. */ - String bodyAsClass(String shortType); + String bodyAsClass(UType type); /** * Return true if body is passed as a method parameter. diff --git a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/HelidonPlatformAdapter.java b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/HelidonPlatformAdapter.java index c2ac630ac..3287d5149 100644 --- a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/HelidonPlatformAdapter.java +++ b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/HelidonPlatformAdapter.java @@ -1,11 +1,12 @@ package io.avaje.http.generator.helidon; +import java.util.List; + import io.avaje.http.generator.core.Append; import io.avaje.http.generator.core.ControllerReader; import io.avaje.http.generator.core.ParamType; import io.avaje.http.generator.core.PlatformAdapter; - -import java.util.List; +import io.avaje.http.generator.core.UType; class HelidonPlatformAdapter implements PlatformAdapter { @@ -38,7 +39,7 @@ public boolean isBodyMethodParam() { } @Override - public String bodyAsClass(String shortType) { + public String bodyAsClass(UType uType) { return "body"; } diff --git a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java index ff362f473..ba81082c5 100644 --- a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java +++ b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java @@ -1,14 +1,12 @@ package io.avaje.http.generator.javalin; -import java.util.List; - import io.avaje.http.api.MediaType; import io.avaje.http.generator.core.Append; import io.avaje.http.generator.core.MethodParam; import io.avaje.http.generator.core.MethodReader; -import io.avaje.http.generator.core.ParamType; import io.avaje.http.generator.core.PathSegments; import io.avaje.http.generator.core.ProcessingContext; +import io.avaje.http.generator.core.UType; import io.avaje.http.generator.core.Util; import io.avaje.http.generator.core.WebMethod; @@ -55,8 +53,9 @@ void write(boolean requestScoped) { param.writeValidate(writer); } } + if (!method.isVoid()) { - writeContextReturn(); + writer.append("var result = "); } if (requestScoped) { @@ -71,11 +70,13 @@ void write(boolean requestScoped) { } params.get(i).buildParamName(writer); } - writer.append(")"); + + writer.append(");").eol(); if (!method.isVoid()) { - writer.append(")"); + writeContextReturn(); + writer.eol(); } - writer.append(";").eol(); + writer.append(" }"); final var roles = method.roles(); @@ -94,29 +95,21 @@ void write(boolean requestScoped) { private void writeContextReturn() { final var produces = method.getProduces(); if (produces == null || MediaType.APPLICATION_JSON.equalsIgnoreCase(produces)) { - writer.append("ctx.json("); + if (useJsonB) { + final var uType = UType.parse(method.getReturnType()); + writer.append( + " %sJsonType.toJson(result, ctx.contentType(\"application/json\").outputStream());", + uType.shortName()); + + } else { + writer.append(" ctx.json(result);"); + } } else if (MediaType.TEXT_HTML.equalsIgnoreCase(produces)) { - writer.append("ctx.html("); + writer.append(" ctx.html(result);"); } else if (MediaType.TEXT_PLAIN.equalsIgnoreCase(produces)) { - writer.append("ctx.contentType(\"text/plain\").result("); + writer.append(" ctx.contentType(\"text/plain\").result(result);"); } else { - writer.append("ctx.contentType(\"%s\").result(", produces); + writer.append(" ctx.contentType(\"%s\").result(result);", produces); } } - - private boolean producesJson() { - return useJsonB - && !"byte[]".equals(method.getReturnType().toString()) - && (method.getProduces() == null || method.getProduces().toLowerCase().contains("json")); - } - - private boolean missingServerResponse(List params) { - return method.isVoid() - && params.stream().noneMatch(p -> "ServerResponse".equals(p.getShortType())); - } - - private boolean usesFormParams() { - return method.getParams().stream() - .anyMatch(p -> p.isForm() || ParamType.FORMPARAM.equals(p.getParamType())); - } } diff --git a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java index 805ea9ac0..e49e2a779 100644 --- a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java +++ b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java @@ -1,26 +1,37 @@ package io.avaje.http.generator.javalin; import java.io.IOException; +import java.util.Map; import io.avaje.http.generator.core.BaseControllerWriter; import io.avaje.http.generator.core.Constants; import io.avaje.http.generator.core.ControllerReader; +import io.avaje.http.generator.core.JsonBUtil; import io.avaje.http.generator.core.MethodReader; +import io.avaje.http.generator.core.PrimitiveUtil; import io.avaje.http.generator.core.ProcessingContext; +import io.avaje.http.generator.core.UType; /** Write Javalin specific Controller WebRoute handling adapter. */ class ControllerWriter extends BaseControllerWriter { private static final String AT_GENERATED = "@Generated(\"avaje-javalin-generator\")"; private static final String API_BUILDER = "io.javalin.apibuilder.ApiBuilder"; - private final boolean useJsonb; + private final boolean useJsonB; + private final Map jsonTypes; - ControllerWriter(ControllerReader reader, ProcessingContext ctx, boolean useJsonb) + ControllerWriter(ControllerReader reader, ProcessingContext ctx, boolean jsonB) throws IOException { - super(reader, ctx); + useJsonB = jsonB; + if (useJsonB) { + reader.addImportType("io.avaje.jsonb.Jsonb"); + reader.addImportType("io.avaje.jsonb.JsonType"); + jsonTypes = JsonBUtil.getJsonTypes(reader); + } else { + jsonTypes = Map.of(); + } reader.addImportType(API_BUILDER); - this.useJsonb = useJsonb; } void write() { @@ -43,7 +54,7 @@ private void writeAddRoutes() { } private void writeForMethod(MethodReader method) { - new ControllerMethodWriter(method, writer, ctx, useJsonb).write(isRequestScoped()); + new ControllerMethodWriter(method, writer, ctx, useJsonB).write(isRequestScoped()); if (!reader.isDocHidden()) { method.buildApiDocumentation(ctx); } @@ -70,17 +81,34 @@ private void writeClassStart() { if (reader.isIncludeValidator()) { writer.append(" private final Validator validator;").eol(); } + + for (final UType type : jsonTypes.values()) { + writer + .append( + " private final JsonType<%s> %sJsonType;", + PrimitiveUtil.wrap(type.full()), type.shortName()) + .eol(); + } + writer.eol(); writer.append(" public %s$Route(%s %s", shortName, controllerType, controllerName); if (reader.isIncludeValidator()) { writer.append(", Validator validator"); } + if (useJsonB) { + writer.append(", Jsonb jsonB"); + } writer.append(") {").eol(); writer.append(" this.%s = %s;", controllerName, controllerName).eol(); if (reader.isIncludeValidator()) { writer.append(" this.validator = validator;").eol(); } + if (useJsonB) { + for (final UType type : jsonTypes.values()) { + JsonBUtil.writeJsonbType(type, writer); + } + } writer.append(" }").eol().eol(); } } diff --git a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinAdapter.java b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinAdapter.java index a3ede7f66..a2182e32a 100644 --- a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinAdapter.java +++ b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinAdapter.java @@ -1,16 +1,23 @@ package io.avaje.http.generator.javalin; +import java.util.List; + import io.avaje.http.generator.core.Append; import io.avaje.http.generator.core.ControllerReader; import io.avaje.http.generator.core.ParamType; import io.avaje.http.generator.core.PlatformAdapter; - -import java.util.List; +import io.avaje.http.generator.core.UType; class JavalinAdapter implements PlatformAdapter { static final String JAVALIN3_CONTEXT = "io.javalin.http.Context"; + private final boolean useJsonB; + + JavalinAdapter(boolean useJsonB) { + this.useJsonB = useJsonB; + } + @Override public boolean isContextType(String rawType) { return JAVALIN3_CONTEXT.equals(rawType); @@ -27,8 +34,11 @@ public boolean isBodyMethodParam() { } @Override - public String bodyAsClass(String shortType) { - return "ctx.bodyAsClass(" + shortType + ".class)"; + public String bodyAsClass(UType type) { + if (useJsonB) { + return type.shortName() + "JsonType.fromJson(ctx.bodyInputStream())"; + } + return "ctx.bodyAsClass(" + type.mainType() + ".class)"; } @Override @@ -47,7 +57,7 @@ public void methodRoles(List roles, ControllerReader controller) { } private void addRoleImports(List roles, ControllerReader controller) { - for (String role : roles) { + for (final String role : roles) { controller.addStaticImportType(role); } } @@ -58,7 +68,8 @@ public void writeReadParameter(Append writer, ParamType paramType, String paramN } @Override - public void writeReadParameter(Append writer, ParamType paramType, String paramName, String paramDefault) { + public void writeReadParameter( + Append writer, ParamType paramType, String paramName, String paramDefault) { writer.append("withDefault(ctx.%s(\"%s\"), \"%s\")", paramType, paramName, paramDefault); } } diff --git a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinProcessor.java b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinProcessor.java index 46e1d23bf..abe403f5d 100644 --- a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinProcessor.java +++ b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinProcessor.java @@ -26,7 +26,7 @@ public JavalinProcessor(boolean useJsonb) { @Override protected PlatformAdapter providePlatformAdapter() { - return new JavalinAdapter(); + return new JavalinAdapter(useJsonB); } @Override diff --git a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/JexAdapter.java b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/JexAdapter.java index fe86b0eba..fc8381e4b 100644 --- a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/JexAdapter.java +++ b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/JexAdapter.java @@ -1,11 +1,12 @@ package io.avaje.http.generator.jex; +import java.util.List; + import io.avaje.http.generator.core.Append; import io.avaje.http.generator.core.ControllerReader; import io.avaje.http.generator.core.ParamType; import io.avaje.http.generator.core.PlatformAdapter; - -import java.util.List; +import io.avaje.http.generator.core.UType; class JexAdapter implements PlatformAdapter { @@ -27,8 +28,8 @@ public boolean isBodyMethodParam() { } @Override - public String bodyAsClass(String shortType) { - return "ctx.bodyAsClass(" + shortType + ".class)"; + public String bodyAsClass(UType uType) { + return "ctx.bodyAsClass(" + uType.mainType() + ".class)"; } @Override @@ -47,7 +48,7 @@ public void methodRoles(List roles, ControllerReader controller) { } private void addRoleImports(List roles, ControllerReader controller) { - for (String role : roles) { + for (final String role : roles) { controller.addStaticImportType(role); } } diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java index 375c040db..3b483c25e 100644 --- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java +++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java @@ -1,12 +1,18 @@ package io.avaje.http.generator.helidon.nima; -import io.avaje.http.api.MediaType; -import io.avaje.http.generator.core.*; - import java.util.List; -import java.util.Map; import java.util.Optional; +import io.avaje.http.api.MediaType; +import io.avaje.http.generator.core.Append; +import io.avaje.http.generator.core.MethodParam; +import io.avaje.http.generator.core.MethodReader; +import io.avaje.http.generator.core.ParamType; +import io.avaje.http.generator.core.PathSegments; +import io.avaje.http.generator.core.ProcessingContext; +import io.avaje.http.generator.core.UType; +import io.avaje.http.generator.core.WebMethod; + /** * Write code to register Web route for a given controller method. */ @@ -21,7 +27,7 @@ class ControllerMethodWriter { ControllerMethodWriter(MethodReader method, Append writer, ProcessingContext ctx, boolean useJsonB) { this.method = method; this.writer = writer; - this.webMethod = method.getWebMethod(); + webMethod = method.getWebMethod(); this.ctx = ctx; this.useJsonB = useJsonB; } @@ -109,7 +115,7 @@ void writeHandler(boolean requestScoped) { if (!method.isVoid()) { writeContextReturn(); if (producesJson()) { - UType uType = UType.parse(method.getReturnType()); + final UType uType = UType.parse(method.getReturnType()); writer.append(" %sJsonType.toJson(result, res.outputStream());", uType.shortName()).eol(); } else { writer.append(" res.send(result);").eol(); diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java index da7c06094..0d1a0182f 100644 --- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java +++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java @@ -29,7 +29,7 @@ class ControllerWriter extends BaseControllerWriter { reader.addImportType("io.avaje.jsonb.JsonType"); jsonTypes = JsonBUtil.getJsonTypes(reader); } else { - jsonTypes = null; + jsonTypes = Map.of(); } reader.addImportType("io.helidon.common.http.HttpMediaType"); reader.addImportType("io.helidon.common.parameters.Parameters"); @@ -96,7 +96,7 @@ private void writeClassStart() { writer .append( " private final JsonType<%s> %sJsonType;", - primitiveWrap(type.full()), type.shortName()) + PrimitiveUtil.wrap(type.full()), type.shortName()) .eol(); } writer.eol(); @@ -115,29 +115,9 @@ private void writeClassStart() { } if (useJsonB) { for (final UType type : jsonTypes.values()) { - writer.append(" this.%sJsonType = jsonB.type(", type.shortName()); - writeJsonbType(type); + JsonBUtil.writeJsonbType(type, writer); } } writer.append(" }").eol().eol(); } - - private void writeJsonbType(UType type) { - if (!type.isGeneric()) { - writer.append("%s.class)", type.full()); - } else { - switch (type.mainType()) { - case "java.util.List" -> writer.append("%s.class).list()", type.param0()); - case "java.util.Set" -> writer.append("%s.class).set()", type.param0()); - case "java.util.Map" -> writer.append("%s.class).map()", type.param1()); - default -> throw new UnsupportedOperationException( - "Only java.util Map, Set and List are supported JsonB Controller Collection Types"); - } - } - writer.append(";").eol(); - } - - private String primitiveWrap(String full) { - return PrimitiveUtil.wrap(full); - } } diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/NimaPlatformAdapter.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/NimaPlatformAdapter.java index 95df0384e..bccfefcb9 100644 --- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/NimaPlatformAdapter.java +++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/NimaPlatformAdapter.java @@ -6,6 +6,7 @@ import io.avaje.http.generator.core.ControllerReader; import io.avaje.http.generator.core.ParamType; import io.avaje.http.generator.core.PlatformAdapter; +import io.avaje.http.generator.core.UType; class NimaPlatformAdapter implements PlatformAdapter { @@ -38,7 +39,7 @@ public boolean isBodyMethodParam() { } @Override - public String bodyAsClass(String shortType) { + public String bodyAsClass(UType uType) { return "body"; } diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 738aaa19f..69046e077 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -16,7 +16,7 @@ true org.example.myapp.Main - 4.6.0 + 5.1.1 2.0.8 1.3.71 2.12.6.1 diff --git a/tests/test-javalin/src/main/java/org/example/myapp/Main.java b/tests/test-javalin/src/main/java/org/example/myapp/Main.java index 8506ca0dd..f788ac2c6 100644 --- a/tests/test-javalin/src/main/java/org/example/myapp/Main.java +++ b/tests/test-javalin/src/main/java/org/example/myapp/Main.java @@ -1,19 +1,23 @@ package org.example.myapp; -import io.avaje.http.api.*; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.avaje.http.api.InvalidPathArgumentException; +import io.avaje.http.api.InvalidTypeArgumentException; +import io.avaje.http.api.ValidationException; +import io.avaje.http.api.Validator; +import io.avaje.http.api.WebRoutes; import io.avaje.inject.BeanScope; import io.avaje.inject.InjectModule; import io.javalin.Javalin; -import io.javalin.core.LoomUtil; import io.javalin.http.staticfiles.Location; import io.swagger.v3.oas.annotations.OpenAPIDefinition; import io.swagger.v3.oas.annotations.info.Info; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; @InjectModule(name = "app", requires = Validator.class) @OpenAPIDefinition(info = @Info(title = "Example service", description = "Example Javalin controllers with Java and Maven")) @@ -27,10 +31,9 @@ public static void main(String[] args) { public static Javalin start(int port) { - LoomUtil.useLoomThreadPool = false; - Javalin app = Javalin.create(config -> { + final var app = Javalin.create(config -> { config.showJavalinBanner = false; - config.addStaticFiles("public", Location.CLASSPATH); + config.staticFiles.add("public", Location.CLASSPATH); config.accessManager((handler, ctx, permittedRoles) -> { log.debug("allow access ..."); handler.handle(ctx); @@ -39,7 +42,7 @@ public static Javalin start(int port) { app.exception(ValidationException.class, (exception, ctx) -> { - Map map = new LinkedHashMap<>(); + final Map map = new LinkedHashMap<>(); map.put("message", exception.getMessage()); map.put("errors", exception.getErrors()); ctx.json(map); @@ -48,7 +51,7 @@ public static Javalin start(int port) { app.exception(InvalidTypeArgumentException.class, (exception, ctx) -> { - Map map = new LinkedHashMap<>(); + final Map map = new LinkedHashMap<>(); map.put("path", ctx.path()); map.put("message", "invalid type argument"); ctx.json(map); @@ -57,7 +60,7 @@ public static Javalin start(int port) { app.exception(InvalidPathArgumentException.class, (exception, ctx) -> { - Map map = new LinkedHashMap<>(); + final Map map = new LinkedHashMap<>(); map.put("path", ctx.path()); map.put("message", "invalid path argument"); ctx.json(map); @@ -70,8 +73,8 @@ public static Javalin start(int port) { }); // All WebRoutes / Controllers ... from DI Context - BeanScope beanScope = BeanScope.builder().build(); - List webRoutes = beanScope.list(WebRoutes.class); + final var beanScope = BeanScope.builder().build(); + final List webRoutes = beanScope.list(WebRoutes.class); app.routes(() -> webRoutes.forEach(WebRoutes::registerRoutes)); app.start(port); diff --git a/tests/test-javalin/src/main/java/org/example/myapp/web/AppRoles.java b/tests/test-javalin/src/main/java/org/example/myapp/web/AppRoles.java index a1bdd6d1b..e89f9b451 100644 --- a/tests/test-javalin/src/main/java/org/example/myapp/web/AppRoles.java +++ b/tests/test-javalin/src/main/java/org/example/myapp/web/AppRoles.java @@ -1,6 +1,6 @@ package org.example.myapp.web; -import io.javalin.core.security.RouteRole; +import io.javalin.security.RouteRole; public enum AppRoles implements RouteRole { ANYONE, ADMIN, BASIC_USER, ORG_ADMIN diff --git a/tests/test-nima-jsonb/.factorypath b/tests/test-nima-jsonb/.factorypath index 3a1d9fa8e..52e4d0c30 100644 --- a/tests/test-nima-jsonb/.factorypath +++ b/tests/test-nima-jsonb/.factorypath @@ -1,5 +1,4 @@ - From a370f379532076363e1471de0a29ddaec4c3c7c5 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Tue, 18 Oct 2022 17:31:34 -0400 Subject: [PATCH 0370/1323] this --- .../http/generator/core/ElementReader.java | 18 +++++++++--------- .../javalin/ControllerMethodWriter.java | 2 +- .../generator/javalin/ControllerWriter.java | 6 +++--- .../generator/javalin/JavalinProcessor.java | 4 ++-- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java index e1940c199..d5d1a81bb 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java @@ -46,19 +46,19 @@ public class ElementReader { this.element = element; this.type = type; this.rawType = rawType; - shortType = Util.shortName(rawType); - contextType = ctx.platform().isContextType(rawType); - typeHandler = TypeMap.get(rawType); + this.shortType = Util.shortName(rawType); + this.contextType = ctx.platform().isContextType(rawType); + this.typeHandler = TypeMap.get(rawType); this.formMarker = formMarker; - varName = element.getSimpleName().toString(); - snakeName = Util.snakeCase(varName); - paramName = varName; + this.varName = element.getSimpleName().toString(); + this.snakeName = Util.snakeCase(varName); + this.paramName = varName; if (!contextType) { readAnnotations(element, defaultType); - useValidation = useValidation(); + this.useValidation = useValidation(); } else { - paramType = ParamType.CONTEXT; - useValidation = false; + this.paramType = ParamType.CONTEXT; + this.useValidation = false; } } diff --git a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java index ba81082c5..29a10b1c9 100644 --- a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java +++ b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java @@ -23,7 +23,7 @@ class ControllerMethodWriter { MethodReader method, Append writer, ProcessingContext ctx, boolean useJsonB) { this.method = method; this.writer = writer; - webMethod = method.getWebMethod(); + this.webMethod = method.getWebMethod(); this.ctx = ctx; this.useJsonB = useJsonB; } diff --git a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java index e49e2a779..a4c0ecfd8 100644 --- a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java +++ b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java @@ -23,13 +23,13 @@ class ControllerWriter extends BaseControllerWriter { ControllerWriter(ControllerReader reader, ProcessingContext ctx, boolean jsonB) throws IOException { super(reader, ctx); - useJsonB = jsonB; + this.useJsonB = jsonB; if (useJsonB) { reader.addImportType("io.avaje.jsonb.Jsonb"); reader.addImportType("io.avaje.jsonb.JsonType"); - jsonTypes = JsonBUtil.getJsonTypes(reader); + this.jsonTypes = JsonBUtil.getJsonTypes(reader); } else { - jsonTypes = Map.of(); + this.jsonTypes = Map.of(); } reader.addImportType(API_BUILDER); } diff --git a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinProcessor.java b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinProcessor.java index abe403f5d..0f6fe0c97 100644 --- a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinProcessor.java +++ b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinProcessor.java @@ -14,9 +14,9 @@ public class JavalinProcessor extends BaseProcessor { public JavalinProcessor() { try { Class.forName("io.avaje.jsonb.Jsonb"); - useJsonB = true; + this.useJsonB = true; } catch (final ClassNotFoundException e) { - useJsonB = false; + this.useJsonB = false; } } From bac1d650e428c2aa63b7ec8a58ec8f7c306b8db1 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Tue, 18 Oct 2022 17:49:17 -0400 Subject: [PATCH 0371/1323] unstatic jsontype and primitive map --- .../avaje/http/generator/core/JsonBUtil.java | 21 +++++++++-------- .../http/generator/core/PrimitiveUtil.java | 23 ++++++++----------- 2 files changed, 21 insertions(+), 23 deletions(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java index 71f2c685a..9da1b416f 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java @@ -2,37 +2,38 @@ import java.util.LinkedHashMap; import java.util.Map; +import java.util.function.Consumer; public class JsonBUtil { private JsonBUtil() {} - private static final Map jsonTypes = new LinkedHashMap<>(); - public static Map getJsonTypes(ControllerReader reader) { + + final Map jsonTypes = new LinkedHashMap<>(); + + final Consumer addToMap = uType -> jsonTypes.put(uType.full(), uType); + reader.getMethods().stream() .filter(MethodReader::isWebMethod) .filter(m -> !"byte[]".equals(m.getReturnType().toString())) .filter(m -> m.getProduces() == null || m.getProduces().toLowerCase().contains("json")) .forEach( methodReader -> { - addJsonBodyType(methodReader); + addJsonBodyType(methodReader, addToMap); if (!methodReader.isVoid()) { - addJsonType(UType.parse(methodReader.getReturnType())); + addToMap.accept(UType.parse(methodReader.getReturnType())); } }); return Map.copyOf(jsonTypes); } - private static void addJsonType(UType type) { - jsonTypes.put(type.full(), type); - } - - private static void addJsonBodyType(MethodReader methodReader) { + private static void addJsonBodyType(MethodReader methodReader, Consumer addToMap) { if (methodReader.getBodyType() != null) { methodReader.getParams().stream() .filter(MethodParam::isBody) - .forEach(param -> addJsonType(param.getUType())); + .map(MethodParam::getUType) + .forEach(addToMap); } } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/PrimitiveUtil.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/PrimitiveUtil.java index b20a67bd5..cd7815ae6 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/PrimitiveUtil.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/PrimitiveUtil.java @@ -1,24 +1,21 @@ package io.avaje.http.generator.core; -import java.util.HashMap; import java.util.Map; public final class PrimitiveUtil { private PrimitiveUtil() {} - static final Map wrapperMap = new HashMap<>(); - - static { - wrapperMap.put("char", "Character"); - wrapperMap.put("byte", "Byte"); - wrapperMap.put("int", "Integer"); - wrapperMap.put("long", "Long"); - wrapperMap.put("short", "Short"); - wrapperMap.put("double", "Double"); - wrapperMap.put("float", "Float"); - wrapperMap.put("boolean", "Boolean"); - } + static final Map wrapperMap = + Map.of( + "char", "Character", + "byte", "Byte", + "int", "Integer", + "long", "Long", + "short", "Short", + "double", "Double", + "float", "Float", + "boolean", "Boolean"); public static String wrap(String shortName) { final var wrapped = wrapperMap.get(shortName); From f76600f090ca11f83ab8f762d011ab9beb6c6080 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Tue, 18 Oct 2022 17:55:02 -0400 Subject: [PATCH 0372/1323] more this --- .../generator/helidon/nima/ControllerMethodWriter.java | 2 +- .../http/generator/helidon/nima/ControllerWriter.java | 6 +++--- .../avaje/http/generator/helidon/nima/NimaProcessor.java | 7 ++++--- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java index 3b483c25e..e61e53ea0 100644 --- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java +++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java @@ -27,7 +27,7 @@ class ControllerMethodWriter { ControllerMethodWriter(MethodReader method, Append writer, ProcessingContext ctx, boolean useJsonB) { this.method = method; this.writer = writer; - webMethod = method.getWebMethod(); + this.webMethod = method.getWebMethod(); this.ctx = ctx; this.useJsonB = useJsonB; } diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java index 0d1a0182f..5f8004f13 100644 --- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java +++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java @@ -23,13 +23,13 @@ class ControllerWriter extends BaseControllerWriter { ControllerWriter(ControllerReader reader, ProcessingContext ctx, boolean jsonB) throws IOException { super(reader, ctx); - useJsonB = jsonB; + this.useJsonB = jsonB; if (useJsonB) { reader.addImportType("io.avaje.jsonb.Jsonb"); reader.addImportType("io.avaje.jsonb.JsonType"); - jsonTypes = JsonBUtil.getJsonTypes(reader); + this.jsonTypes = JsonBUtil.getJsonTypes(reader); } else { - jsonTypes = Map.of(); + this.jsonTypes = Map.of(); } reader.addImportType("io.helidon.common.http.HttpMediaType"); reader.addImportType("io.helidon.common.parameters.Parameters"); diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/NimaProcessor.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/NimaProcessor.java index 44cccfaee..4b1bc6c9e 100644 --- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/NimaProcessor.java +++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/NimaProcessor.java @@ -14,9 +14,9 @@ public class NimaProcessor extends BaseProcessor { public NimaProcessor() { try { Class.forName("io.avaje.jsonb.Jsonb"); - jsonB = true; + this.jsonB = true; } catch (final ClassNotFoundException e) { - jsonB = false; + this.jsonB = false; } } @@ -30,7 +30,8 @@ protected PlatformAdapter providePlatformAdapter() { } @Override - public void writeControllerAdapter(ProcessingContext ctx, ControllerReader reader) throws IOException { + public void writeControllerAdapter(ProcessingContext ctx, ControllerReader reader) + throws IOException { new ControllerWriter(reader, ctx, jsonB).write(); } } From e5f729e1caed8d1694a4f47f485c23f1963a4067 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Tue, 18 Oct 2022 18:37:09 -0400 Subject: [PATCH 0373/1323] javalin jsonB test --- .gitignore | 2 + tests/pom.xml | 1 + tests/test-javalin-jsonb/.gitignore | 5 + tests/test-javalin-jsonb/Dockerfile | 25 + tests/test-javalin-jsonb/LICENSE | 201 +++++ tests/test-javalin-jsonb/README.md | 7 + tests/test-javalin-jsonb/pom.xml | 150 ++++ .../java/org/example/myapp/JsonBFactory.java | 13 + .../src/main/java/org/example/myapp/Main.java | 83 ++ .../org/example/myapp/service/BazRepo.java | 31 + .../example/myapp/service/MyDependency.java | 11 + .../org/example/myapp/service/MyService.java | 20 + .../java/org/example/myapp/web/AppRoles.java | 7 + .../main/java/org/example/myapp/web/Bar.java | 7 + .../org/example/myapp/web/BarController.java | 28 + .../org/example/myapp/web/BarInterface.java | 25 + .../org/example/myapp/web/BaseController.java | 31 + .../main/java/org/example/myapp/web/Baz.java | 13 + .../org/example/myapp/web/BazController.java | 43 + .../org/example/myapp/web/GetBeanForm.java | 29 + .../java/org/example/myapp/web/Hallo.java | 13 + .../example/myapp/web/HelloController.java | 150 ++++ .../java/org/example/myapp/web/HelloDto.java | 48 ++ .../java/org/example/myapp/web/HelloForm.java | 41 + .../org/example/myapp/web/Repository.java | 13 + .../myapp/web/ReqScopedController.java | 23 + .../java/org/example/myapp/web/Roles.java | 21 + .../src/main/resources/logback.xml | 18 + .../src/main/resources/public/openapi.json | 797 ++++++++++++++++++ .../http/generator/JavalinProcessorTest.java | 92 ++ .../java/io/avaje/http/generator}/MyForm.java | 2 +- .../java/io/avaje/http/generator/Person.java | 19 + .../avaje/http/generator/TestController.java | 107 +++ .../org/example/myapp/BarControllerTest.java | 43 + .../java/org/example/myapp/BaseWebTest.java | 32 + .../org/example/myapp/BazControllerTest.java | 41 + .../java/org/example/myapp/ErrorResponse.java | 27 + .../example/myapp/HelloControllerTest.java | 308 +++++++ .../myapp/ReqScopedControllerTest.java | 24 + .../src/test/resources/application-test.yaml | 6 + .../src/test/resources/logback-test.xml | 19 + .../example/myapp/web/HelloController.java | 36 +- .../java/org/example/HelloController.java | 1 + 43 files changed, 2600 insertions(+), 13 deletions(-) create mode 100644 tests/test-javalin-jsonb/.gitignore create mode 100644 tests/test-javalin-jsonb/Dockerfile create mode 100644 tests/test-javalin-jsonb/LICENSE create mode 100644 tests/test-javalin-jsonb/README.md create mode 100644 tests/test-javalin-jsonb/pom.xml create mode 100644 tests/test-javalin-jsonb/src/main/java/org/example/myapp/JsonBFactory.java create mode 100644 tests/test-javalin-jsonb/src/main/java/org/example/myapp/Main.java create mode 100644 tests/test-javalin-jsonb/src/main/java/org/example/myapp/service/BazRepo.java create mode 100644 tests/test-javalin-jsonb/src/main/java/org/example/myapp/service/MyDependency.java create mode 100644 tests/test-javalin-jsonb/src/main/java/org/example/myapp/service/MyService.java create mode 100644 tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/AppRoles.java create mode 100644 tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/Bar.java create mode 100644 tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/BarController.java create mode 100644 tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/BarInterface.java create mode 100644 tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/BaseController.java create mode 100644 tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/Baz.java create mode 100644 tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/BazController.java create mode 100644 tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/GetBeanForm.java create mode 100644 tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/Hallo.java create mode 100644 tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/HelloController.java create mode 100644 tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/HelloDto.java create mode 100644 tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/HelloForm.java create mode 100644 tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/Repository.java create mode 100644 tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/ReqScopedController.java create mode 100644 tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/Roles.java create mode 100644 tests/test-javalin-jsonb/src/main/resources/logback.xml create mode 100644 tests/test-javalin-jsonb/src/main/resources/public/openapi.json create mode 100644 tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/JavalinProcessorTest.java rename tests/{test-nima-jsonb/src/main/java/org/example => test-javalin-jsonb/src/test/java/io/avaje/http/generator}/MyForm.java (73%) create mode 100644 tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/Person.java create mode 100644 tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/TestController.java create mode 100644 tests/test-javalin-jsonb/src/test/java/org/example/myapp/BarControllerTest.java create mode 100644 tests/test-javalin-jsonb/src/test/java/org/example/myapp/BaseWebTest.java create mode 100644 tests/test-javalin-jsonb/src/test/java/org/example/myapp/BazControllerTest.java create mode 100644 tests/test-javalin-jsonb/src/test/java/org/example/myapp/ErrorResponse.java create mode 100644 tests/test-javalin-jsonb/src/test/java/org/example/myapp/HelloControllerTest.java create mode 100644 tests/test-javalin-jsonb/src/test/java/org/example/myapp/ReqScopedControllerTest.java create mode 100644 tests/test-javalin-jsonb/src/test/resources/application-test.yaml create mode 100644 tests/test-javalin-jsonb/src/test/resources/logback-test.xml diff --git a/.gitignore b/.gitignore index 1e7ecad3f..2c1471b49 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,5 @@ build/ *.project *.processors */bin/ +*.editorconfig +*.Module diff --git a/tests/pom.xml b/tests/pom.xml index e01034c90..f14840ab8 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -14,6 +14,7 @@ test-helidon test-javalin + test-javalin-jsonb test-jex test-client diff --git a/tests/test-javalin-jsonb/.gitignore b/tests/test-javalin-jsonb/.gitignore new file mode 100644 index 000000000..0c9d542d8 --- /dev/null +++ b/tests/test-javalin-jsonb/.gitignore @@ -0,0 +1,5 @@ +target/ +build/ +.idea/ +*.iml +.gradle diff --git a/tests/test-javalin-jsonb/Dockerfile b/tests/test-javalin-jsonb/Dockerfile new file mode 100644 index 000000000..384e0d669 --- /dev/null +++ b/tests/test-javalin-jsonb/Dockerfile @@ -0,0 +1,25 @@ +FROM openjdk:13-alpine +#FROM openjdk:11-slim + +EXPOSE 7000 +#VOLUME /var/log/java + +WORKDIR /app +COPY target/lib /app/lib +COPY target/app.jar /app/app.jar + +# For local docker build +#COPY application.yml /app/application.yml + +ENV JAVA_OPTS="" +ENTRYPOINT java ${JAVA_OPTS} -jar app.jar + + +## openjdk class archive +#COPY target/class-archive.jsa /app/class-archive.jsa +#ENTRYPOINT java ${JAVA_OPTS} -Xshare:on -XX:SharedArchiveFile=class-archive.jsa -Xlog:class+load=warning -jar app.jar + +## open9 shared classes +#FROM adoptopenjdk/openjdk11-openj9:nightly +#RUN mkdir /opt/shareclasses +#ENTRYPOINT java -Xshareclasses:cacheDir=/opt/shareclasses -jar app.jar diff --git a/tests/test-javalin-jsonb/LICENSE b/tests/test-javalin-jsonb/LICENSE new file mode 100644 index 000000000..261eeb9e9 --- /dev/null +++ b/tests/test-javalin-jsonb/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/tests/test-javalin-jsonb/README.md b/tests/test-javalin-jsonb/README.md new file mode 100644 index 000000000..7463daa77 --- /dev/null +++ b/tests/test-javalin-jsonb/README.md @@ -0,0 +1,7 @@ +# example-javalin-java-jsonb + +Very simple Java Maven Javalin example with Avaje JsonB instead of Jackson. + +- Run the main method - org.example.myapp.Main + +- `curl http://localhost:7000/hello/42/Roberto?otherParam=banana` diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml new file mode 100644 index 000000000..0dec4c17d --- /dev/null +++ b/tests/test-javalin-jsonb/pom.xml @@ -0,0 +1,150 @@ + + + 4.0.0 + + org.example + test-javalin-jsonb + 1 + + + org.avaje + java11-oss + 3.8 + + + + + true + org.example.myapp.Main + 5.1.1 + 2.0.8 + 1.3.71 + 2.12.6.1 + 1.19-SNAPSHOT + + + + + + org.avaje + logback + 1.0 + + + + io.javalin + javalin + ${javalin.version} + + + + io.avaje + avaje-inject + 8.9 + + + + io.avaje + avaje-http-api + ${avaje-http-version} + + + + io.avaje + avaje-http-hibernate-validator + 2.8 + + + + io.swagger.core.v3 + swagger-annotations + ${swagger.version} + + + + + + io.avaje + avaje-inject-generator + 8.9 + provided + + + + io.avaje + avaje-http-javalin-generator + ${avaje-http-version} + provided + + + + io.avaje + avaje-jsonb-generator + 1.0-RC2 + provided + + + + + io.avaje + junit + 1.1 + test + + + + io.rest-assured + rest-assured + 5.0.1 + test + + + + io.avaje + avaje-http-client + 1.16 + test + + + + + + app + + + + io.dinject + openapi-maven-plugin + 1.2 + + + main + process-classes + + openapi + + + + + + + io.repaint.maven + tiles-maven-plugin + 2.22 + true + + + org.avaje.tile:lib-classpath:1.1 + + + + + + + + + + HEAD + scm:git:git@github.com:avaje/avaje-http.git + + diff --git a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/JsonBFactory.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/JsonBFactory.java new file mode 100644 index 000000000..a1aed395a --- /dev/null +++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/JsonBFactory.java @@ -0,0 +1,13 @@ +package org.example.myapp; + +import io.avaje.inject.Bean; +import io.avaje.inject.Factory; +import io.avaje.jsonb.Jsonb; + +@Factory +public class JsonBFactory { + @Bean + Jsonb jsonB() { + return Jsonb.builder().failOnUnknown(false).build(); + } +} diff --git a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/Main.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/Main.java new file mode 100644 index 000000000..f788ac2c6 --- /dev/null +++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/Main.java @@ -0,0 +1,83 @@ +package org.example.myapp; + +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.avaje.http.api.InvalidPathArgumentException; +import io.avaje.http.api.InvalidTypeArgumentException; +import io.avaje.http.api.ValidationException; +import io.avaje.http.api.Validator; +import io.avaje.http.api.WebRoutes; +import io.avaje.inject.BeanScope; +import io.avaje.inject.InjectModule; +import io.javalin.Javalin; +import io.javalin.http.staticfiles.Location; +import io.swagger.v3.oas.annotations.OpenAPIDefinition; +import io.swagger.v3.oas.annotations.info.Info; + +@InjectModule(name = "app", requires = Validator.class) +@OpenAPIDefinition(info = @Info(title = "Example service", description = "Example Javalin controllers with Java and Maven")) +public class Main { + + private static final Logger log = LoggerFactory.getLogger(Main.class); + + public static void main(String[] args) { + start(8082); + } + + public static Javalin start(int port) { + + final var app = Javalin.create(config -> { + config.showJavalinBanner = false; + config.staticFiles.add("public", Location.CLASSPATH); + config.accessManager((handler, ctx, permittedRoles) -> { + log.debug("allow access ..."); + handler.handle(ctx); + }); + }); + + app.exception(ValidationException.class, (exception, ctx) -> { + + final Map map = new LinkedHashMap<>(); + map.put("message", exception.getMessage()); + map.put("errors", exception.getErrors()); + ctx.json(map); + ctx.status(exception.getStatus()); + }); + + app.exception(InvalidTypeArgumentException.class, (exception, ctx) -> { + + final Map map = new LinkedHashMap<>(); + map.put("path", ctx.path()); + map.put("message", "invalid type argument"); + ctx.json(map); + ctx.status(400); + }); + + app.exception(InvalidPathArgumentException.class, (exception, ctx) -> { + + final Map map = new LinkedHashMap<>(); + map.put("path", ctx.path()); + map.put("message", "invalid path argument"); + ctx.json(map); + ctx.status(404); + }); + + + app.get("/", ctx -> { + ctx.result("Hello World"); + }); + + // All WebRoutes / Controllers ... from DI Context + final var beanScope = BeanScope.builder().build(); + final List webRoutes = beanScope.list(WebRoutes.class); + app.routes(() -> webRoutes.forEach(WebRoutes::registerRoutes)); + + app.start(port); + return app; + } +} diff --git a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/service/BazRepo.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/service/BazRepo.java new file mode 100644 index 000000000..226df54b9 --- /dev/null +++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/service/BazRepo.java @@ -0,0 +1,31 @@ +package org.example.myapp.service; + +import org.example.myapp.web.Baz; +import org.example.myapp.web.Repository; + +import jakarta.inject.Singleton; +import java.util.ArrayList; +import java.util.List; + +@Singleton +public class BazRepo implements Repository { + + @Override + public Baz findById(Long id) { + Baz baz = new Baz(); + baz.id = id; + baz.name = "Baz" + id; + //baz.startDate = LocalDate.of(2020, 1, 1); + return baz; + } + + @Override + public List findAll() { + return new ArrayList<>(); + } + + @Override + public Long save(Baz bean) { + return 42L; + } +} diff --git a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/service/MyDependency.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/service/MyDependency.java new file mode 100644 index 000000000..394f48d76 --- /dev/null +++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/service/MyDependency.java @@ -0,0 +1,11 @@ +package org.example.myapp.service; + +import jakarta.inject.Singleton; + +@Singleton +public class MyDependency { + + public String hello() { + return "my dependency"; + } +} diff --git a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/service/MyService.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/service/MyService.java new file mode 100644 index 000000000..e21da48fa --- /dev/null +++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/service/MyService.java @@ -0,0 +1,20 @@ +package org.example.myapp.service; + +import org.example.myapp.web.HelloDto; + +import jakarta.inject.Singleton; +import java.util.ArrayList; +import java.util.List; + +@Singleton +public class MyService { + + public List findAll() { + + List list = new ArrayList<>(); + list.add(new HelloDto(12, "Jim", "asd")); + list.add(new HelloDto(13, "Spock", "456456")); + + return list; + } +} diff --git a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/AppRoles.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/AppRoles.java new file mode 100644 index 000000000..e89f9b451 --- /dev/null +++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/AppRoles.java @@ -0,0 +1,7 @@ +package org.example.myapp.web; + +import io.javalin.security.RouteRole; + +public enum AppRoles implements RouteRole { + ANYONE, ADMIN, BASIC_USER, ORG_ADMIN +} diff --git a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/Bar.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/Bar.java new file mode 100644 index 000000000..72aa5cb14 --- /dev/null +++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/Bar.java @@ -0,0 +1,7 @@ +package org.example.myapp.web; + +public class Bar { + + public long id; + public String name; +} diff --git a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/BarController.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/BarController.java new file mode 100644 index 000000000..2c6e281e4 --- /dev/null +++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/BarController.java @@ -0,0 +1,28 @@ +package org.example.myapp.web; + +import io.avaje.http.api.Controller; + +import java.util.ArrayList; +import java.util.List; + +@Controller +public class BarController implements BarInterface { + + @Override + public Bar getById(long id) { + Bar bar = new Bar(); + bar.id = id; + bar.name = "Rob" + id; + return bar; + } + + @Override + public List findByCode(String code) { + return new ArrayList<>(); + } + + @Override + public String barMessage() { + return "Hello"; + } +} diff --git a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/BarInterface.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/BarInterface.java new file mode 100644 index 000000000..4572236ae --- /dev/null +++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/BarInterface.java @@ -0,0 +1,25 @@ +package org.example.myapp.web; + +import io.avaje.http.api.Get; +import io.avaje.http.api.MediaType; +import io.avaje.http.api.Path; +import io.avaje.http.api.Produces; +import io.swagger.v3.oas.annotations.links.Link; +import io.swagger.v3.oas.annotations.responses.ApiResponse; + +import java.util.List; + +@Path("/bars") +public interface BarInterface { + + @Get(":id") + @ApiResponse(links = @Link(name="find", ref ="/find/:code", description="find by code")) + Bar getById(long id); + + @Get("/find/:code") + List findByCode(String code); + + @Produces(MediaType.TEXT_PLAIN) + @Get + String barMessage(); +} diff --git a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/BaseController.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/BaseController.java new file mode 100644 index 000000000..d342015b6 --- /dev/null +++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/BaseController.java @@ -0,0 +1,31 @@ +package org.example.myapp.web; + +import io.avaje.http.api.Get; +import io.avaje.http.api.Post; + +import java.util.List; + +abstract class BaseController { + + protected final Repository repository; + + BaseController(Repository repository) { + this.repository = repository; + } + + @Get(":id") + T getById(I id) { + return repository.findById(id); + } + + @Get + List findAll() { + return repository.findAll(); + } + + @Post + I save(T bean) { + return repository.save(bean); + } + +} diff --git a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/Baz.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/Baz.java new file mode 100644 index 000000000..7bae1ea1c --- /dev/null +++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/Baz.java @@ -0,0 +1,13 @@ +package org.example.myapp.web; + +import java.time.LocalDate; + +public class Baz { + + public Long id; + + public String name; + + public LocalDate startDate; + +} diff --git a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/BazController.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/BazController.java new file mode 100644 index 000000000..96923c60f --- /dev/null +++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/BazController.java @@ -0,0 +1,43 @@ +package org.example.myapp.web; + +import io.avaje.http.api.Controller; +import io.avaje.http.api.Get; +import io.avaje.http.api.Path; + +import java.util.Arrays; +import java.util.List; + +@Controller +@Path("/baz") +class BazController extends BaseController { + + BazController(Repository repository) { + super(repository); + } + + /** + * Find the baz by name. + *

+ * This is some more comments about this method. + * + * @return The list of baz + */ + @Get("findbyname/{name}") + List searchByName(String name) { + + Baz b1 = new Baz(); + b1.id = 1L; + b1.name = "baz1-" + name; + + Baz b2 = new Baz(); + b2.id = 2L; + b2.name = "baz2"; + + return Arrays.asList(b1, b2); + } + + @Get("checkparams/{id}") + String checkParams(int id, String p1, Double p2, Integer p3, Float p4, String body) { + return "dummy-response"; + } +} diff --git a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/GetBeanForm.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/GetBeanForm.java new file mode 100644 index 000000000..f92072efb --- /dev/null +++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/GetBeanForm.java @@ -0,0 +1,29 @@ +package org.example.myapp.web; + +import javax.validation.Valid; +import javax.validation.constraints.Email; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; + +@Valid +public class GetBeanForm { + + @NotNull @Size(min = 2, max = 150) + String name; + + @Email @Size(max = 100) + String email; + + public GetBeanForm(String name, String email) { + this.name = name; + this.email = email; + } + + @Override + public String toString() { + return "HelloForm{" + + "name='" + name + '\'' + + ", email='" + email + '\'' + + '}'; + } +} diff --git a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/Hallo.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/Hallo.java new file mode 100644 index 000000000..441676e7b --- /dev/null +++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/Hallo.java @@ -0,0 +1,13 @@ +package org.example.myapp.web; + +import io.avaje.http.api.Controller; +import io.avaje.http.api.Path; + +@Controller +@Path("hallo") +public class Hallo { + + public String getStuff() { + return "Hallo"; + } +} diff --git a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/HelloController.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/HelloController.java new file mode 100644 index 000000000..a6ba9a5f8 --- /dev/null +++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/HelloController.java @@ -0,0 +1,150 @@ +package org.example.myapp.web; + +import io.avaje.http.api.*; +import io.javalin.http.Context; +import io.swagger.v3.oas.annotations.Hidden; +import org.example.myapp.service.MyService; + +import jakarta.inject.Inject; + +import javax.validation.Valid; +import java.time.LocalDate; +import java.util.ArrayList; +import java.util.List; + +import static java.util.Objects.requireNonNull; + +/** + * Hello resource manager. + *

+ * Simple API for Hello resources. + */ +//@Hidden +@Valid +@Controller +@Path("/hello") +class HelloController { + + private final MyService myService; + + @Inject + HelloController(MyService myService) { + this.myService = myService; + } + + @Produces(MediaType.TEXT_PLAIN) + @Get("message") + String getPlainMessage() { + return "hello world"; + } + + /** + * Return the Hello DTO. + * + * @param id The hello Id. + * @param date The name of the hello + * @param otherParam Optional other parameter + * @return The Hello DTO given the id and name. + * @deprecated Please migrate away + */ + @Roles({AppRoles.ADMIN, AppRoles.BASIC_USER}) + @Get("/:id/:date") + HelloDto hello(int id, LocalDate date, String otherParam) { + return new HelloDto(id, date.toString(), otherParam); + } + + /** + * Find Hellos by name. + * + * @param name The name to search for + * @param myParam My option parameter + * @return The Hellos that we found. + */ + @Roles(AppRoles.ADMIN) + @Get("/findbyname/{name}") + List findByName(String name, @QueryParam("my-param") @Default("one") String myParam) { + return new ArrayList<>(); + } + + /** + * Simple example post with JSON body response. + */ + @Post + HelloDto post(HelloDto dto) { + dto.name = "posted"; + return dto; + } + + /** + * Save the hello using json body. + * + * @param foo The hello doo id + * @param dto The hello body as json + */ +// @Roles({ADMIN}) + @Post("/savebean/:foo") + void saveBean(String foo, HelloDto dto, Context context) { + // save hello data ... + System.out.println("save " + foo + " dto:" + dto); + requireNonNull(foo); + requireNonNull(dto); + requireNonNull(context); + } + + /** + * Create the new Hello using a form. + */ + @Post("saveform") + @Form + void saveForm(HelloForm helloForm) { + System.out.println("saving " + helloForm); + } + + @Form @Post("mySave") + void saveForm324(@Default("junk") String name, String email, String url) { + System.out.println("name " + name + " email:" + email + " url:" + url); + } + + + @Post("saveform2") + @Form + void saveForm2(String name, String email, String url) { + System.out.println("name " + name + " email:" + email + " url:" + url); + } + + @Post("saveform3") + @Form + HelloDto saveForm3(HelloForm helloForm) { + return new HelloDto(52, helloForm.name, helloForm.email); + } + + @Produces("text/plain") + @Get("withValidBean") + String getGetBeanForm(@BeanParam GetBeanForm bean) { + return "ok name:" + bean.name; + } + + @Hidden + @Get + List getAll() { + return myService.findAll(); + } + + // @Hidden + @Delete(":id") + void deleteById(int id) { + System.out.println("deleting " + id); + } + + @Produces("text/plain") + @Get("/withMatrix/:year;author;country/:other") + String getWithMatrixParam(int year, String author, String country, String other, String extra) { + return "yr:" + year + " au:" + author + " co:" + country + " other:" + other + " extra:" + extra; + } + + @Produces("text/plain") + @Get("slash/{name}//other/") + String slashAccepting(String name, String nam0, String nam1) { + return "got name:" + name + " splat0:" + nam0 + " splat1:" + nam1; + } +} diff --git a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/HelloDto.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/HelloDto.java new file mode 100644 index 000000000..d4dbc253c --- /dev/null +++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/HelloDto.java @@ -0,0 +1,48 @@ +package org.example.myapp.web; + +import java.time.Instant; +import java.util.UUID; + +public class HelloDto { + + public int id; + public String name; + public String otherParam; + private UUID gid; + + private Instant whenAction; + + public HelloDto(int id, String name, String otherParam) { + this.id = id; + this.name = name; + this.otherParam = otherParam; + } + + /** + * Jackson constructor. + */ + public HelloDto() { + } + + public UUID getGid() { + return gid; + } + + public void setGid(UUID gid) { + this.gid = gid; + } + + public Instant getWhenAction() { + return whenAction; + } + + public void setWhenAction(Instant whenAction) { + this.whenAction = whenAction; + } + + @Override + public String toString() { + return "id:" + id + " name:" + name + " other:" + otherParam; + } + +} diff --git a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/HelloForm.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/HelloForm.java new file mode 100644 index 000000000..e29d4141a --- /dev/null +++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/HelloForm.java @@ -0,0 +1,41 @@ +package org.example.myapp.web; + +import org.hibernate.validator.constraints.URL; + +import javax.validation.Valid; +import javax.validation.constraints.Email; +import javax.validation.constraints.Future; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; +import java.time.LocalDate; + +@Valid +public class HelloForm { + + @NotNull @Size(min = 2, max = 150) + String name; + + @Email @Size(max = 100) + String email; + + @URL + String url; + + @Future + LocalDate startDate; + + public HelloForm(String name, String email) { + this.name = name; + this.email = email; + } + + @Override + public String toString() { + return "HelloForm{" + + "name='" + name + '\'' + + ", email='" + email + '\'' + + ", url='" + url + '\'' + + ", startDate=" + startDate + + '}'; + } +} diff --git a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/Repository.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/Repository.java new file mode 100644 index 000000000..de24d26ca --- /dev/null +++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/Repository.java @@ -0,0 +1,13 @@ +package org.example.myapp.web; + +import java.util.List; + +public interface Repository { + + T findById(I id); + + List findAll(); + + I save(T bean); +} + diff --git a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/ReqScopedController.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/ReqScopedController.java new file mode 100644 index 000000000..fb5f7ba35 --- /dev/null +++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/ReqScopedController.java @@ -0,0 +1,23 @@ +package org.example.myapp.web; + +import io.avaje.http.api.Controller; +import io.avaje.http.api.Get; +import io.avaje.http.api.Path; +import io.avaje.http.api.Produces; +import io.javalin.http.Context; + +import jakarta.inject.Inject; + +@Controller +@Path("/req-scoped") +class ReqScopedController { + + @Inject + Context context; + + @Produces("text/plain") + @Get + String getSimple() { + return context.url(); + } +} diff --git a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/Roles.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/Roles.java new file mode 100644 index 000000000..29d8f9742 --- /dev/null +++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/Roles.java @@ -0,0 +1,21 @@ +package org.example.myapp.web; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +/** + * Specify permitted roles. + */ +@Target(value={METHOD, TYPE}) +@Retention(value=RUNTIME) +public @interface Roles { + + /** + * Specify the permitted roles. + */ + AppRoles[] value() default {}; +} diff --git a/tests/test-javalin-jsonb/src/main/resources/logback.xml b/tests/test-javalin-jsonb/src/main/resources/logback.xml new file mode 100644 index 000000000..1119a0c85 --- /dev/null +++ b/tests/test-javalin-jsonb/src/main/resources/logback.xml @@ -0,0 +1,18 @@ + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + + + + + + + diff --git a/tests/test-javalin-jsonb/src/main/resources/public/openapi.json b/tests/test-javalin-jsonb/src/main/resources/public/openapi.json new file mode 100644 index 000000000..fe92fc8f0 --- /dev/null +++ b/tests/test-javalin-jsonb/src/main/resources/public/openapi.json @@ -0,0 +1,797 @@ +{ + "openapi" : "3.0.1", + "info" : { + "title" : "Example service", + "description" : "Example Javalin controllers with Java and Maven", + "version" : "" + }, + "paths" : { + "/bars" : { + "get" : { + "tags" : [ ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/bars/find/{code}" : { + "get" : { + "tags" : [ ], + "summary" : "", + "description" : "", + "parameters" : [ { + "name" : "code", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + } ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "array", + "items" : { + "$ref" : "#/components/schemas/Bar" + } + } + } + } + } + } + } + }, + "/bars/{id}" : { + "get" : { + "tags" : [ ], + "summary" : "", + "description" : "", + "parameters" : [ { + "name" : "id", + "in" : "path", + "required" : true, + "schema" : { + "type" : "integer", + "format" : "int64", + "nullable" : false + } + } ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Bar" + } + } + } + } + } + } + }, + "/baz" : { + "get" : { + "tags" : [ ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "array", + "items" : { + "$ref" : "#/components/schemas/Baz" + } + } + } + } + } + } + }, + "post" : { + "tags" : [ ], + "summary" : "", + "description" : "", + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Baz" + } + } + }, + "required" : true + }, + "responses" : { + "201" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "integer", + "format" : "int64" + } + } + } + } + } + } + }, + "/baz/checkparams/{id}" : { + "get" : { + "tags" : [ ], + "summary" : "", + "description" : "", + "parameters" : [ { + "name" : "id", + "in" : "path", + "required" : true, + "schema" : { + "type" : "integer", + "format" : "int32", + "nullable" : false + } + }, { + "name" : "p1", + "in" : "query", + "schema" : { + "type" : "string" + } + }, { + "name" : "p2", + "in" : "query", + "schema" : { + "type" : "number" + } + }, { + "name" : "p3", + "in" : "query", + "schema" : { + "type" : "integer", + "format" : "int32" + } + }, { + "name" : "p4", + "in" : "query", + "schema" : { + "type" : "number" + } + }, { + "name" : "body", + "in" : "query", + "schema" : { + "type" : "string" + } + } ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/baz/findbyname/{name}" : { + "get" : { + "tags" : [ ], + "summary" : "Find the baz by name", + "description" : "This is some more comments about this method.", + "parameters" : [ { + "name" : "name", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + } ], + "responses" : { + "200" : { + "description" : "The list of baz", + "content" : { + "application/json" : { + "schema" : { + "type" : "array", + "items" : { + "$ref" : "#/components/schemas/Baz" + } + } + } + } + } + } + } + }, + "/baz/{id}" : { + "get" : { + "tags" : [ ], + "summary" : "", + "description" : "", + "parameters" : [ { + "name" : "id", + "in" : "path", + "required" : true, + "schema" : { + "type" : "integer", + "format" : "int64" + } + } ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Baz" + } + } + } + } + } + } + }, + "/hello" : { + "post" : { + "tags" : [ ], + "summary" : "Simple example post with JSON body response", + "description" : "", + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/HelloDto" + } + } + }, + "required" : true + }, + "responses" : { + "201" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/HelloDto" + } + } + } + } + } + } + }, + "/hello/findbyname/{name}" : { + "get" : { + "tags" : [ ], + "summary" : "Find Hellos by name", + "description" : "", + "parameters" : [ { + "name" : "name", + "in" : "path", + "description" : "The name to search for", + "required" : true, + "schema" : { + "type" : "string" + } + }, { + "name" : "myParam", + "in" : "query", + "schema" : { + "type" : "string" + } + } ], + "responses" : { + "200" : { + "description" : "The Hellos that we found.", + "content" : { + "application/json" : { + "schema" : { + "type" : "array", + "items" : { + "$ref" : "#/components/schemas/HelloDto" + } + } + } + } + } + } + } + }, + "/hello/message" : { + "get" : { + "tags" : [ ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/hello/mySave" : { + "post" : { + "tags" : [ ], + "summary" : "", + "description" : "", + "requestBody" : { + "content" : { + "application/x-www-form-urlencoded" : { + "schema" : { + "type" : "object", + "properties" : { + "name" : { + "type" : "string" + }, + "email" : { + "type" : "string" + }, + "url" : { + "type" : "string" + } + } + } + } + }, + "required" : true + }, + "responses" : { + "201" : { + "description" : "No content" + } + } + } + }, + "/hello/savebean/{foo}" : { + "post" : { + "tags" : [ ], + "summary" : "Save the hello using json body", + "description" : "", + "parameters" : [ { + "name" : "foo", + "in" : "path", + "description" : "The hello doo id", + "required" : true, + "schema" : { + "type" : "string" + } + } ], + "requestBody" : { + "description" : "The hello body as json", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/HelloDto" + } + } + }, + "required" : true + }, + "responses" : { + "201" : { + "description" : "No content" + } + } + } + }, + "/hello/saveform" : { + "post" : { + "tags" : [ ], + "summary" : "Create the new Hello using a form", + "description" : "", + "requestBody" : { + "content" : { + "application/x-www-form-urlencoded" : { + "schema" : { + "$ref" : "#/components/schemas/HelloForm" + } + } + }, + "required" : true + }, + "responses" : { + "201" : { + "description" : "No content" + } + } + } + }, + "/hello/saveform2" : { + "post" : { + "tags" : [ ], + "summary" : "", + "description" : "", + "requestBody" : { + "content" : { + "application/x-www-form-urlencoded" : { + "schema" : { + "type" : "object", + "properties" : { + "name" : { + "type" : "string" + }, + "email" : { + "type" : "string" + }, + "url" : { + "type" : "string" + } + } + } + } + }, + "required" : true + }, + "responses" : { + "201" : { + "description" : "No content" + } + } + } + }, + "/hello/saveform3" : { + "post" : { + "tags" : [ ], + "summary" : "", + "description" : "", + "requestBody" : { + "content" : { + "application/x-www-form-urlencoded" : { + "schema" : { + "$ref" : "#/components/schemas/HelloForm" + } + } + }, + "required" : true + }, + "responses" : { + "201" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/HelloDto" + } + } + } + } + } + } + }, + "/hello/slash/{name}//other/" : { + "get" : { + "tags" : [ ], + "summary" : "", + "description" : "", + "parameters" : [ { + "name" : "name", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + }, { + "name" : "nam0", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + }, { + "name" : "nam1", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + } ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/hello/withMatrix/{year_segment}/{other}" : { + "get" : { + "tags" : [ ], + "summary" : "", + "description" : "", + "parameters" : [ { + "name" : "year", + "in" : "path", + "required" : true, + "schema" : { + "type" : "integer", + "format" : "int32", + "nullable" : false + } + }, { + "name" : "author", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + }, { + "name" : "country", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + }, { + "name" : "other", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + }, { + "name" : "extra", + "in" : "query", + "schema" : { + "type" : "string" + } + } ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/hello/withValidBean" : { + "get" : { + "tags" : [ ], + "summary" : "", + "description" : "", + "parameters" : [ { + "name" : "bean", + "in" : "bean", + "schema" : { + "$ref" : "#/components/schemas/GetBeanForm" + } + } ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/hello/{id}" : { + "delete" : { + "tags" : [ ], + "summary" : "", + "description" : "", + "parameters" : [ { + "name" : "id", + "in" : "path", + "required" : true, + "schema" : { + "type" : "integer", + "format" : "int32", + "nullable" : false + } + } ], + "responses" : { + "204" : { + "description" : "No content" + } + } + } + }, + "/hello/{id}/{date}" : { + "get" : { + "tags" : [ ], + "summary" : "Return the Hello DTO", + "description" : "", + "parameters" : [ { + "name" : "id", + "in" : "path", + "description" : "The hello Id.", + "required" : true, + "schema" : { + "type" : "integer", + "format" : "int32", + "nullable" : false + } + }, { + "name" : "date", + "in" : "path", + "description" : "The name of the hello", + "required" : true, + "schema" : { + "type" : "string", + "format" : "date" + } + }, { + "name" : "otherParam", + "in" : "query", + "description" : "Optional other parameter", + "schema" : { + "type" : "string" + } + } ], + "responses" : { + "200" : { + "description" : "The Hello DTO given the id and name.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/HelloDto" + } + } + } + } + }, + "deprecated" : true + } + }, + "/req-scoped" : { + "get" : { + "tags" : [ ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + } + }, + "components" : { + "schemas" : { + "Bar" : { + "type" : "object", + "properties" : { + "id" : { + "type" : "integer", + "format" : "int64", + "nullable" : false + }, + "name" : { + "type" : "string" + } + } + }, + "Baz" : { + "type" : "object", + "properties" : { + "id" : { + "type" : "integer", + "format" : "int64" + }, + "name" : { + "type" : "string" + }, + "startDate" : { + "type" : "string", + "format" : "date" + } + } + }, + "GetBeanForm" : { + "type" : "object", + "properties" : { + "name" : { + "maxLength" : 150, + "minLength" : 2, + "type" : "string", + "nullable" : false + }, + "email" : { + "maxLength" : 100, + "type" : "string", + "format" : "email" + } + } + }, + "HelloDto" : { + "type" : "object", + "properties" : { + "id" : { + "type" : "integer", + "format" : "int32", + "nullable" : false + }, + "name" : { + "type" : "string" + }, + "otherParam" : { + "type" : "string" + }, + "gid" : { + "type" : "string", + "format" : "uuid" + }, + "whenAction" : { + "type" : "string", + "format" : "date-time" + } + } + }, + "HelloForm" : { + "type" : "object", + "properties" : { + "name" : { + "maxLength" : 150, + "minLength" : 2, + "type" : "string", + "nullable" : false + }, + "email" : { + "maxLength" : 100, + "type" : "string", + "format" : "email" + }, + "url" : { + "type" : "string" + }, + "startDate" : { + "type" : "string", + "format" : "date" + } + } + } + } + } +} \ No newline at end of file diff --git a/tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/JavalinProcessorTest.java b/tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/JavalinProcessorTest.java new file mode 100644 index 000000000..2f938db84 --- /dev/null +++ b/tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/JavalinProcessorTest.java @@ -0,0 +1,92 @@ +package io.avaje.http.generator; + +import java.io.File; +import java.io.IOException; +import java.io.PrintWriter; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +import java.util.Set; + +import javax.tools.JavaFileObject; +import javax.tools.JavaFileObject.Kind; +import javax.tools.StandardLocation; +import javax.tools.ToolProvider; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; + +import io.avaje.http.generator.javalin.JavalinProcessor; +import io.avaje.inject.generator.Processor; + +class JavalinProcessorTest { + + @AfterEach + void deleteGeneratedFiles() throws IOException { + + Paths.get("openapi.json").toAbsolutePath().toFile().delete(); + Files.walk(Paths.get("org").toAbsolutePath()) + .sorted(Comparator.reverseOrder()) + .map(Path::toFile) + .forEach(File::delete); + Files.walk(Paths.get("io").toAbsolutePath()) + .sorted(Comparator.reverseOrder()) + .map(Path::toFile) + .forEach(File::delete); + } + + @Test + public void runAnnoationProcessor() throws Exception { + final var source = Paths.get("src").toAbsolutePath().toString(); + + final var files = getSourceFiles(source); + + final var compiler = ToolProvider.getSystemJavaCompiler(); + + final var task = + compiler.getTask( + new PrintWriter(System.out), + null, + null, + List.of("--enable-preview", "--release=19"), + null, + files); + task.setProcessors(List.of(new JavalinProcessor(), new Processor())); + + task.call(); + } + + @Test + public void runAnnoationProcessorJsonB() throws Exception { + final var source = Paths.get("src").toAbsolutePath().toString(); + + final var files = getSourceFiles(source); + + final var compiler = ToolProvider.getSystemJavaCompiler(); + + final var task = + compiler.getTask( + new PrintWriter(System.out), + null, + null, + List.of("--enable-preview", "--release=19"), + null, + files); + task.setProcessors(List.of(new JavalinProcessor(false), new Processor())); + + task.call(); + } + + private Iterable getSourceFiles(String source) throws Exception { + final var compiler = ToolProvider.getSystemJavaCompiler(); + final var files = compiler.getStandardFileManager(null, null, null); + + files.setLocation(StandardLocation.SOURCE_PATH, List.of(new File(source))); + + final Set fileKinds = Collections.singleton(Kind.SOURCE); + return files.list(StandardLocation.SOURCE_PATH, "", fileKinds, true); + } +} diff --git a/tests/test-nima-jsonb/src/main/java/org/example/MyForm.java b/tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/MyForm.java similarity index 73% rename from tests/test-nima-jsonb/src/main/java/org/example/MyForm.java rename to tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/MyForm.java index 3c3a75138..2fdaa8595 100644 --- a/tests/test-nima-jsonb/src/main/java/org/example/MyForm.java +++ b/tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/MyForm.java @@ -1,4 +1,4 @@ -package org.example; +package io.avaje.http.generator; public class MyForm { diff --git a/tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/Person.java b/tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/Person.java new file mode 100644 index 000000000..99e60e342 --- /dev/null +++ b/tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/Person.java @@ -0,0 +1,19 @@ +package io.avaje.http.generator; + +public class Person { + private final long id; + private final String name; + + public Person(long id, String name) { + this.id = id; + this.name = name; + } + + public long id() { + return id; + } + + public String name() { + return name; + } +} diff --git a/tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/TestController.java b/tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/TestController.java new file mode 100644 index 000000000..042bf9ef2 --- /dev/null +++ b/tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/TestController.java @@ -0,0 +1,107 @@ +package io.avaje.http.generator; + +import java.util.List; +import java.util.Map; +import java.util.Set; + +import io.avaje.http.api.Controller; +import io.avaje.http.api.Form; +import io.avaje.http.api.Get; +import io.avaje.http.api.Header; +import io.avaje.http.api.MediaType; +import io.avaje.http.api.Post; +import io.avaje.http.api.Produces; +import io.avaje.http.api.Put; +import io.javalin.http.Context; + +@Controller +public class TestController { + + @Get + @Produces(MediaType.TEXT_PLAIN) + String index() { + return "Hello world - index"; + } + + @Get("hello") + @Produces(MediaType.TEXT_PLAIN) + String helloWorld() { + return "Hello world"; + } + + @Get("/get") + @Produces("image/png") + byte[] testBytes() { + return "not really an image but ok".getBytes(); + } + + @Get("/ctx") + void testVoid(Context ctx) { + + ctx.result("success path:" + ctx.path()); + } + + @Get("/header") + String testHeader(@Header String head) { + return head; + } + + @Get("person/{name}") + Person testParamAndBody(String name) { + return new Person(42, name + " hello"); + } + + @Post("/person") + Person testPostPerson(Person body) { + return new Person(42, "Returning " + body.name()); + } + + @Get("person/{sortBy}/list") + List testPersonList(String sortBy) { + return List.of(new Person(42, "fooList"), new Person(43, "barList")); + } + + // curl -v localhost:8081/person/foo/set + @Get("person/{sortBy}/set") + Set testPersonSet(String sortBy) { + return Set.of(new Person(42, "fooSet"), new Person(43, "barSet")); + } + + @Get("person/{sortBy}/map") + Map testPersonMap(String sortBy) { + return Map.of("one", new Person(42, "fooMap"), "two", new Person(43, "barMap")); + } + + @Put("person/update") + String testPersonListBody(List newGuys) { + return "New Guys Added"; + } + + @Put("test/int") + int testIntReturn() { + return 422; + } + + @Put("test/long") + long testLongReturn() { + return 69; + } + + // curl -X POST http://localhost:8081/form + // -H "Content-Type: application/x-www-form-urlencoded" + // -d "name=Jimmy&email=jim@foo&url=notaurl" + @Form + @Post("form") + String testForm(String name, String email, String url) { + return name + "-" + email + "-" + url; + } + + // curl -X POST http://localhost:8081/formBean + // -H "Content-Type:application/x-www-form-urlencoded" + // -d "name=FormBeanJimmy&email=jim@foo&url=notaurl" + @Form + @Post("formBean") + String testFormBean(MyForm form) { + return form.name + "|" + form.email + "|" + form.url; + } +} diff --git a/tests/test-javalin-jsonb/src/test/java/org/example/myapp/BarControllerTest.java b/tests/test-javalin-jsonb/src/test/java/org/example/myapp/BarControllerTest.java new file mode 100644 index 000000000..2c1fd784c --- /dev/null +++ b/tests/test-javalin-jsonb/src/test/java/org/example/myapp/BarControllerTest.java @@ -0,0 +1,43 @@ +package org.example.myapp; + +import org.example.myapp.web.Bar; +import org.junit.jupiter.api.Test; + +import static io.restassured.RestAssured.given; +import static org.assertj.core.api.Assertions.assertThat; +import static org.hamcrest.Matchers.equalTo; + +class BarControllerTest extends BaseWebTest { + + @Test + void getBars() { + given() + .get(baseUrl + "/bars") + .then() + .statusCode(200) + .body(equalTo("Hello")); + } + + @Test + void getById() { + + Bar bar = given() + .get(baseUrl + "/bars/53") + .then() + .statusCode(200) + .extract() + .as(Bar.class); + + assertThat(bar.id).isEqualTo(53L); + assertThat(bar.name).isEqualTo("Rob53"); + } + + @Test + void findByCode() { + given() + .get(baseUrl + "/bars/find/mycode") + .then() + .statusCode(200); + } + +} diff --git a/tests/test-javalin-jsonb/src/test/java/org/example/myapp/BaseWebTest.java b/tests/test-javalin-jsonb/src/test/java/org/example/myapp/BaseWebTest.java new file mode 100644 index 000000000..872f82e48 --- /dev/null +++ b/tests/test-javalin-jsonb/src/test/java/org/example/myapp/BaseWebTest.java @@ -0,0 +1,32 @@ +package org.example.myapp; + +import io.avaje.http.client.HttpClientContext; +import io.avaje.http.client.JacksonBodyAdapter; +import io.javalin.Javalin; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; + +public class BaseWebTest { + + static Javalin webServer; + + public static String baseUrl; + + @BeforeAll + public static void init() { + webServer = Main.start(8887); + baseUrl = "http://localhost:8887"; + } + + @AfterAll + public static void shutdown() { + webServer.stop(); + } + + public static HttpClientContext client() { + return HttpClientContext.builder() + .baseUrl(baseUrl) + .bodyAdapter(new JacksonBodyAdapter()) + .build(); + } +} diff --git a/tests/test-javalin-jsonb/src/test/java/org/example/myapp/BazControllerTest.java b/tests/test-javalin-jsonb/src/test/java/org/example/myapp/BazControllerTest.java new file mode 100644 index 000000000..e197a7084 --- /dev/null +++ b/tests/test-javalin-jsonb/src/test/java/org/example/myapp/BazControllerTest.java @@ -0,0 +1,41 @@ +package org.example.myapp; + +import org.example.myapp.web.Baz; +import org.junit.jupiter.api.Test; + +import static io.restassured.RestAssured.given; +import static org.assertj.core.api.Assertions.assertThat; + +class BazControllerTest extends BaseWebTest { + + @Test + void findAll() { + given() + .get(baseUrl + "/baz") + .then() + .statusCode(200); + } + + @Test + void findById() { + + Baz baz = given() + .get(baseUrl + "/baz/53") + .then() + .statusCode(200) + .extract() + .as(Baz.class); + + assertThat(baz.id).isEqualTo(53L); + assertThat(baz.name).isEqualTo("Baz53"); + } + + @Test + void searchByName() { + given() + .get(baseUrl + "/baz/findbyname/mycode") + .then() + .statusCode(200); + } + +} diff --git a/tests/test-javalin-jsonb/src/test/java/org/example/myapp/ErrorResponse.java b/tests/test-javalin-jsonb/src/test/java/org/example/myapp/ErrorResponse.java new file mode 100644 index 000000000..75eadc95b --- /dev/null +++ b/tests/test-javalin-jsonb/src/test/java/org/example/myapp/ErrorResponse.java @@ -0,0 +1,27 @@ +package org.example.myapp; + +import java.util.LinkedHashMap; +import java.util.Map; + +public class ErrorResponse { + + private String message; + + private Map errors = new LinkedHashMap<>(); + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public Map getErrors() { + return errors; + } + + public void setErrors(Map errors) { + this.errors = errors; + } +} diff --git a/tests/test-javalin-jsonb/src/test/java/org/example/myapp/HelloControllerTest.java b/tests/test-javalin-jsonb/src/test/java/org/example/myapp/HelloControllerTest.java new file mode 100644 index 000000000..c007a848e --- /dev/null +++ b/tests/test-javalin-jsonb/src/test/java/org/example/myapp/HelloControllerTest.java @@ -0,0 +1,308 @@ +package org.example.myapp; + +import io.avaje.http.client.*; +import io.restassured.common.mapper.TypeRef; +import io.restassured.http.ContentType; +import io.restassured.response.Response; +import org.example.myapp.web.HelloDto; +import org.junit.jupiter.api.Test; + +import java.net.http.HttpClient; +import java.net.http.HttpResponse; +import java.util.List; +import java.util.Map; + +import static io.restassured.RestAssured.get; +import static io.restassured.RestAssured.given; +import static org.assertj.core.api.Assertions.assertThat; +import static org.hamcrest.Matchers.equalTo; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +class HelloControllerTest extends BaseWebTest { + + final HttpClientContext clientContext; + + HelloControllerTest() { + this.clientContext = HttpClientContext.builder() + .baseUrl(baseUrl) + .bodyAdapter(new JacksonBodyAdapter()) + .build(); + } + + @Test + void hello() { + final Response response = get(baseUrl + "/hello/message"); + assertThat(response.body().asString()).contains("hello world"); + assertThat(response.statusCode()).isEqualTo(200); + + final HttpResponse hres = clientContext.request().path("hello").path("message") + .GET().asString(); + + assertThat(hres.body()).contains("hello world"); + assertThat(hres.statusCode()).isEqualTo(200); + } + + @Test + void hello2() { + + TypeRef> listDto = new TypeRef>() { }; + final List beans = given() + .get(baseUrl + "/hello") + .then() + .statusCode(200) + .extract() + .as(listDto); + + assertThat(beans).hasSize(2); + + final List helloDtos = clientContext.request() + .path("hello") + .GET().list(HelloDto.class); + + assertThat(helloDtos).hasSize(2); + } + + @Test + void getWithPathParamAndQueryParam() { + + final HelloDto bean = given() + .get(baseUrl + "/hello/43/2020-03-05?otherParam=other") + .then() + .statusCode(200) + .extract() + .as(HelloDto.class); + + assertThat(bean.id).isEqualTo(43L); + assertThat(bean.name).isEqualTo("2020-03-05"); + assertThat(bean.otherParam).isEqualTo("other"); + + final HelloDto dto = clientContext.request() + .path("hello/43/2020-03-05").queryParam("otherParam", "other").queryParam("foo", null) + .GET().bean(HelloDto.class); + + assertThat(dto.id).isEqualTo(43L); + assertThat(dto.name).isEqualTo("2020-03-05"); + assertThat(dto.otherParam).isEqualTo("other"); + } + + @Test + void postIt() { + HelloDto dto = new HelloDto(12, "rob", "other"); + + given().body(dto).post(baseUrl + "/hello") + .then() + .body("id", equalTo(12)) + .body("name", equalTo("posted")) + .body("otherParam", equalTo("other")); + + final BodyWriter from = clientContext.converters().beanWriter(HelloDto.class); + final BodyReader toDto = clientContext.converters().beanReader(HelloDto.class); + + final HelloDto bean = clientContext.request() + .path("hello") + .body(from.write(dto)) + .POST() + .read(toDto); + + assertEquals("posted", bean.name); + assertEquals(12, bean.id); + } + + @Test + void saveBean() { + HelloDto dto = new HelloDto(12, "rob", "other"); + + given().body(dto).post(baseUrl + "/hello/savebean/foo") + .then() + .statusCode(201); + } + + @Test + void postForm_controller_using_formbean() { + + given().urlEncodingEnabled(true) + .param("name", "Bazz") + .param("email", "user@foo.com") + .param("url", "http://foo.com") + .param("startDate", "2030-12-03") + .header("Accept", ContentType.JSON.getAcceptHeader()) + .post(baseUrl + "/hello/saveform") + .then() + .statusCode(201); + } + + @Test + void postForm2_controllerUsingParams() { + + given().urlEncodingEnabled(true) + .param("name", "Bazz") + .param("email", "user@foo.com") + .param("url", "http://foo.com") + .param("startDate", "2020-12-03") + .header("Accept", ContentType.JSON.getAcceptHeader()) + .post(baseUrl + "/hello/saveform2") + .then() + .statusCode(201); + } + + @Test + void postForm3_controllerFormBean_responseJsonDto() { + + final HelloDto bean = clientContext.request() + .path("hello/saveform3") + .formParam("name", "Bax") + .formParam("email", "Bax@foo.com") + .formParam("url", "http://foo.com") + .formParam("startDate", "2030-12-03") + .POST().bean(HelloDto.class); + + assertThat(bean.name).isEqualTo("Bax"); + assertThat(bean.otherParam).isEqualTo("Bax@foo.com"); + assertThat(bean.id).isEqualTo(52); + + given().urlEncodingEnabled(true) + .param("name", "Bax") + .param("email", "Bax@foo.com") + .param("url", "http://foo.com") + .param("startDate", "2030-12-03") + .header("Accept", ContentType.JSON.getAcceptHeader()) + .post(baseUrl + "/hello/saveform3") + .then() + .body("name", equalTo("Bax")) + .body("otherParam", equalTo("Bax@foo.com")) + .body("id", equalTo(52)) + .statusCode(201); + } + + @Test + void postForm_validation_expect_badRequest() { + + final ErrorResponse res = given().urlEncodingEnabled(true) + .param("email", "user@foo.com") + .param("url", "notAValidUrl") + .header("Accept", ContentType.JSON.getAcceptHeader()) + .post(baseUrl + "/hello/saveform") + .then() + .statusCode(422) + .extract() + .as(ErrorResponse.class); + + assertNotNull(res); + assertThat(res.getMessage()).contains("failed validation"); + final Map errors = res.getErrors(); + assertThat(errors.get("url")).isEqualTo("must be a valid URL"); + assertThat(errors.get("name")).isEqualTo("must not be null"); + + try { + clientContext.request() + .path("hello/saveform") + .formParam("email", "user@foo.com") + .formParam("url", "notAValidUrl") + .POST() + .asVoid(); + + } catch (HttpException e) { + assertEquals(422, e.statusCode()); + + final HttpResponse httpResponse = e.httpResponse(); + assertNotNull(httpResponse); + assertEquals(422, httpResponse.statusCode()); + + final ErrorResponse errorResponse = e.bean(ErrorResponse.class); + + final Map errorMap = errorResponse.getErrors(); + assertThat(errorMap.get("url")).isEqualTo("must be a valid URL"); + assertThat(errorMap.get("name")).isEqualTo("must not be null"); + + } + } + + @Test + void get_validate_bean_expect422() { + final HttpResponse hres = clientContext.request() + .path("hello/withValidBean") + .queryParam("email", "user@foo.com") + .GET() + .asString(); + + assertThat(hres.statusCode()).isEqualTo(422); + } + + @Test + void get_validate_bean_expect200() { + final HttpResponse hres = clientContext.request() + .path("hello/withValidBean") + .queryParam("name", "hello") + .queryParam("email", "user@foo.com") + .GET() + .asString(); + + assertThat(hres.statusCode()).isEqualTo(200); + } + + @Test + void delete() { + given().delete(baseUrl + "/hello/52") + .then() + .statusCode(204); + } + + @Test + void getWithMatrixParam() { + given() + .get(baseUrl + "/hello/withMatrix/2011;author=rob;country=nz/foo?extra=banana") + .then() + .statusCode(200) + .body(equalTo("yr:2011 au:rob co:nz other:foo extra:banana")); + + given() + .get(baseUrl + "/hello/withMatrix/2011;author=rob;country=nz/foo") + .then() + .statusCode(200) + .body(equalTo("yr:2011 au:rob co:nz other:foo extra:null")); + + given() + .get(baseUrl + "/hello/withMatrix/2011;author=rob/foo2") + .then() + .statusCode(200) + .body(equalTo("yr:2011 au:rob co:null other:foo2 extra:null")); + + given() + .get(baseUrl + "/hello/withMatrix/2011;country=nz/foo2") + .then() + .statusCode(200) + .body(equalTo("yr:2011 au:null co:nz other:foo2 extra:null")); + + given() + .get(baseUrl + "/hello/withMatrix/2011/foo3") + .then() + .statusCode(200) + .body(equalTo("yr:2011 au:null co:null other:foo3 extra:null")); + + + final HttpResponse httpRes = clientContext.request() + .path("hello/withMatrix/2011") + .matrixParam("author", "rob") + .matrixParam("country", "nz") + .path("foo") + .queryParam("extra", "banana") + + .GET().asString(); + + assertEquals(200, httpRes.statusCode()); + assertEquals("yr:2011 au:rob co:nz other:foo extra:banana", httpRes.body()); + } + + + @Test + void get_slashAcceptingPath_expect200() { + final HttpResponse hres = clientContext.request() + .path("hello/slash/one/a/b/other/x/y/z") + .GET() + .asString(); + + assertThat(hres.statusCode()).isEqualTo(200); + assertEquals("got name:one splat0:a/b splat1:x/y/z", hres.body()); + } +} diff --git a/tests/test-javalin-jsonb/src/test/java/org/example/myapp/ReqScopedControllerTest.java b/tests/test-javalin-jsonb/src/test/java/org/example/myapp/ReqScopedControllerTest.java new file mode 100644 index 000000000..af5f0d420 --- /dev/null +++ b/tests/test-javalin-jsonb/src/test/java/org/example/myapp/ReqScopedControllerTest.java @@ -0,0 +1,24 @@ +package org.example.myapp; + +import io.avaje.http.client.HttpClientContext; +import org.junit.jupiter.api.Test; + +import java.net.http.HttpResponse; + +import static org.assertj.core.api.Assertions.assertThat; + +class ReqScopedControllerTest extends BaseWebTest { + + private final HttpClientContext client = client(); + + @Test + void testGet() { + + final HttpResponse res = client.request() + .path("req-scoped") + .GET().asString(); + + assertThat(res.statusCode()).isEqualTo(200); + assertThat(res.body()).isEqualTo("http://localhost:8887/req-scoped"); + } +} diff --git a/tests/test-javalin-jsonb/src/test/resources/application-test.yaml b/tests/test-javalin-jsonb/src/test/resources/application-test.yaml new file mode 100644 index 000000000..ae43f3a1f --- /dev/null +++ b/tests/test-javalin-jsonb/src/test/resources/application-test.yaml @@ -0,0 +1,6 @@ +ebean: + test: +# shutdown: remove # stop | remove + platform: h2 # h2, postgres, mysql, mariadb, sqlserver, oracle, hana, clickhouse, sqlite + ddlMode: dropCreate # none | dropCreate | create | migration | createOnly | migrationDropCreate + dbName: my_app diff --git a/tests/test-javalin-jsonb/src/test/resources/logback-test.xml b/tests/test-javalin-jsonb/src/test/resources/logback-test.xml new file mode 100644 index 000000000..8467abcc9 --- /dev/null +++ b/tests/test-javalin-jsonb/src/test/resources/logback-test.xml @@ -0,0 +1,19 @@ + + + + TRACE + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + + + + + diff --git a/tests/test-javalin/src/main/java/org/example/myapp/web/HelloController.java b/tests/test-javalin/src/main/java/org/example/myapp/web/HelloController.java index a6ba9a5f8..551d0f0eb 100644 --- a/tests/test-javalin/src/main/java/org/example/myapp/web/HelloController.java +++ b/tests/test-javalin/src/main/java/org/example/myapp/web/HelloController.java @@ -1,18 +1,29 @@ package org.example.myapp.web; -import io.avaje.http.api.*; -import io.javalin.http.Context; -import io.swagger.v3.oas.annotations.Hidden; -import org.example.myapp.service.MyService; - -import jakarta.inject.Inject; +import static java.util.Objects.requireNonNull; -import javax.validation.Valid; import java.time.LocalDate; import java.util.ArrayList; import java.util.List; -import static java.util.Objects.requireNonNull; +import javax.validation.Valid; + +import org.example.myapp.service.MyService; + +import io.avaje.http.api.BeanParam; +import io.avaje.http.api.Controller; +import io.avaje.http.api.Default; +import io.avaje.http.api.Delete; +import io.avaje.http.api.Form; +import io.avaje.http.api.Get; +import io.avaje.http.api.MediaType; +import io.avaje.http.api.Path; +import io.avaje.http.api.Post; +import io.avaje.http.api.Produces; +import io.avaje.http.api.QueryParam; +import io.javalin.http.Context; +import io.swagger.v3.oas.annotations.Hidden; +import jakarta.inject.Inject; /** * Hello resource manager. @@ -47,8 +58,9 @@ String getPlainMessage() { * @return The Hello DTO given the id and name. * @deprecated Please migrate away */ - @Roles({AppRoles.ADMIN, AppRoles.BASIC_USER}) - @Get("/:id/:date") + @Deprecated +@Roles({AppRoles.ADMIN, AppRoles.BASIC_USER}) + @Get("/{id}/{date}") HelloDto hello(int id, LocalDate date, String otherParam) { return new HelloDto(id, date.toString(), otherParam); } @@ -82,7 +94,7 @@ HelloDto post(HelloDto dto) { * @param dto The hello body as json */ // @Roles({ADMIN}) - @Post("/savebean/:foo") + @Post("/savebean/{foo}") void saveBean(String foo, HelloDto dto, Context context) { // save hello data ... System.out.println("save " + foo + " dto:" + dto); @@ -131,7 +143,7 @@ List getAll() { } // @Hidden - @Delete(":id") + @Delete("{id}") void deleteById(int id) { System.out.println("deleting " + id); } diff --git a/tests/test-nima-jsonb/src/main/java/org/example/HelloController.java b/tests/test-nima-jsonb/src/main/java/org/example/HelloController.java index 485752448..3ca1cdd9b 100644 --- a/tests/test-nima-jsonb/src/main/java/org/example/HelloController.java +++ b/tests/test-nima-jsonb/src/main/java/org/example/HelloController.java @@ -12,6 +12,7 @@ import io.avaje.http.api.Post; import io.avaje.http.api.Produces; import io.avaje.http.api.Put; +import io.avaje.http.generator.MyForm; import io.helidon.common.http.HttpMediaType; import io.helidon.nima.webserver.http.ServerRequest; import io.helidon.nima.webserver.http.ServerResponse; From 22e9491f74edcf32a81070f6974e5cf40b5219ee Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Tue, 18 Oct 2022 19:41:38 -0400 Subject: [PATCH 0374/1323] something is up with JsonB --- tests/test-javalin-jsonb/pom.xml | 6 ++ .../main/java/org/example/myapp/web/Bar.java | 3 + .../main/java/org/example/myapp/web/Baz.java | 2 + .../org/example/myapp/web/GetBeanForm.java | 34 +++++++-- .../example/myapp/web/HelloController.java | 32 +++++--- .../java/org/example/myapp/web/HelloDto.java | 2 + .../java/org/example/myapp/web/HelloForm.java | 73 +++++++++++++++---- .../http/generator/JavalinProcessorTest.java | 11 ++- .../io/avaje/http/generator/JsonBFactory.java | 15 ++++ .../java/io/avaje/http/generator/Person.java | 20 ++++- .../avaje/http/generator/TestController.java | 2 +- .../java/org/example/HelloController.java | 1 - .../src/main/java/org/example/MyForm.java | 8 ++ 13 files changed, 166 insertions(+), 43 deletions(-) create mode 100644 tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/JsonBFactory.java create mode 100644 tests/test-nima-jsonb/src/main/java/org/example/MyForm.java diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 0dec4c17d..8d6876bd3 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -36,6 +36,12 @@ javalin ${javalin.version} + + + com.fasterxml.jackson.core + jackson-databind + ${jackson.version} + io.avaje diff --git a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/Bar.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/Bar.java index 72aa5cb14..5d044cbf6 100644 --- a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/Bar.java +++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/Bar.java @@ -1,5 +1,8 @@ package org.example.myapp.web; +import io.avaje.jsonb.Json; + +@Json public class Bar { public long id; diff --git a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/Baz.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/Baz.java index 7bae1ea1c..7fbf3d1fc 100644 --- a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/Baz.java +++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/Baz.java @@ -2,6 +2,8 @@ import java.time.LocalDate; +import io.avaje.jsonb.Json; +@Json public class Baz { public Long id; diff --git a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/GetBeanForm.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/GetBeanForm.java index f92072efb..21eb47db3 100644 --- a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/GetBeanForm.java +++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/GetBeanForm.java @@ -5,14 +5,35 @@ import javax.validation.constraints.NotNull; import javax.validation.constraints.Size; +import io.avaje.jsonb.Json; + +@Json @Valid public class GetBeanForm { - @NotNull @Size(min = 2, max = 150) - String name; + @NotNull + @Size(min = 2, max = 150) + private String name; + + @Email + @Size(max = 100) + private String email; + + public String getName() { + return name; + } - @Email @Size(max = 100) - String email; + public void setName(String name) { + this.name = name; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } public GetBeanForm(String name, String email) { this.name = name; @@ -21,9 +42,6 @@ public GetBeanForm(String name, String email) { @Override public String toString() { - return "HelloForm{" + - "name='" + name + '\'' + - ", email='" + email + '\'' + - '}'; + return "HelloForm{" + "name='" + name + '\'' + ", email='" + email + '\'' + '}'; } } diff --git a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/HelloController.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/HelloController.java index a6ba9a5f8..4996122b3 100644 --- a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/HelloController.java +++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/HelloController.java @@ -1,18 +1,29 @@ package org.example.myapp.web; -import io.avaje.http.api.*; -import io.javalin.http.Context; -import io.swagger.v3.oas.annotations.Hidden; -import org.example.myapp.service.MyService; - -import jakarta.inject.Inject; +import static java.util.Objects.requireNonNull; -import javax.validation.Valid; import java.time.LocalDate; import java.util.ArrayList; import java.util.List; -import static java.util.Objects.requireNonNull; +import javax.validation.Valid; + +import org.example.myapp.service.MyService; + +import io.avaje.http.api.BeanParam; +import io.avaje.http.api.Controller; +import io.avaje.http.api.Default; +import io.avaje.http.api.Delete; +import io.avaje.http.api.Form; +import io.avaje.http.api.Get; +import io.avaje.http.api.MediaType; +import io.avaje.http.api.Path; +import io.avaje.http.api.Post; +import io.avaje.http.api.Produces; +import io.avaje.http.api.QueryParam; +import io.javalin.http.Context; +import io.swagger.v3.oas.annotations.Hidden; +import jakarta.inject.Inject; /** * Hello resource manager. @@ -47,7 +58,8 @@ String getPlainMessage() { * @return The Hello DTO given the id and name. * @deprecated Please migrate away */ - @Roles({AppRoles.ADMIN, AppRoles.BASIC_USER}) + @Deprecated +@Roles({AppRoles.ADMIN, AppRoles.BASIC_USER}) @Get("/:id/:date") HelloDto hello(int id, LocalDate date, String otherParam) { return new HelloDto(id, date.toString(), otherParam); @@ -121,7 +133,7 @@ HelloDto saveForm3(HelloForm helloForm) { @Produces("text/plain") @Get("withValidBean") String getGetBeanForm(@BeanParam GetBeanForm bean) { - return "ok name:" + bean.name; + return "ok name:" + bean.getName(); } @Hidden diff --git a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/HelloDto.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/HelloDto.java index d4dbc253c..abd2ff856 100644 --- a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/HelloDto.java +++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/HelloDto.java @@ -3,6 +3,8 @@ import java.time.Instant; import java.util.UUID; +import io.avaje.jsonb.Json; +@Json public class HelloDto { public int id; diff --git a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/HelloForm.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/HelloForm.java index e29d4141a..7f6aeab63 100644 --- a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/HelloForm.java +++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/HelloForm.java @@ -1,41 +1,84 @@ package org.example.myapp.web; -import org.hibernate.validator.constraints.URL; +import java.time.LocalDate; import javax.validation.Valid; import javax.validation.constraints.Email; import javax.validation.constraints.Future; import javax.validation.constraints.NotNull; import javax.validation.constraints.Size; -import java.time.LocalDate; +import org.hibernate.validator.constraints.URL; + +import io.avaje.jsonb.Json; + +@Json @Valid public class HelloForm { - @NotNull @Size(min = 2, max = 150) + @NotNull + @Size(min = 2, max = 150) String name; - @Email @Size(max = 100) + @Email + @Size(max = 100) String email; +@URL + private String url; +@Future + public LocalDate startDate; - @URL - String url; + public HelloForm(String name, String email) { + this.name = name; + this.email = email; + } - @Future - LocalDate startDate; + public String getName() { + return name; + } - public HelloForm(String name, String email) { + public void setName(String name) { this.name = name; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { this.email = email; } + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public LocalDate getStartDate() { + return startDate; + } + + public void setStartDate(LocalDate startDate) { + this.startDate = startDate; + } + @Override public String toString() { - return "HelloForm{" + - "name='" + name + '\'' + - ", email='" + email + '\'' + - ", url='" + url + '\'' + - ", startDate=" + startDate + - '}'; + return "HelloForm{" + + "name='" + + name + + '\'' + + ", email='" + + email + + '\'' + + ", url='" + + url + + '\'' + + ", startDate=" + + startDate + + '}'; } } diff --git a/tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/JavalinProcessorTest.java b/tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/JavalinProcessorTest.java index 2f938db84..d171f3170 100644 --- a/tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/JavalinProcessorTest.java +++ b/tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/JavalinProcessorTest.java @@ -1,5 +1,7 @@ package io.avaje.http.generator; +import static org.assertj.core.api.Assertions.assertThat; + import java.io.File; import java.io.IOException; import java.io.PrintWriter; @@ -20,7 +22,7 @@ import org.junit.jupiter.api.Test; import io.avaje.http.generator.javalin.JavalinProcessor; -import io.avaje.inject.generator.Processor; +import io.avaje.jsonb.generator.Processor; class JavalinProcessorTest { @@ -54,9 +56,9 @@ public void runAnnoationProcessor() throws Exception { List.of("--enable-preview", "--release=19"), null, files); - task.setProcessors(List.of(new JavalinProcessor(), new Processor())); + task.setProcessors(List.of(new JavalinProcessor())); - task.call(); + assertThat(task.call()).isTrue(); } @Test @@ -75,9 +77,10 @@ public void runAnnoationProcessorJsonB() throws Exception { List.of("--enable-preview", "--release=19"), null, files); - task.setProcessors(List.of(new JavalinProcessor(false), new Processor())); + task.setProcessors(List.of(new JavalinProcessor(false),new Processor())); task.call(); + assertThat(task.call()).isTrue(); } private Iterable getSourceFiles(String source) throws Exception { diff --git a/tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/JsonBFactory.java b/tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/JsonBFactory.java new file mode 100644 index 000000000..ea04e16a0 --- /dev/null +++ b/tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/JsonBFactory.java @@ -0,0 +1,15 @@ +package io.avaje.http.generator; + +import io.avaje.inject.Bean; +import io.avaje.inject.Factory; +import io.avaje.inject.Secondary; +import io.avaje.jsonb.Jsonb; + +@Factory +public class JsonBFactory { + @Bean + @Secondary + Jsonb jsonB() { + return Jsonb.builder().failOnUnknown(false).build(); + } +} diff --git a/tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/Person.java b/tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/Person.java index 99e60e342..58624feba 100644 --- a/tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/Person.java +++ b/tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/Person.java @@ -1,19 +1,31 @@ package io.avaje.http.generator; +import io.avaje.jsonb.Json; + +@Json public class Person { - private final long id; - private final String name; + + long id; + String name; public Person(long id, String name) { this.id = id; this.name = name; } - public long id() { + public long getId() { return id; } - public String name() { + public void setId(long id) { + this.id = id; + } + + public String getName() { return name; } + + public void setName(String name) { + this.name = name; + } } diff --git a/tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/TestController.java b/tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/TestController.java index 042bf9ef2..35d36f19e 100644 --- a/tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/TestController.java +++ b/tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/TestController.java @@ -53,7 +53,7 @@ Person testParamAndBody(String name) { @Post("/person") Person testPostPerson(Person body) { - return new Person(42, "Returning " + body.name()); + return new Person(42, "Returning " + body.getName()); } @Get("person/{sortBy}/list") diff --git a/tests/test-nima-jsonb/src/main/java/org/example/HelloController.java b/tests/test-nima-jsonb/src/main/java/org/example/HelloController.java index 3ca1cdd9b..485752448 100644 --- a/tests/test-nima-jsonb/src/main/java/org/example/HelloController.java +++ b/tests/test-nima-jsonb/src/main/java/org/example/HelloController.java @@ -12,7 +12,6 @@ import io.avaje.http.api.Post; import io.avaje.http.api.Produces; import io.avaje.http.api.Put; -import io.avaje.http.generator.MyForm; import io.helidon.common.http.HttpMediaType; import io.helidon.nima.webserver.http.ServerRequest; import io.helidon.nima.webserver.http.ServerResponse; diff --git a/tests/test-nima-jsonb/src/main/java/org/example/MyForm.java b/tests/test-nima-jsonb/src/main/java/org/example/MyForm.java new file mode 100644 index 000000000..3c3a75138 --- /dev/null +++ b/tests/test-nima-jsonb/src/main/java/org/example/MyForm.java @@ -0,0 +1,8 @@ +package org.example; + +public class MyForm { + + public String name; + public String email; + public String url; +} From 40c9da2b0d18003490abefe589957ae50bcbf96e Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Tue, 18 Oct 2022 20:50:47 -0400 Subject: [PATCH 0375/1323] tests finally pass --- .../io/avaje/http/generator/core/JsonBUtil.java | 2 +- .../io.avaje.jsonb.Jsonb$GeneratedComponent | 1 + tests/test-javalin-jsonb/pom.xml | 4 ++-- .../java/org/example/myapp/web/test}/MyForm.java | 2 +- .../java/org/example/myapp/web/test}/Person.java | 2 +- .../example/myapp/web/test}/TestController.java | 15 ++++++++------- .../http/generator/JavalinProcessorTest.java | 9 +++------ .../io/avaje/http/generator/JsonBFactory.java | 15 --------------- 8 files changed, 17 insertions(+), 33 deletions(-) create mode 100644 tests/test-javalin-jsonb/io.avaje.jsonb.Jsonb$GeneratedComponent rename tests/test-javalin-jsonb/src/{test/java/io/avaje/http/generator => main/java/org/example/myapp/web/test}/MyForm.java (71%) rename tests/test-javalin-jsonb/src/{test/java/io/avaje/http/generator => main/java/org/example/myapp/web/test}/Person.java (91%) rename tests/test-javalin-jsonb/src/{test/java/io/avaje/http/generator => main/java/org/example/myapp/web/test}/TestController.java (93%) delete mode 100644 tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/JsonBFactory.java diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java index 9da1b416f..598879747 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java @@ -41,7 +41,7 @@ public static void writeJsonbType(UType type, Append writer) { writer.append(" this.%sJsonType = jsonB.type(", type.shortName()); if (!type.isGeneric()) { - writer.append("%s.class)", type.full()); + writer.append("%s.class)", PrimitiveUtil.wrap(type.full())); } else { switch (type.mainType()) { case "java.util.List": diff --git a/tests/test-javalin-jsonb/io.avaje.jsonb.Jsonb$GeneratedComponent b/tests/test-javalin-jsonb/io.avaje.jsonb.Jsonb$GeneratedComponent new file mode 100644 index 000000000..05a41ae93 --- /dev/null +++ b/tests/test-javalin-jsonb/io.avaje.jsonb.Jsonb$GeneratedComponent @@ -0,0 +1 @@ +org.example.myapp.web.jsonb.GeneratedJsonComponent \ No newline at end of file diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 8d6876bd3..87e13b317 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -36,7 +36,7 @@ javalin ${javalin.version} - + com.fasterxml.jackson.core jackson-databind @@ -86,7 +86,7 @@ io.avaje avaje-jsonb-generator - 1.0-RC2 + 1.0-RC3 provided diff --git a/tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/MyForm.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/MyForm.java similarity index 71% rename from tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/MyForm.java rename to tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/MyForm.java index 2fdaa8595..8b7207843 100644 --- a/tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/MyForm.java +++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/MyForm.java @@ -1,4 +1,4 @@ -package io.avaje.http.generator; +package org.example.myapp.web.test; public class MyForm { diff --git a/tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/Person.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/Person.java similarity index 91% rename from tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/Person.java rename to tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/Person.java index 58624feba..434251ba0 100644 --- a/tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/Person.java +++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/Person.java @@ -1,4 +1,4 @@ -package io.avaje.http.generator; +package org.example.myapp.web.test; import io.avaje.jsonb.Json; diff --git a/tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/TestController.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController.java similarity index 93% rename from tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/TestController.java rename to tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController.java index 35d36f19e..9e2b64468 100644 --- a/tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/TestController.java +++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController.java @@ -1,4 +1,4 @@ -package io.avaje.http.generator; +package org.example.myapp.web.test; import java.util.List; import java.util.Map; @@ -9,27 +9,28 @@ import io.avaje.http.api.Get; import io.avaje.http.api.Header; import io.avaje.http.api.MediaType; +import io.avaje.http.api.Path; import io.avaje.http.api.Post; import io.avaje.http.api.Produces; import io.avaje.http.api.Put; import io.javalin.http.Context; - +@Path("test/") @Controller public class TestController { @Get @Produces(MediaType.TEXT_PLAIN) - String index() { + String basic() { return "Hello world - index"; } - @Get("hello") + @Get("hey") @Produces(MediaType.TEXT_PLAIN) String helloWorld() { return "Hello world"; } - @Get("/get") + @Get("/byte") @Produces("image/png") byte[] testBytes() { return "not really an image but ok".getBytes(); @@ -77,12 +78,12 @@ String testPersonListBody(List newGuys) { return "New Guys Added"; } - @Put("test/int") + @Put("int") int testIntReturn() { return 422; } - @Put("test/long") + @Put("long") long testLongReturn() { return 69; } diff --git a/tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/JavalinProcessorTest.java b/tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/JavalinProcessorTest.java index d171f3170..1878fbc71 100644 --- a/tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/JavalinProcessorTest.java +++ b/tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/JavalinProcessorTest.java @@ -30,14 +30,12 @@ class JavalinProcessorTest { void deleteGeneratedFiles() throws IOException { Paths.get("openapi.json").toAbsolutePath().toFile().delete(); + Paths.get("io.avaje.jsonb.Jsonb$GeneratedComponent").toAbsolutePath().toFile().delete(); + Files.walk(Paths.get("org").toAbsolutePath()) .sorted(Comparator.reverseOrder()) .map(Path::toFile) .forEach(File::delete); - Files.walk(Paths.get("io").toAbsolutePath()) - .sorted(Comparator.reverseOrder()) - .map(Path::toFile) - .forEach(File::delete); } @Test @@ -77,9 +75,8 @@ public void runAnnoationProcessorJsonB() throws Exception { List.of("--enable-preview", "--release=19"), null, files); - task.setProcessors(List.of(new JavalinProcessor(false),new Processor())); + task.setProcessors(List.of(new JavalinProcessor(false), new Processor())); - task.call(); assertThat(task.call()).isTrue(); } diff --git a/tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/JsonBFactory.java b/tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/JsonBFactory.java deleted file mode 100644 index ea04e16a0..000000000 --- a/tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/JsonBFactory.java +++ /dev/null @@ -1,15 +0,0 @@ -package io.avaje.http.generator; - -import io.avaje.inject.Bean; -import io.avaje.inject.Factory; -import io.avaje.inject.Secondary; -import io.avaje.jsonb.Jsonb; - -@Factory -public class JsonBFactory { - @Bean - @Secondary - Jsonb jsonB() { - return Jsonb.builder().failOnUnknown(false).build(); - } -} From 854c2e1bc533bc78d5f21cfe3a69f0b3d146f4c7 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Wed, 19 Oct 2022 00:42:03 -0400 Subject: [PATCH 0376/1323] last this --- .../http/generator/core/ElementReader.java | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java index d5d1a81bb..55c0b32d4 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java @@ -86,42 +86,42 @@ private void readAnnotations(Element element, ParamType defaultType) { } final var beanParam = element.getAnnotation(BeanParam.class); if (beanParam != null) { - paramType = ParamType.BEANPARAM; + this.paramType = ParamType.BEANPARAM; return; } final var queryParam = element.getAnnotation(QueryParam.class); if (queryParam != null) { - paramName = nameFrom(queryParam.value(), varName); - paramType = ParamType.QUERYPARAM; + this.paramName = nameFrom(queryParam.value(), varName); + this.paramType = ParamType.QUERYPARAM; return; } final var formParam = element.getAnnotation(FormParam.class); if (formParam != null) { - paramName = nameFrom(formParam.value(), varName); - paramType = ParamType.FORMPARAM; + this.paramName = nameFrom(formParam.value(), varName); + this.paramType = ParamType.FORMPARAM; return; } final var cookieParam = element.getAnnotation(Cookie.class); if (cookieParam != null) { - paramName = nameFrom(cookieParam.value(), varName); - paramType = ParamType.COOKIE; - paramDefault = null; + this.paramName = nameFrom(cookieParam.value(), varName); + this.paramType = ParamType.COOKIE; + this.paramDefault = null; return; } final var headerParam = element.getAnnotation(Header.class); if (headerParam != null) { - paramName = nameFrom(headerParam.value(), Util.initcapSnake(snakeName)); - paramType = ParamType.HEADER; - paramDefault = null; + this.paramName = nameFrom(headerParam.value(), Util.initcapSnake(snakeName)); + this.paramType = ParamType.HEADER; + this.paramDefault = null; return; } if (paramType == null) { - impliedParamType = true; + this.impliedParamType = true; if (typeHandler != null) { // a scalar type that we know how to convert - paramType = defaultType; + this.paramType = defaultType; } else { - paramType = formMarker ? ParamType.FORM : ParamType.BODY; + this.paramType = formMarker ? ParamType.FORM : ParamType.BODY; } } } From a7c2352fd5452545d90fc50513442e558f7c46c6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 19 Oct 2022 06:07:45 +0000 Subject: [PATCH 0377/1323] Bump jackson-databind from 2.12.6.1 to 2.13.4.1 in /tests/test-jex Bumps [jackson-databind](https://github.com/FasterXML/jackson) from 2.12.6.1 to 2.13.4.1. - [Release notes](https://github.com/FasterXML/jackson/releases) - [Commits](https://github.com/FasterXML/jackson/commits) --- updated-dependencies: - dependency-name: com.fasterxml.jackson.core:jackson-databind dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- tests/test-jex/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 3ac277fe2..6f207acdb 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -18,7 +18,7 @@ org.example.myapp.Main 2.2 2.0.8 - 2.12.6.1 + 2.13.4.1 8.9 1.19-SNAPSHOT From ccdf7015e65d28491c73443a475b2403752955c2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 19 Oct 2022 06:07:53 +0000 Subject: [PATCH 0378/1323] Bump jackson-databind from 2.12.6.1 to 2.13.4.1 in /tests/test-client Bumps [jackson-databind](https://github.com/FasterXML/jackson) from 2.12.6.1 to 2.13.4.1. - [Release notes](https://github.com/FasterXML/jackson/releases) - [Commits](https://github.com/FasterXML/jackson/commits) --- updated-dependencies: - dependency-name: com.fasterxml.jackson.core:jackson-databind dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- tests/test-client/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index 4f619bea1..e602bd308 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -42,7 +42,7 @@ com.fasterxml.jackson.core jackson-databind - 2.12.6.1 + 2.13.4.1 From 0e18991127b71a426fdd7b547da8ae03d85f6f9a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 19 Oct 2022 06:08:19 +0000 Subject: [PATCH 0379/1323] Bump jackson-databind from 2.12.6.1 to 2.13.4.1 in /tests/test-javalin Bumps [jackson-databind](https://github.com/FasterXML/jackson) from 2.12.6.1 to 2.13.4.1. - [Release notes](https://github.com/FasterXML/jackson/releases) - [Commits](https://github.com/FasterXML/jackson/commits) --- updated-dependencies: - dependency-name: com.fasterxml.jackson.core:jackson-databind dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- tests/test-javalin/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 738aaa19f..5004254cf 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -19,7 +19,7 @@ 4.6.0 2.0.8 1.3.71 - 2.12.6.1 + 2.13.4.1 1.19-SNAPSHOT From 8625b9fc6725502465ac78d947e661852c2a46c1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 19 Oct 2022 06:09:55 +0000 Subject: [PATCH 0380/1323] Bump jackson-databind from 2.13.3 to 2.13.4.1 in /http-generator-core Bumps [jackson-databind](https://github.com/FasterXML/jackson) from 2.13.3 to 2.13.4.1. - [Release notes](https://github.com/FasterXML/jackson/releases) - [Commits](https://github.com/FasterXML/jackson/commits) --- updated-dependencies: - dependency-name: com.fasterxml.jackson.core:jackson-databind dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- http-generator-core/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 909e79b93..92a6f1062 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -13,7 +13,7 @@ 2.0.8 - 2.13.3 + 2.13.4.1 From d40a180521cd192d12ca35691cecc79a1a17fdbb Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Wed, 19 Oct 2022 16:23:55 -0400 Subject: [PATCH 0381/1323] Update README.md --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 59305d1ab..eb9ad82c4 100644 --- a/README.md +++ b/README.md @@ -57,7 +57,6 @@ Javalin.create() .start(); ``` - ## Usage with Helidon SE The annotation processor will generate controller classes implementing the Helidon Service interface, which we can use From e4febc393a2c938ae4b904930e475860e0c7989d Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Thu, 20 Oct 2022 12:47:55 +1300 Subject: [PATCH 0382/1323] Update README for Nima with JsonB generation --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 59305d1ab..b291b52b2 100644 --- a/README.md +++ b/README.md @@ -247,13 +247,13 @@ public class WidgetController$Route implements HttpService { private final WidgetController controller; - private final JsonType getByIdReturnedJsonType; - private final JsonType> getAllReturnedJsonType; + private final JsonType widgetJsonType; + private final JsonType> listWidgetJsonType; public WidgetController$Route(WidgetController controller, Jsonb jsonB) { this.controller = controller; - this.getByIdReturnedJsonType = jsonB.type(org.example.hello.WidgetController.Widget.class); - this.getAllReturnedJsonType = jsonB.type(org.example.hello.WidgetController.Widget.class).list(); + this.widgetJsonType = jsonB.type(org.example.hello.WidgetController.Widget.class); + this.listWidgetJsonType = jsonB.type(org.example.hello.WidgetController.Widget.class).list(); } @Override @@ -267,14 +267,14 @@ public class WidgetController$Route implements HttpService { int id = asInt(pathParams.first("id").get()); var result = controller.getById(id); res.headers().contentType(io.helidon.common.http.HttpMediaType.APPLICATION_JSON); - getByIdReturnedJsonType.toJson(result, res.outputStream()); + widgetJsonType.toJson(result, res.outputStream()); } private void _getAll(ServerRequest req, ServerResponse res) { var pathParams = req.path().pathParameters(); var result = controller.getAll(); res.headers().contentType(io.helidon.common.http.HttpMediaType.APPLICATION_JSON); - getAllReturnedJsonType.toJson(result, res.outputStream()); + listWidgetJsonType.toJson(result, res.outputStream()); } } From a10dd131457a2b1c82b2dae96d38fb878f03e38c Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Wed, 19 Oct 2022 21:10:54 -0400 Subject: [PATCH 0383/1323] release 11 --- .../test-javalin-jsonb/io.avaje.jsonb.Jsonb$GeneratedComponent | 1 - .../test/java/io/avaje/http/generator/JavalinProcessorTest.java | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) delete mode 100644 tests/test-javalin-jsonb/io.avaje.jsonb.Jsonb$GeneratedComponent diff --git a/tests/test-javalin-jsonb/io.avaje.jsonb.Jsonb$GeneratedComponent b/tests/test-javalin-jsonb/io.avaje.jsonb.Jsonb$GeneratedComponent deleted file mode 100644 index 05a41ae93..000000000 --- a/tests/test-javalin-jsonb/io.avaje.jsonb.Jsonb$GeneratedComponent +++ /dev/null @@ -1 +0,0 @@ -org.example.myapp.web.jsonb.GeneratedJsonComponent \ No newline at end of file diff --git a/tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/JavalinProcessorTest.java b/tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/JavalinProcessorTest.java index 1878fbc71..bb6c52e1d 100644 --- a/tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/JavalinProcessorTest.java +++ b/tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/JavalinProcessorTest.java @@ -51,7 +51,7 @@ public void runAnnoationProcessor() throws Exception { new PrintWriter(System.out), null, null, - List.of("--enable-preview", "--release=19"), + List.of("--enable-preview", "--release=11"), null, files); task.setProcessors(List.of(new JavalinProcessor())); From b052639c2715bd02dedf937aedc2fb1666052405 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Wed, 19 Oct 2022 21:16:39 -0400 Subject: [PATCH 0384/1323] remove style --- .../http/generator/core/ElementReader.java | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java index 55c0b32d4..f4ae26a58 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java @@ -55,10 +55,10 @@ public class ElementReader { this.paramName = varName; if (!contextType) { readAnnotations(element, defaultType); - this.useValidation = useValidation(); + useValidation = useValidation(); } else { - this.paramType = ParamType.CONTEXT; - this.useValidation = false; + paramType = ParamType.CONTEXT; + useValidation = false; } } @@ -66,7 +66,7 @@ private boolean useValidation() { if (typeHandler != null) { return false; } - final var elementType = ctx.getTypeElement(rawType); + TypeElement elementType = ctx.getTypeElement(rawType); return elementType != null && elementType.getAnnotation(Valid.class) != null; } @@ -75,33 +75,33 @@ private void readAnnotations(Element element, ParamType defaultType) { notNullKotlin = (element.getAnnotation(org.jetbrains.annotations.NotNull.class) != null); //notNullJavax = (element.getAnnotation(javax.validation.constraints.NotNull.class) != null); - final var defaultVal = element.getAnnotation(Default.class); + Default defaultVal = element.getAnnotation(Default.class); if (defaultVal != null) { - paramDefault = defaultVal.value(); + this.paramDefault = defaultVal.value(); } - final var form = element.getAnnotation(Form.class); + Form form = element.getAnnotation(Form.class); if (form != null) { paramType = ParamType.FORM; return; } - final var beanParam = element.getAnnotation(BeanParam.class); + BeanParam beanParam = element.getAnnotation(BeanParam.class); if (beanParam != null) { this.paramType = ParamType.BEANPARAM; return; } - final var queryParam = element.getAnnotation(QueryParam.class); + QueryParam queryParam = element.getAnnotation(QueryParam.class); if (queryParam != null) { this.paramName = nameFrom(queryParam.value(), varName); this.paramType = ParamType.QUERYPARAM; return; } - final var formParam = element.getAnnotation(FormParam.class); + FormParam formParam = element.getAnnotation(FormParam.class); if (formParam != null) { this.paramName = nameFrom(formParam.value(), varName); this.paramType = ParamType.FORMPARAM; return; } - final var cookieParam = element.getAnnotation(Cookie.class); + Cookie cookieParam = element.getAnnotation(Cookie.class); if (cookieParam != null) { this.paramName = nameFrom(cookieParam.value(), varName); this.paramType = ParamType.COOKIE; From 20267f4da28910f7c09fc52c19ffebea8e87541a Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Wed, 19 Oct 2022 21:21:20 -0400 Subject: [PATCH 0385/1323] Update ElementReader.java --- .../http/generator/core/ElementReader.java | 23 +++++++++++-------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java index f4ae26a58..3a033853a 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java @@ -81,10 +81,10 @@ private void readAnnotations(Element element, ParamType defaultType) { } Form form = element.getAnnotation(Form.class); if (form != null) { - paramType = ParamType.FORM; + this.paramType = ParamType.FORM; return; } - BeanParam beanParam = element.getAnnotation(BeanParam.class); + BeanParam beanParam = element.getAnnotation(BeanParam.class); if (beanParam != null) { this.paramType = ParamType.BEANPARAM; return; @@ -108,7 +108,7 @@ private void readAnnotations(Element element, ParamType defaultType) { this.paramDefault = null; return; } - final var headerParam = element.getAnnotation(Header.class); + Header headerParam = element.getAnnotation(Header.class); if (headerParam != null) { this.paramName = nameFrom(headerParam.value(), Util.initcapSnake(snakeName)); this.paramType = ParamType.HEADER; @@ -164,7 +164,7 @@ private String shortType() { void addImports(ControllerReader bean) { if (typeHandler != null) { - final var importType = typeHandler.getImportType(); + String importType = typeHandler.getImportType(); if (importType != null) { bean.addImportType(rawType); } @@ -202,11 +202,14 @@ void writeValidate(Append writer) { } void writeCtxGet(Append writer, PathSegments segments) { - if (isPlatformContext() || (paramType == ParamType.BODY && ctx.platform().isBodyMethodParam())) { - // body passed as method parameter (Helidon) + if (isPlatformContext()) { + // no conversion for this parameter + return; + } + if (paramType == ParamType.BODY && ctx.platform().isBodyMethodParam()) { // body passed as method parameter (Helidon) return; } - final var shortType = shortType(); + String shortType = shortType(); writer.append("%s var %s = ", ctx.platform().indent(), varName); if (setValue(writer, segments, shortType)) { writer.append(";").eol(); @@ -236,11 +239,11 @@ private boolean setValue(Append writer, PathSegments segments, String shortType) return false; } if (impliedParamType) { - final var segment = segments.segment(varName); + PathSegments.Segment segment = segments.segment(varName); if (segment != null) { // path or matrix parameter - final var requiredParam = segment.isRequired(varName); - final var asMethod = (typeHandler == null) ? null : (requiredParam) ? typeHandler.asMethod() : typeHandler.toMethod(); + boolean requiredParam = segment.isRequired(varName); + String asMethod = (typeHandler == null) ? null : (requiredParam) ? typeHandler.asMethod() : typeHandler.toMethod(); if (asMethod != null) { writer.append(asMethod); } From 64e932206991a880d0bdf4acf7e07ba7f70527fa Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Wed, 19 Oct 2022 21:27:54 -0400 Subject: [PATCH 0386/1323] Update ElementReader.java --- .../http/generator/core/ElementReader.java | 42 +++++++++---------- 1 file changed, 20 insertions(+), 22 deletions(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java index 3a033853a..b8d85e037 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java @@ -1,19 +1,14 @@ package io.avaje.http.generator.core; -import static io.avaje.http.generator.core.ParamType.RESPONSE_HANDLER; +import io.avaje.http.api.*; +import io.avaje.http.generator.core.openapi.MethodDocBuilder; +import io.avaje.http.generator.core.openapi.MethodParamDocBuilder; import javax.lang.model.element.Element; +import javax.lang.model.element.TypeElement; import javax.validation.Valid; -import io.avaje.http.api.BeanParam; -import io.avaje.http.api.Cookie; -import io.avaje.http.api.Default; -import io.avaje.http.api.Form; -import io.avaje.http.api.FormParam; -import io.avaje.http.api.Header; -import io.avaje.http.api.QueryParam; -import io.avaje.http.generator.core.openapi.MethodDocBuilder; -import io.avaje.http.generator.core.openapi.MethodParamDocBuilder; +import static io.avaje.http.generator.core.ParamType.RESPONSE_HANDLER; public class ElementReader { @@ -206,7 +201,8 @@ void writeCtxGet(Append writer, PathSegments segments) { // no conversion for this parameter return; } - if (paramType == ParamType.BODY && ctx.platform().isBodyMethodParam()) { // body passed as method parameter (Helidon) + if (paramType == ParamType.BODY && ctx.platform().isBodyMethodParam()) { + // body passed as method parameter (Helidon) return; } String shortType = shortType(); @@ -256,7 +252,7 @@ private boolean setValue(Append writer, PathSegments segments, String shortType) } } - final var asMethod = (typeHandler == null) ? null : typeHandler.toMethod(); + String asMethod = (typeHandler == null) ? null : typeHandler.toMethod(); if (asMethod != null) { writer.append(asMethod); } @@ -265,17 +261,19 @@ private boolean setValue(Append writer, PathSegments segments, String shortType) // this is a body (POST, PATCH) writer.append(ctx.platform().bodyAsClass(type)); - }else if (hasParamDefault()) { - ctx.platform().writeReadParameter(writer, paramType, paramName, paramDefault); } else { - final var checkNull = notNullKotlin || (paramType == ParamType.FORMPARAM && typeHandler.isPrimitive()); - if (checkNull) { - writer.append("checkNull("); - } - ctx.platform().writeReadParameter(writer, paramType, paramName); - //writer.append("ctx.%s(\"%s\")", paramType, paramName); - if (checkNull) { - writer.append(", \"%s\")", paramName); + if (hasParamDefault()) { + ctx.platform().writeReadParameter(writer, paramType, paramName, paramDefault); + } else { + boolean checkNull = notNullKotlin || (paramType == ParamType.FORMPARAM && typeHandler.isPrimitive()); + if (checkNull) { + writer.append("checkNull("); + } + ctx.platform().writeReadParameter(writer, paramType, paramName); + //writer.append("ctx.%s(\"%s\")", paramType, paramName); + if (checkNull) { + writer.append(", \"%s\")", paramName); + } } } From 7329ca438d0b6d15e63267b44a3a14db218eced2 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Wed, 19 Oct 2022 21:30:27 -0400 Subject: [PATCH 0387/1323] Update ElementReader.java --- .../main/java/io/avaje/http/generator/core/ElementReader.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java index b8d85e037..7b8cc0864 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java @@ -284,8 +284,8 @@ private boolean setValue(Append writer, PathSegments segments, String shortType) } private void writeForm(Append writer, String shortType, String varName, ParamType defaultParamType) { - final var formBeanType = ctx.getTypeElement(rawType); - final var form = new BeanParamReader(ctx, formBeanType, varName, shortType, defaultParamType); + TypeElement formBeanType = ctx.getTypeElement(rawType); + BeanParamReader form = new BeanParamReader(ctx, formBeanType, varName, shortType, defaultParamType); form.write(writer); } From cd21c9218af48861467a9d63e55a41ead679979a Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Wed, 19 Oct 2022 21:31:48 -0400 Subject: [PATCH 0388/1323] Update JavalinProcessorTest.java --- .../test/java/io/avaje/http/generator/JavalinProcessorTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/JavalinProcessorTest.java b/tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/JavalinProcessorTest.java index bb6c52e1d..60a72ff53 100644 --- a/tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/JavalinProcessorTest.java +++ b/tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/JavalinProcessorTest.java @@ -51,7 +51,7 @@ public void runAnnoationProcessor() throws Exception { new PrintWriter(System.out), null, null, - List.of("--enable-preview", "--release=11"), + List.of("--release=11"), null, files); task.setProcessors(List.of(new JavalinProcessor())); From 85d6f754480912430ddc029521e372b292394f33 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Wed, 19 Oct 2022 21:34:22 -0400 Subject: [PATCH 0389/1323] Update JavalinProcessorTest.java --- .../test/java/io/avaje/http/generator/JavalinProcessorTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/JavalinProcessorTest.java b/tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/JavalinProcessorTest.java index 60a72ff53..d460fd3fc 100644 --- a/tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/JavalinProcessorTest.java +++ b/tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/JavalinProcessorTest.java @@ -72,7 +72,7 @@ public void runAnnoationProcessorJsonB() throws Exception { new PrintWriter(System.out), null, null, - List.of("--enable-preview", "--release=19"), + List.of("--release=11"), null, files); task.setProcessors(List.of(new JavalinProcessor(false), new Processor())); From d36168e38caf6786e56d7ba007c59ffc4439b78d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 20 Oct 2022 08:43:26 +0000 Subject: [PATCH 0390/1323] Bump jackson-databind in /tests/test-javalin-jsonb Bumps [jackson-databind](https://github.com/FasterXML/jackson) from 2.12.6.1 to 2.13.4.1. - [Release notes](https://github.com/FasterXML/jackson/releases) - [Commits](https://github.com/FasterXML/jackson/commits) --- updated-dependencies: - dependency-name: com.fasterxml.jackson.core:jackson-databind dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- tests/test-javalin-jsonb/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 87e13b317..0b6b6f5c2 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -19,7 +19,7 @@ 5.1.1 2.0.8 1.3.71 - 2.12.6.1 + 2.13.4.1 1.19-SNAPSHOT From 90a249610b455d64d8eb45fb5d921f9d364ccb64 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Thu, 20 Oct 2022 21:48:56 +1300 Subject: [PATCH 0391/1323] Use max_line_length = 135, remove extraneous LICENSE, format pom --- .editorconfig | 1 + tests/test-javalin-jsonb/LICENSE | 201 -------------------- tests/test-javalin-jsonb/pom.xml | 309 ++++++++++++++++--------------- 3 files changed, 156 insertions(+), 355 deletions(-) delete mode 100644 tests/test-javalin-jsonb/LICENSE diff --git a/.editorconfig b/.editorconfig index 837d975fa..83aec7c10 100644 --- a/.editorconfig +++ b/.editorconfig @@ -10,3 +10,4 @@ indent_style = space insert_final_newline = true trim_trailing_whitespace = true spaces_around_operators = true +max_line_length = 135 diff --git a/tests/test-javalin-jsonb/LICENSE b/tests/test-javalin-jsonb/LICENSE deleted file mode 100644 index 261eeb9e9..000000000 --- a/tests/test-javalin-jsonb/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 0b6b6f5c2..4305cfd54 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -1,156 +1,157 @@ - - 4.0.0 - - org.example - test-javalin-jsonb - 1 - - - org.avaje - java11-oss - 3.8 - - - - - true - org.example.myapp.Main - 5.1.1 - 2.0.8 - 1.3.71 - 2.13.4.1 - 1.19-SNAPSHOT - - - - - - org.avaje - logback - 1.0 - - - - io.javalin - javalin - ${javalin.version} - - - - com.fasterxml.jackson.core - jackson-databind - ${jackson.version} - - - - io.avaje - avaje-inject - 8.9 - - - - io.avaje - avaje-http-api - ${avaje-http-version} - - - - io.avaje - avaje-http-hibernate-validator - 2.8 - - - - io.swagger.core.v3 - swagger-annotations - ${swagger.version} - - - - - - io.avaje - avaje-inject-generator - 8.9 - provided - - - - io.avaje - avaje-http-javalin-generator - ${avaje-http-version} - provided - - - - io.avaje - avaje-jsonb-generator - 1.0-RC3 - provided - - - - - io.avaje - junit - 1.1 - test - - - - io.rest-assured - rest-assured - 5.0.1 - test - - - - io.avaje - avaje-http-client - 1.16 - test - - - - - - app - - - - io.dinject - openapi-maven-plugin - 1.2 - - - main - process-classes - - openapi - - - - - - - io.repaint.maven - tiles-maven-plugin - 2.22 - true - - - org.avaje.tile:lib-classpath:1.1 - - - - - - - - - - HEAD - scm:git:git@github.com:avaje/avaje-http.git - + + 4.0.0 + + org.example + test-javalin-jsonb + 1 + + + org.avaje + java11-oss + 3.8 + + + + + true + org.example.myapp.Main + 5.1.1 + 2.0.8 + 1.3.71 + 2.13.4.1 + 1.19-SNAPSHOT + + + + + + org.avaje + logback + 1.0 + + + + io.javalin + javalin + ${javalin.version} + + + + com.fasterxml.jackson.core + jackson-databind + ${jackson.version} + + + + io.avaje + avaje-inject + 8.9 + + + + io.avaje + avaje-http-api + ${avaje-http-version} + + + + io.avaje + avaje-http-hibernate-validator + 2.8 + + + + io.swagger.core.v3 + swagger-annotations + ${swagger.version} + + + + + + io.avaje + avaje-inject-generator + 8.9 + provided + + + + io.avaje + avaje-http-javalin-generator + ${avaje-http-version} + provided + + + + io.avaje + avaje-jsonb-generator + 1.0-RC3 + provided + + + + + io.avaje + junit + 1.1 + test + + + + io.rest-assured + rest-assured + 5.0.1 + test + + + + io.avaje + avaje-http-client + 1.16 + test + + + + + + app + + + + io.dinject + openapi-maven-plugin + 1.2 + + + main + process-classes + + openapi + + + + + + + io.repaint.maven + tiles-maven-plugin + 2.22 + true + + + org.avaje.tile:lib-classpath:1.1 + + + + + + + + + + HEAD + scm:git:git@github.com:avaje/avaje-http.git + From 5c3ca08755a15178fa77b93381e1326ed781f355 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Thu, 20 Oct 2022 22:01:24 +1300 Subject: [PATCH 0392/1323] Format only changes --- .../javalin/ControllerMethodWriter.java | 25 +- .../generator/javalin/ControllerWriter.java | 35 +- .../generator/javalin/JavalinAdapter.java | 11 +- .../generator/javalin/JavalinProcessor.java | 7 +- .../helidon/nima/ControllerMethodWriter.java | 4 +- .../helidon/nima/ControllerWriter.java | 30 +- .../helidon/nima/NimaPlatformAdapter.java | 10 +- .../generator/helidon/nima/NimaProcessor.java | 7 +- .../src/main/resources/public/openapi.json | 420 ++++++++++++++++++ 9 files changed, 462 insertions(+), 87 deletions(-) diff --git a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java index 29a10b1c9..19dd3791a 100644 --- a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java +++ b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java @@ -1,16 +1,11 @@ package io.avaje.http.generator.javalin; import io.avaje.http.api.MediaType; -import io.avaje.http.generator.core.Append; -import io.avaje.http.generator.core.MethodParam; -import io.avaje.http.generator.core.MethodReader; -import io.avaje.http.generator.core.PathSegments; -import io.avaje.http.generator.core.ProcessingContext; -import io.avaje.http.generator.core.UType; -import io.avaje.http.generator.core.Util; -import io.avaje.http.generator.core.WebMethod; +import io.avaje.http.generator.core.*; -/** Write code to register Web route for a given controller method. */ +/** + * Write code to register Web route for a given controller method. + */ class ControllerMethodWriter { private final MethodReader method; @@ -19,8 +14,7 @@ class ControllerMethodWriter { private final ProcessingContext ctx; private final boolean useJsonB; - ControllerMethodWriter( - MethodReader method, Append writer, ProcessingContext ctx, boolean useJsonB) { + ControllerMethodWriter(MethodReader method, Append writer, ProcessingContext ctx, boolean useJsonB) { this.method = method; this.writer = writer; this.webMethod = method.getWebMethod(); @@ -33,9 +27,7 @@ void write(boolean requestScoped) { final var segments = method.getPathSegments(); final var fullPath = segments.fullPath(); - writer - .append(" ApiBuilder.%s(\"%s\", ctx -> {", webMethod.name().toLowerCase(), fullPath) - .eol(); + writer.append(" ApiBuilder.%s(\"%s\", ctx -> {", webMethod.name().toLowerCase(), fullPath).eol(); writer.append(" ctx.status(%s);", method.getStatusCode()).eol(); final var matrixSegments = segments.matrixSegments(); @@ -97,10 +89,7 @@ private void writeContextReturn() { if (produces == null || MediaType.APPLICATION_JSON.equalsIgnoreCase(produces)) { if (useJsonB) { final var uType = UType.parse(method.getReturnType()); - writer.append( - " %sJsonType.toJson(result, ctx.contentType(\"application/json\").outputStream());", - uType.shortName()); - + writer.append(" %sJsonType.toJson(result, ctx.contentType(\"application/json\").outputStream());", uType.shortName()); } else { writer.append(" ctx.json(result);"); } diff --git a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java index a4c0ecfd8..59de8005a 100644 --- a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java +++ b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java @@ -1,18 +1,13 @@ package io.avaje.http.generator.javalin; +import io.avaje.http.generator.core.*; + import java.io.IOException; import java.util.Map; -import io.avaje.http.generator.core.BaseControllerWriter; -import io.avaje.http.generator.core.Constants; -import io.avaje.http.generator.core.ControllerReader; -import io.avaje.http.generator.core.JsonBUtil; -import io.avaje.http.generator.core.MethodReader; -import io.avaje.http.generator.core.PrimitiveUtil; -import io.avaje.http.generator.core.ProcessingContext; -import io.avaje.http.generator.core.UType; - -/** Write Javalin specific Controller WebRoute handling adapter. */ +/** + * Write Javalin specific Controller WebRoute handling adapter. + */ class ControllerWriter extends BaseControllerWriter { private static final String AT_GENERATED = "@Generated(\"avaje-javalin-generator\")"; @@ -20,8 +15,7 @@ class ControllerWriter extends BaseControllerWriter { private final boolean useJsonB; private final Map jsonTypes; - ControllerWriter(ControllerReader reader, ProcessingContext ctx, boolean jsonB) - throws IOException { + ControllerWriter(ControllerReader reader, ProcessingContext ctx, boolean jsonB) throws IOException { super(reader, ctx); this.useJsonB = jsonB; if (useJsonB) { @@ -64,11 +58,11 @@ private void writeClassStart() { writer.append(AT_GENERATED).eol(); writer.append("@Component").eol(); writer - .append("public class ") - .append(shortName) - .append("$Route implements WebRoutes {") - .eol() - .eol(); + .append("public class ") + .append(shortName) + .append("$Route implements WebRoutes {") + .eol() + .eol(); var controllerName = "controller"; var controllerType = shortName; @@ -83,13 +77,8 @@ private void writeClassStart() { } for (final UType type : jsonTypes.values()) { - writer - .append( - " private final JsonType<%s> %sJsonType;", - PrimitiveUtil.wrap(type.full()), type.shortName()) - .eol(); + writer.append(" private final JsonType<%s> %sJsonType;", PrimitiveUtil.wrap(type.full()), type.shortName()).eol(); } - writer.eol(); writer.append(" public %s$Route(%s %s", shortName, controllerType, controllerName); diff --git a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinAdapter.java b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinAdapter.java index a2182e32a..6db6c07df 100644 --- a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinAdapter.java +++ b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinAdapter.java @@ -1,12 +1,8 @@ package io.avaje.http.generator.javalin; -import java.util.List; +import io.avaje.http.generator.core.*; -import io.avaje.http.generator.core.Append; -import io.avaje.http.generator.core.ControllerReader; -import io.avaje.http.generator.core.ParamType; -import io.avaje.http.generator.core.PlatformAdapter; -import io.avaje.http.generator.core.UType; +import java.util.List; class JavalinAdapter implements PlatformAdapter { @@ -68,8 +64,7 @@ public void writeReadParameter(Append writer, ParamType paramType, String paramN } @Override - public void writeReadParameter( - Append writer, ParamType paramType, String paramName, String paramDefault) { + public void writeReadParameter(Append writer, ParamType paramType, String paramName, String paramDefault) { writer.append("withDefault(ctx.%s(\"%s\"), \"%s\")", paramType, paramName, paramDefault); } } diff --git a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinProcessor.java b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinProcessor.java index 0f6fe0c97..4d6285675 100644 --- a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinProcessor.java +++ b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinProcessor.java @@ -1,12 +1,12 @@ package io.avaje.http.generator.javalin; -import java.io.IOException; - import io.avaje.http.generator.core.BaseProcessor; import io.avaje.http.generator.core.ControllerReader; import io.avaje.http.generator.core.PlatformAdapter; import io.avaje.http.generator.core.ProcessingContext; +import java.io.IOException; + public class JavalinProcessor extends BaseProcessor { private boolean useJsonB; @@ -30,8 +30,7 @@ protected PlatformAdapter providePlatformAdapter() { } @Override - public void writeControllerAdapter(ProcessingContext ctx, ControllerReader reader) - throws IOException { + public void writeControllerAdapter(ProcessingContext ctx, ControllerReader reader) throws IOException { new ControllerWriter(reader, ctx, useJsonB).write(); } } diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java index e61e53ea0..628afa7c0 100644 --- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java +++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java @@ -50,9 +50,7 @@ void writeHandler(boolean requestScoped) { .orElseThrow() .getUType() .shortName(); - writer - .append(" var %s = %sJsonType.fromJson(req.content().inputStream());", method.getBodyName(), fieldName) - .eol(); + writer.append(" var %s = %sJsonType.fromJson(req.content().inputStream());", method.getBodyName(), fieldName).eol(); } else { // use default helidon content negotiation diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java index 5f8004f13..c50153082 100644 --- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java +++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java @@ -1,27 +1,21 @@ package io.avaje.http.generator.helidon.nima; +import io.avaje.http.generator.core.*; + import java.io.IOException; import java.util.List; import java.util.Map; -import io.avaje.http.generator.core.BaseControllerWriter; -import io.avaje.http.generator.core.Constants; -import io.avaje.http.generator.core.ControllerReader; -import io.avaje.http.generator.core.JsonBUtil; -import io.avaje.http.generator.core.MethodReader; -import io.avaje.http.generator.core.PrimitiveUtil; -import io.avaje.http.generator.core.ProcessingContext; -import io.avaje.http.generator.core.UType; - -/** Write Helidon specific web route adapter (a Helidon Service). */ +/** + * Write Helidon specific web route adapter (a Helidon Service). + */ class ControllerWriter extends BaseControllerWriter { private static final String AT_GENERATED = "@Generated(\"avaje-helidon-nima-generator\")"; private final boolean useJsonB; private final Map jsonTypes; - ControllerWriter(ControllerReader reader, ProcessingContext ctx, boolean jsonB) - throws IOException { + ControllerWriter(ControllerReader reader, ProcessingContext ctx, boolean jsonB) throws IOException { super(reader, ctx); this.useJsonB = jsonB; if (useJsonB) { @@ -50,9 +44,9 @@ void write() { private List writerMethods() { return reader.getMethods().stream() - .filter(MethodReader::isWebMethod) - .map(it -> new ControllerMethodWriter(it, writer, ctx, useJsonB)) - .toList(); + .filter(MethodReader::isWebMethod) + .map(it -> new ControllerMethodWriter(it, writer, ctx, useJsonB)) + .toList(); } private void writeAddRoutes() { @@ -93,11 +87,7 @@ private void writeClassStart() { writer.append(" private final Validator validator;").eol(); } for (final UType type : jsonTypes.values()) { - writer - .append( - " private final JsonType<%s> %sJsonType;", - PrimitiveUtil.wrap(type.full()), type.shortName()) - .eol(); + writer.append(" private final JsonType<%s> %sJsonType;", PrimitiveUtil.wrap(type.full()), type.shortName()).eol(); } writer.eol(); diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/NimaPlatformAdapter.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/NimaPlatformAdapter.java index bccfefcb9..990e95f63 100644 --- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/NimaPlatformAdapter.java +++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/NimaPlatformAdapter.java @@ -1,12 +1,8 @@ package io.avaje.http.generator.helidon.nima; -import java.util.List; +import io.avaje.http.generator.core.*; -import io.avaje.http.generator.core.Append; -import io.avaje.http.generator.core.ControllerReader; -import io.avaje.http.generator.core.ParamType; -import io.avaje.http.generator.core.PlatformAdapter; -import io.avaje.http.generator.core.UType; +import java.util.List; class NimaPlatformAdapter implements PlatformAdapter { @@ -30,7 +26,7 @@ public String platformVariable(String rawType) { if (HELIDON_FORMPARAMS.equals(rawType)) { return "formParams"; } - return "unknownVariable for: "+rawType; + return "unknownVariable for: " + rawType; } @Override diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/NimaProcessor.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/NimaProcessor.java index 4b1bc6c9e..c65a83b6a 100644 --- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/NimaProcessor.java +++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/NimaProcessor.java @@ -1,12 +1,12 @@ package io.avaje.http.generator.helidon.nima; -import java.io.IOException; - import io.avaje.http.generator.core.BaseProcessor; import io.avaje.http.generator.core.ControllerReader; import io.avaje.http.generator.core.PlatformAdapter; import io.avaje.http.generator.core.ProcessingContext; +import java.io.IOException; + public class NimaProcessor extends BaseProcessor { private boolean jsonB; @@ -30,8 +30,7 @@ protected PlatformAdapter providePlatformAdapter() { } @Override - public void writeControllerAdapter(ProcessingContext ctx, ControllerReader reader) - throws IOException { + public void writeControllerAdapter(ProcessingContext ctx, ControllerReader reader) throws IOException { new ControllerWriter(reader, ctx, jsonB).write(); } } diff --git a/tests/test-javalin-jsonb/src/main/resources/public/openapi.json b/tests/test-javalin-jsonb/src/main/resources/public/openapi.json index fe92fc8f0..212c84cb7 100644 --- a/tests/test-javalin-jsonb/src/main/resources/public/openapi.json +++ b/tests/test-javalin-jsonb/src/main/resources/public/openapi.json @@ -696,6 +696,393 @@ } } } + }, + "/test" : { + "get" : { + "tags" : [ ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/test/byte" : { + "get" : { + "tags" : [ ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "", + "content" : { + "image/png" : { + "schema" : { + "type" : "array", + "items" : { + "$ref" : "#/components/schemas/byte" + } + } + } + } + } + } + } + }, + "/test/ctx" : { + "get" : { + "tags" : [ ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "No content" + } + } + } + }, + "/test/form" : { + "post" : { + "tags" : [ ], + "summary" : "", + "description" : "", + "requestBody" : { + "content" : { + "application/x-www-form-urlencoded" : { + "schema" : { + "type" : "object", + "properties" : { + "name" : { + "type" : "string" + }, + "email" : { + "type" : "string" + }, + "url" : { + "type" : "string" + } + } + } + } + }, + "required" : true + }, + "responses" : { + "201" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/test/formBean" : { + "post" : { + "tags" : [ ], + "summary" : "", + "description" : "", + "requestBody" : { + "content" : { + "application/x-www-form-urlencoded" : { + "schema" : { + "$ref" : "#/components/schemas/MyForm" + } + } + }, + "required" : true + }, + "responses" : { + "201" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/test/header" : { + "get" : { + "tags" : [ ], + "summary" : "", + "description" : "", + "parameters" : [ { + "name" : "head", + "in" : "header", + "schema" : { + "type" : "string" + } + } ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/test/hey" : { + "get" : { + "tags" : [ ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/test/int" : { + "put" : { + "tags" : [ ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "integer", + "format" : "int32", + "nullable" : false + } + } + } + } + } + } + }, + "/test/long" : { + "put" : { + "tags" : [ ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "integer", + "format" : "int64", + "nullable" : false + } + } + } + } + } + } + }, + "/test/person" : { + "post" : { + "tags" : [ ], + "summary" : "", + "description" : "", + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Person" + } + } + }, + "required" : true + }, + "responses" : { + "201" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Person" + } + } + } + } + } + } + }, + "/test/person/update" : { + "put" : { + "tags" : [ ], + "summary" : "", + "description" : "", + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "type" : "array", + "items" : { + "$ref" : "#/components/schemas/E" + } + } + } + }, + "required" : true + }, + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/test/person/{name}" : { + "get" : { + "tags" : [ ], + "summary" : "", + "description" : "", + "parameters" : [ { + "name" : "name", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + } ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Person" + } + } + } + } + } + } + }, + "/test/person/{sortBy}/list" : { + "get" : { + "tags" : [ ], + "summary" : "", + "description" : "", + "parameters" : [ { + "name" : "sortBy", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + } ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "array", + "items" : { + "$ref" : "#/components/schemas/Person" + } + } + } + } + } + } + } + }, + "/test/person/{sortBy}/map" : { + "get" : { + "tags" : [ ], + "summary" : "", + "description" : "", + "parameters" : [ { + "name" : "sortBy", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + } ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "object", + "additionalProperties" : { + "$ref" : "#/components/schemas/Person" + } + } + } + } + } + } + } + }, + "/test/person/{sortBy}/set" : { + "get" : { + "tags" : [ ], + "summary" : "", + "description" : "", + "parameters" : [ { + "name" : "sortBy", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + } ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "array", + "items" : { + "$ref" : "#/components/schemas/Person" + } + } + } + } + } + } + } } }, "components" : { @@ -729,6 +1116,9 @@ } } }, + "E" : { + "type" : "object" + }, "GetBeanForm" : { "type" : "object", "properties" : { @@ -791,6 +1181,36 @@ "format" : "date" } } + }, + "MyForm" : { + "type" : "object", + "properties" : { + "name" : { + "type" : "string" + }, + "email" : { + "type" : "string" + }, + "url" : { + "type" : "string" + } + } + }, + "Person" : { + "type" : "object", + "properties" : { + "id" : { + "type" : "integer", + "format" : "int64", + "nullable" : false + }, + "name" : { + "type" : "string" + } + } + }, + "byte" : { + "type" : "object" } } } From 3bd775cf815d3932981c13ec90782eba7da02b05 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Thu, 20 Oct 2022 22:16:13 +1300 Subject: [PATCH 0393/1323] Refactor rename methods to use accessor style (from getter style) --- .../generator/client/ClientMethodWriter.java | 78 +++++++++---------- .../generator/client/ClientProcessor.java | 4 +- .../http/generator/client/ClientWriter.java | 2 +- .../generator/core/BaseControllerWriter.java | 8 +- .../http/generator/core/BaseProcessor.java | 2 +- .../http/generator/core/BeanParamReader.java | 22 +++--- .../http/generator/core/ControllerReader.java | 14 ++-- .../http/generator/core/ElementReader.java | 26 +++---- .../avaje/http/generator/core/JsonBUtil.java | 17 ++-- .../http/generator/core/MethodParam.java | 28 +++---- .../http/generator/core/MethodReader.java | 34 ++++---- .../avaje/http/generator/core/ParamType.java | 2 +- .../http/generator/core/PathSegments.java | 2 +- .../generator/core/ProcessingContext.java | 4 +- .../http/generator/core/TypeHandler.java | 2 +- .../io/avaje/http/generator/core/TypeMap.java | 8 +- .../core/openapi/MethodDocBuilder.java | 16 ++-- .../core/openapi/MethodParamDocBuilder.java | 12 +-- .../helidon/ControllerMethodWriter.java | 16 ++-- .../generator/helidon/ControllerWriter.java | 2 +- .../helidon/HelidonPlatformAdapter.java | 4 +- .../javalin/ControllerMethodWriter.java | 12 +-- .../generator/javalin/ControllerWriter.java | 4 +- .../generator/jex/ControllerMethodWriter.java | 10 +-- .../http/generator/jex/ControllerWriter.java | 2 +- .../helidon/nima/ControllerMethodWriter.java | 34 ++++---- .../helidon/nima/ControllerWriter.java | 4 +- .../helidon/nima/NimaPlatformAdapter.java | 4 +- 28 files changed, 186 insertions(+), 187 deletions(-) diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java index bebf499e4..ff0c4f3b2 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java @@ -26,32 +26,32 @@ class ClientMethodWriter { ClientMethodWriter(MethodReader method, Append writer, ProcessingContext ctx) { this.method = method; this.writer = writer; - this.webMethod = method.getWebMethod(); + this.webMethod = method.webMethod(); this.ctx = ctx; - this.returnType = Util.parseType(method.getReturnType()); + this.returnType = Util.parseType(method.returnType()); } void addImportTypes(ControllerReader reader) { reader.addImportTypes(returnType.importTypes()); - for (MethodParam param : method.getParams()) { + for (MethodParam param : method.params()) { param.addImports(reader); } } private void methodStart(Append writer) { - for (MethodParam param : method.getParams()) { + for (MethodParam param : method.params()) { checkBodyHandler(param); } - writer.append(" // %s %s", webMethod, method.getWebMethodPath()).eol(); + writer.append(" // %s %s", webMethod, method.webMethodPath()).eol(); writer.append(" @Override").eol(); writer.append(" public %s%s %s(", methodGenericParams, returnType.shortType(), method.simpleName()); int count = 0; - for (MethodParam param : method.getParams()) { + for (MethodParam param : method.params()) { if (count++ > 0) { writer.append(", "); } - writer.append(param.getUType().shortType()).append(" "); - writer.append(param.getName()); + writer.append(param.utype().shortType()).append(" "); + writer.append(param.name()); } writer.append(") {").eol(); } @@ -60,10 +60,10 @@ private void methodStart(Append writer) { * Assign a method parameter as *the* BodyHandler. */ private void checkBodyHandler(MethodParam param) { - if (param.getRawType().startsWith(BODY_HANDLER)) { + if (param.rawType().startsWith(BODY_HANDLER)) { param.setResponseHandler(); bodyHandlerParam = param; - methodGenericParams = param.getUType().genericParams(); + methodGenericParams = param.utype().genericParams(); } } @@ -75,8 +75,8 @@ void write() { } writer.append("clientContext.request()").eol(); - PathSegments pathSegments = method.getPathSegments(); - Set segments = pathSegments.getSegments(); + PathSegments pathSegments = method.pathSegments(); + Set segments = pathSegments.segments(); writeHeaders(); writePaths(segments); @@ -88,7 +88,7 @@ void write() { } private void writeEnd() { - WebMethod webMethod = method.getWebMethod(); + WebMethod webMethod = method.webMethod(); writer.append(" .%s()", webMethod.name()).eol(); if (returnType == UType.VOID) { writer.append(" .asVoid();").eol(); @@ -144,21 +144,21 @@ private void writeResponse(String type0, String type1) { private void writeWithHandler() { if (bodyHandlerParam != null) { - writer.append(".handler(%s);", bodyHandlerParam.getName()).eol(); + writer.append(".handler(%s);", bodyHandlerParam.name()).eol(); } else { writer.append(".handler(responseHandler);").eol(); // Better to barf here? } } private void writeQueryParams(PathSegments pathSegments) { - for (MethodParam param : method.getParams()) { - ParamType paramType = param.getParamType(); + for (MethodParam param : method.params()) { + ParamType paramType = param.paramType(); if (paramType == ParamType.QUERYPARAM) { - if (pathSegments.segment(param.getParamName()) == null) { + if (pathSegments.segment(param.paramName()) == null) { if (isMap(param)) { - writer.append(" .queryParam(%s)", param.getName()).eol(); + writer.append(" .queryParam(%s)", param.name()).eol(); } else { - writer.append(" .queryParam(\"%s\", %s)", param.getParamName(), param.getName()).eol(); + writer.append(" .queryParam(\"%s\", %s)", param.paramName(), param.name()).eol(); } } } @@ -166,35 +166,35 @@ private void writeQueryParams(PathSegments pathSegments) { } private void writeHeaders() { - for (MethodParam param : method.getParams()) { - ParamType paramType = param.getParamType(); + for (MethodParam param : method.params()) { + ParamType paramType = param.paramType(); if (paramType == ParamType.HEADER) { if (isMap(param)) { - writer.append(" .header(%s)", param.getName()).eol(); + writer.append(" .header(%s)", param.name()).eol(); } else { - writer.append(" .header(\"%s\", %s)", param.getParamName(), param.getName()).eol(); + writer.append(" .header(\"%s\", %s)", param.paramName(), param.name()).eol(); } } } } private void writeBeanParams(PathSegments segments) { - for (MethodParam param : method.getParams()) { - final String varName = param.getName(); - ParamType paramType = param.getParamType(); + for (MethodParam param : method.params()) { + final String varName = param.name(); + ParamType paramType = param.paramType(); PathSegments.Segment segment = segments.segment(varName); if (segment == null && paramType == ParamType.BEANPARAM) { - TypeElement formBeanType = ctx.getTypeElement(param.getRawType()); - BeanParamReader form = new BeanParamReader(ctx, formBeanType, param.getName(), param.getShortType(), ParamType.QUERYPARAM); + TypeElement formBeanType = ctx.typeElement(param.rawType()); + BeanParamReader form = new BeanParamReader(ctx, formBeanType, param.name(), param.shortType(), ParamType.QUERYPARAM); form.writeFormParams(writer); } } } private void writeFormParams(PathSegments segments) { - for (MethodParam param : method.getParams()) { - final String varName = param.getName(); - ParamType paramType = param.getParamType(); + for (MethodParam param : method.params()) { + final String varName = param.name(); + ParamType paramType = param.paramType(); PathSegments.Segment segment = segments.segment(varName); if (segment == null) { // not a path or matrix parameter @@ -206,22 +206,22 @@ private void writeFormParams(PathSegments segments) { private void writeFormParam(MethodParam param, ParamType paramType) { if (paramType == ParamType.FORMPARAM) { if (isMap(param)) { - writer.append(" .formParam(%s)", param.getName()).eol(); + writer.append(" .formParam(%s)", param.name()).eol(); } else { - writer.append(" .formParam(\"%s\", %s)", param.getParamName(), param.getName()).eol(); + writer.append(" .formParam(\"%s\", %s)", param.paramName(), param.name()).eol(); } } else if (paramType == ParamType.FORM) { - TypeElement formBeanType = ctx.getTypeElement(param.getRawType()); - BeanParamReader form = new BeanParamReader(ctx, formBeanType, param.getName(), param.getShortType(), ParamType.FORMPARAM); + TypeElement formBeanType = ctx.typeElement(param.rawType()); + BeanParamReader form = new BeanParamReader(ctx, formBeanType, param.name(), param.shortType(), ParamType.FORMPARAM); form.writeFormParams(writer); } } private void writeBody() { - for (MethodParam param : method.getParams()) { - ParamType paramType = param.getParamType(); + for (MethodParam param : method.params()) { + ParamType paramType = param.paramType(); if (paramType == ParamType.BODY) { - writer.append(" .body(%s)", param.getName()).eol(); + writer.append(" .body(%s)", param.name()).eol(); } } } @@ -244,7 +244,7 @@ private void writePaths(Set segments) { } private boolean isMap(MethodParam param) { - return isMap(param.getUType().mainType()); + return isMap(param.utype().mainType()); } private boolean isMap(String type0) { diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java index 376e7af94..0a8b68605 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java @@ -87,7 +87,7 @@ private void writeForImported(Element importedElement) { private void writeImported(String fullName) { // trim .class suffix String apiClassName = fullName.substring(0, fullName.length() - 6); - TypeElement typeElement = ctx.getTypeElement(apiClassName); + TypeElement typeElement = ctx.typeElement(apiClassName); if (typeElement != null) { writeClient(typeElement); } @@ -101,7 +101,7 @@ private void writeClient(Element controller) { generatedClients.add(writeClientAdapter(ctx, reader)); } catch (Throwable e) { e.printStackTrace(); - ctx.logError(reader.getBeanType(), "Failed to write client class " + e); + ctx.logError(reader.beanType(), "Failed to write client class " + e); } } } diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientWriter.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientWriter.java index 66c2bff02..26dd12a6a 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientWriter.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientWriter.java @@ -36,7 +36,7 @@ protected String initPackageName(String originName) { } private void readMethods() { - for (MethodReader method : reader.getMethods()) { + for (MethodReader method : reader.methods()) { if (method.isWebMethod()) { ClientMethodWriter methodWriter = new ClientMethodWriter(method, writer, ctx); methodWriter.addImportTypes(reader); diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseControllerWriter.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseControllerWriter.java index 844cf5225..28ee7e14c 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseControllerWriter.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseControllerWriter.java @@ -27,7 +27,7 @@ protected BaseControllerWriter(ControllerReader reader, ProcessingContext ctx, S this.reader = reader; this.ctx = ctx; this.router = "$Route".equals(suffix); - TypeElement origin = reader.getBeanType(); + TypeElement origin = reader.beanType(); this.originName = origin.getQualifiedName().toString(); this.shortName = origin.getSimpleName().toString(); this.packageName = initPackageName(originName); @@ -50,7 +50,7 @@ protected void initWriter() throws IOException { } protected Writer createFileWriter() throws IOException { - JavaFileObject jfo = ctx.createWriter(fullName, reader.getBeanType()); + JavaFileObject jfo = ctx.createWriter(fullName, reader.beanType()); return jfo.openWriter(); } @@ -64,11 +64,11 @@ protected void writeImports() { if (router) { writer.append(Constants.IMPORT_PATH_TYPE_CONVERT).eol(); } - for (String type : reader.getStaticImportTypes()) { + for (String type : reader.staticImportTypes()) { writer.append("import static %s;", type).eol(); } writer.eol(); - for (String type : reader.getImportTypes()) { + for (String type : reader.importTypes()) { writer.append("import %s;", type).eol(); } writer.eol(); diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java index dca911161..228cf923a 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java @@ -93,7 +93,7 @@ private void writeControllerAdapter(Element controller) { writeControllerAdapter(ctx, reader); } catch (Throwable e) { e.printStackTrace(); - ctx.logError(reader.getBeanType(), "Failed to write $Route class " + e); + ctx.logError(reader.beanType(), "Failed to write $Route class " + e); } } } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/BeanParamReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/BeanParamReader.java index 8ebbb34f1..d3350b74c 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/BeanParamReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/BeanParamReader.java @@ -42,7 +42,7 @@ private void read() { private void readField(Element enclosedElement) { FieldReader field = new FieldReader(ctx, enclosedElement, defaultParamType); - fieldMap.put(field.getVarName(), field); + fieldMap.put(field.varName(), field); } private void readMethod(ExecutableElement enclosedElement) { @@ -104,13 +104,13 @@ private Set writeConstructorParams(Append writer) { public void writeFormParams(Append writer) { for (FieldReader field : fieldMap.values()) { - ExecutableElement getter = findGetter(field.getVarName()); - ParamType paramType = field.element.getParamType(); + ExecutableElement getter = findGetter(field.varName()); + ParamType paramType = field.element.paramType(); String type = propertyParamType(paramType); if (type != null) { - String accessor = (getter != null) ? getter.toString() : field.isPublic() ? field.getVarName() : null; + String accessor = (getter != null) ? getter.toString() : field.isPublic() ? field.varName() : null; if (accessor != null) { - writer.append(" .%s(\"%s\", %s.%s)", type, field.getParamName(), beanVarName, accessor).eol(); + writer.append(" .%s(\"%s\", %s.%s)", type, field.paramName(), beanVarName, accessor).eol(); } } } @@ -152,15 +152,15 @@ static class FieldReader { } boolean isPublic() { - return element.getElement().getModifiers().contains(Modifier.PUBLIC); + return element.element().getModifiers().contains(Modifier.PUBLIC); } - String getParamName() { - return element.getParamName(); + String paramName() { + return element.paramName(); } - String getVarName() { - return element.getVarName(); + String varName() { + return element.varName(); } @Override @@ -187,7 +187,7 @@ void writeSet(Append writer, String beanVarName) { } else { // populate via field put - writer.append("%s %s.%s = ", ctx.platform().indent(), beanVarName, getVarName()); + writer.append("%s %s.%s = ", ctx.platform().indent(), beanVarName, varName()); element.setValue(writer); writer.append(";").eol(); } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java index faf9914b9..516587209 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java @@ -133,11 +133,11 @@ private boolean initHasValid() { return findAnnotation(Valid.class) != null; } - String getProduces() { + String produces() { return produces; } - public TypeElement getBeanType() { + public TypeElement beanType() { return beanType; } @@ -237,15 +237,15 @@ private void readMethod(ExecutableElement method, DeclaredType declaredType) { } } - public List getRoles() { + public List roles() { return roles; } - public List getMethods() { + public List methods() { return methods; } - public String getPath() { + public String path() { Path path = findAnnotation(Path.class); if (path == null) { return null; @@ -269,11 +269,11 @@ public void addStaticImportType(String rawType) { staticImportTypes.add(rawType); } - public Set getStaticImportTypes() { + public Set staticImportTypes() { return staticImportTypes; } - public Set getImportTypes() { + public Set importTypes() { return importTypes; } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java index 7b8cc0864..09dd97d76 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java @@ -61,7 +61,7 @@ private boolean useValidation() { if (typeHandler != null) { return false; } - TypeElement elementType = ctx.getTypeElement(rawType); + TypeElement elementType = ctx.typeElement(rawType); return elementType != null && elementType.getAnnotation(Valid.class) != null; } @@ -133,7 +133,7 @@ private String nameFrom(String name, String defaultName) { return defaultName; } - public String getVarName() { + public String varName() { return varName; } @@ -149,7 +149,7 @@ private String platformVariable() { return ctx.platform().platformVariable(rawType); } - private String shortType() { + private String handlerShortType() { if (typeHandler != null) { return typeHandler.shortName(); } else { @@ -159,7 +159,7 @@ private String shortType() { void addImports(ControllerReader bean) { if (typeHandler != null) { - String importType = typeHandler.getImportType(); + String importType = typeHandler.importType(); if (importType != null) { bean.addImportType(rawType); } @@ -205,7 +205,7 @@ void writeCtxGet(Append writer, PathSegments segments) { // body passed as method parameter (Helidon) return; } - String shortType = shortType(); + String shortType = handlerShortType(); writer.append("%s var %s = ", ctx.platform().indent(), varName); if (setValue(writer, segments, shortType)) { writer.append(";").eol(); @@ -213,7 +213,7 @@ void writeCtxGet(Append writer, PathSegments segments) { } void setValue(Append writer) { - setValue(writer, PathSegments.EMPTY, shortType()); + setValue(writer, PathSegments.EMPTY, handlerShortType()); } private boolean setValue(Append writer, PathSegments segments, String shortType) { @@ -284,32 +284,32 @@ private boolean setValue(Append writer, PathSegments segments, String shortType) } private void writeForm(Append writer, String shortType, String varName, ParamType defaultParamType) { - TypeElement formBeanType = ctx.getTypeElement(rawType); + TypeElement formBeanType = ctx.typeElement(rawType); BeanParamReader form = new BeanParamReader(ctx, formBeanType, varName, shortType, defaultParamType); form.write(writer); } - public ParamType getParamType() { + public ParamType paramType() { return paramType; } - public String getParamName() { + public String paramName() { return paramName; } - public String getShortType() { + public String shortType() { return shortType; } - public String getRawType() { + public String rawType() { return rawType; } - public UType getType() { + public UType type() { return type; } - public Element getElement() { + public Element element() { return element; } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java index 598879747..78365b3f2 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java @@ -7,21 +7,20 @@ public class JsonBUtil { private JsonBUtil() {} - public static Map getJsonTypes(ControllerReader reader) { + public static Map jsonTypes(ControllerReader reader) { final Map jsonTypes = new LinkedHashMap<>(); - final Consumer addToMap = uType -> jsonTypes.put(uType.full(), uType); - reader.getMethods().stream() + reader.methods().stream() .filter(MethodReader::isWebMethod) - .filter(m -> !"byte[]".equals(m.getReturnType().toString())) - .filter(m -> m.getProduces() == null || m.getProduces().toLowerCase().contains("json")) + .filter(m -> !"byte[]".equals(m.returnType().toString())) + .filter(m -> m.produces() == null || m.produces().toLowerCase().contains("json")) .forEach( methodReader -> { addJsonBodyType(methodReader, addToMap); if (!methodReader.isVoid()) { - addToMap.accept(UType.parse(methodReader.getReturnType())); + addToMap.accept(UType.parse(methodReader.returnType())); } }); @@ -29,10 +28,10 @@ public static Map getJsonTypes(ControllerReader reader) { } private static void addJsonBodyType(MethodReader methodReader, Consumer addToMap) { - if (methodReader.getBodyType() != null) { - methodReader.getParams().stream() + if (methodReader.bodyType() != null) { + methodReader.params().stream() .filter(MethodParam::isBody) - .map(MethodParam::getUType) + .map(MethodParam::utype) .forEach(addToMap); } } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodParam.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodParam.java index dc39d0d7c..3439dec0b 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodParam.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodParam.java @@ -33,35 +33,35 @@ public void buildApiDocumentation(MethodDocBuilder methodDoc) { } public boolean isBody() { - return elementParam.getParamType() == ParamType.BODY; + return elementParam.paramType() == ParamType.BODY; } public boolean isForm() { - return elementParam.getParamType() == ParamType.FORM; + return elementParam.paramType() == ParamType.FORM; } - public String getShortType() { - return elementParam.getShortType(); + public String shortType() { + return elementParam.shortType(); } - public String getRawType() { - return elementParam.getRawType(); + public String rawType() { + return elementParam.rawType(); } - public String getName() { - return elementParam.getVarName(); + public String name() { + return elementParam.varName(); } - public String getParamName() { - return elementParam.getParamName(); + public String paramName() { + return elementParam.paramName(); } - public ParamType getParamType() { - return elementParam.getParamType(); + public ParamType paramType() { + return elementParam.paramType(); } - public UType getUType() { - return elementParam.getType(); + public UType utype() { + return elementParam.type(); } public void setResponseHandler() { diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java index 1dc024e14..bfd0addae 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java @@ -65,7 +65,7 @@ public class MethodReader { initWebMethodViaAnnotation(); if (isWebMethod()) { this.hasValid = findAnnotation(Valid.class) != null; - this.pathSegments = PathSegments.parse(Util.combinePath(bean.getPath(), webMethodPath)); + this.pathSegments = PathSegments.parse(Util.combinePath(bean.path(), webMethodPath)); } else { this.hasValid = false; this.pathSegments = null; @@ -113,13 +113,13 @@ private void initSetWebMethod(WebMethod webMethod, String value) { this.webMethodPath = value; } - public Javadoc getJavadoc() { + public Javadoc javadoc() { return javadoc; } private String produces(ControllerReader bean) { final Produces produces = findAnnotation(Produces.class); - return (produces != null) ? produces.value() : bean.getProduces(); + return (produces != null) ? produces.value() : bean.produces(); } public A findAnnotation(Class type) { @@ -145,7 +145,7 @@ private List addTagsToList(Element element, List list) { return list; } - public List getTags() { + public List tags() { List tags = new ArrayList<>(); tags = addTagsToList(element, tags); return addTagsToList(element.getEnclosingElement(), tags); @@ -189,22 +189,22 @@ public void buildApiDocumentation(ProcessingContext ctx) { } public List roles() { - return methodRoles.isEmpty() ? bean.getRoles() : methodRoles; + return methodRoles.isEmpty() ? bean.roles() : methodRoles; } public boolean isWebMethod() { return webMethod != null; } - public WebMethod getWebMethod() { + public WebMethod webMethod() { return webMethod; } - public String getWebMethodPath() { + public String webMethodPath() { return webMethodPath; } - public List getParams() { + public List params() { return params; } @@ -212,26 +212,26 @@ public boolean isVoid() { return isVoid; } - public String getProduces() { + public String produces() { return produces; } - public TypeMirror getReturnType() { + public TypeMirror returnType() { if (actualExecutable != null) { return actualExecutable.getReturnType(); } return element.getReturnType(); } - public String getStatusCode() { + public String statusCode() { return Integer.toString(webMethod.statusCode(isVoid)); } - public PathSegments getPathSegments() { + public PathSegments pathSegments() { return pathSegments; } - public String getFullPath() { + public String fullPath() { return pathSegments.fullPath(); } @@ -256,19 +256,19 @@ public boolean isFormBody() { return false; } - public String getBodyType() { + public String bodyType() { for (MethodParam param : params) { if (param.isBody()) { - return param.getShortType(); + return param.shortType(); } } return null; } - public String getBodyName() { + public String bodyName() { for (MethodParam param : params) { if (param.isBody()) { - return param.getName(); + return param.name(); } } return "body"; diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ParamType.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ParamType.java index 724c5afe9..312da14e7 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ParamType.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ParamType.java @@ -21,7 +21,7 @@ public enum ParamType { this.type = type; } - public String getType() { + public String type() { return type; } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/PathSegments.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/PathSegments.java index 2f84a23eb..6145fcd69 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/PathSegments.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/PathSegments.java @@ -95,7 +95,7 @@ public List matrixSegments() { /** * Return all segments including literal segments. */ - public Set getSegments() { + public Set segments() { return segments; } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java index f00175337..9ae147c9c 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java @@ -38,10 +38,10 @@ public ProcessingContext(ProcessingEnvironment env, PlatformAdapter readAdapter) } private boolean isTypeAvailable(String canonicalName) { - return null != getTypeElement(canonicalName); + return null != typeElement(canonicalName); } - public TypeElement getTypeElement(String canonicalName) { + public TypeElement typeElement(String canonicalName) { return elements.getTypeElement(canonicalName); } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/TypeHandler.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/TypeHandler.java index b85e9aca8..a6c6a0878 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/TypeHandler.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/TypeHandler.java @@ -18,7 +18,7 @@ interface TypeHandler { /** * The type for adding to imports. */ - String getImportType(); + String importType(); /** * The short name. diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/TypeMap.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/TypeMap.java index 686d590e7..6c3c97a6a 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/TypeMap.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/TypeMap.java @@ -13,7 +13,7 @@ class TypeMap { private static final Map types = new HashMap<>(); private static void add(TypeHandler h) { - types.put(h.getImportType(), h); + types.put(h.importType(), h); } static { @@ -188,7 +188,7 @@ public String shortName() { } @Override - public String getImportType() { + public String importType() { return null; } } @@ -230,7 +230,7 @@ public String toMethod() { } @Override - public String getImportType() { + public String importType() { return null; } } @@ -298,7 +298,7 @@ public boolean isPrimitive() { } @Override - public String getImportType() { + public String importType() { return importType; } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/MethodDocBuilder.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/MethodDocBuilder.java index 340b5c86b..3d4d3139f 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/MethodDocBuilder.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/MethodDocBuilder.java @@ -24,7 +24,7 @@ public class MethodDocBuilder { public MethodDocBuilder(MethodReader methodReader, DocContext ctx) { this.methodReader = methodReader; this.ctx = ctx; - this.javadoc = methodReader.getJavadoc(); + this.javadoc = methodReader.javadoc(); } public void build() { @@ -36,7 +36,7 @@ public void build() { //operation.setOperationId(); operation.setSummary(javadoc.getSummary()); operation.setDescription(javadoc.getDescription()); - operation.setTags(methodReader.getTags()); + operation.setTags(methodReader.tags()); if (javadoc.isDeprecated()) { operation.setDeprecated(true); @@ -44,8 +44,8 @@ public void build() { operation.setDeprecated(true); } - PathItem pathItem = ctx.pathItem(methodReader.getFullPath()); - switch (methodReader.getWebMethod()) { + PathItem pathItem = ctx.pathItem(methodReader.fullPath()); + switch (methodReader.webMethod()) { case GET: pathItem.setGet(operation); break; @@ -63,7 +63,7 @@ public void build() { break; } - for (MethodParam param : methodReader.getParams()) { + for (MethodParam param : methodReader.params()) { param.buildApiDocumentation(this); } @@ -78,11 +78,11 @@ public void build() { response.setDescription("No content"); } } else { - final String produces = methodReader.getProduces(); + final String produces = methodReader.produces(); String contentMediaType = (produces == null) ? MediaType.APPLICATION_JSON : produces; - response.setContent(ctx.createContent(methodReader.getReturnType(), contentMediaType)); + response.setContent(ctx.createContent(methodReader.returnType(), contentMediaType)); } - responses.addApiResponse(methodReader.getStatusCode(), response); + responses.addApiResponse(methodReader.statusCode(), response); } DocContext getContext() { diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/MethodParamDocBuilder.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/MethodParamDocBuilder.java index 57badb969..7352c9a1d 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/MethodParamDocBuilder.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/MethodParamDocBuilder.java @@ -29,11 +29,11 @@ public MethodParamDocBuilder(MethodDocBuilder methodDoc, ElementReader param) { this.javadoc = methodDoc.getJavadoc(); this.operation = methodDoc.getOperation(); - this.paramType = param.getParamType(); - this.paramName = param.getParamName(); - this.varName = param.getVarName(); - this.rawType = param.getRawType(); - this.element = param.getElement(); + this.paramType = param.paramType(); + this.paramName = param.paramName(); + this.varName = param.varName(); + this.rawType = param.rawType(); + this.element = param.element(); } /** @@ -55,7 +55,7 @@ public void build() { } else { param.setSchema(schema); - param.setIn(paramType.getType()); + param.setIn(paramType.type()); operation.addParametersItem(param); } } diff --git a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/ControllerMethodWriter.java b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/ControllerMethodWriter.java index 434bfa497..e2df2842e 100644 --- a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/ControllerMethodWriter.java +++ b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/ControllerMethodWriter.java @@ -23,13 +23,13 @@ class ControllerMethodWriter { ControllerMethodWriter(MethodReader method, Append writer, ProcessingContext ctx) { this.method = method; this.writer = writer; - this.webMethod = method.getWebMethod(); + this.webMethod = method.webMethod(); this.ctx = ctx; } void writeRule() { - final String fullPath = method.getFullPath(); - final String bodyType = method.getBodyType(); + final String fullPath = method.fullPath(); + final String bodyType = method.bodyType(); if (bodyType != null) { writer.append(" rules.%s(\"%s\", Handler.create(%s.class, this::_%s));", webMethod.name().toLowerCase(), fullPath, bodyType, method.simpleName()).eol(); } else if (method.isFormBody()) { @@ -41,9 +41,9 @@ void writeRule() { void writeHandler(boolean requestScoped) { writer.append(" private void _%s(ServerRequest req, ServerResponse res", method.simpleName()); - final String bodyType = method.getBodyType(); + final String bodyType = method.bodyType(); if (bodyType != null) { - writer.append(", %s %s", bodyType, method.getBodyName()); + writer.append(", %s %s", bodyType, method.bodyName()); } else if (method.isFormBody()) { writer.append(", %s %s", "FormParams", "formParams"); } @@ -52,13 +52,13 @@ void writeHandler(boolean requestScoped) { writeContextReturn(); } - final PathSegments segments = method.getPathSegments(); + final PathSegments segments = method.pathSegments(); List matrixSegments = segments.matrixSegments(); for (PathSegments.Segment matrixSegment : matrixSegments) { matrixSegment.writeCreateSegment(writer, ctx.platform()); } - final List params = method.getParams(); + final List params = method.params(); for (MethodParam param : params) { param.writeCtxGet(writer, segments); } @@ -93,7 +93,7 @@ void writeHandler(boolean requestScoped) { } private void writeContextReturn() { - final String produces = method.getProduces(); + final String produces = method.produces(); if (produces == null) { // let it be automatically set } else if (MediaType.APPLICATION_JSON.equalsIgnoreCase(produces)) { diff --git a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/ControllerWriter.java b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/ControllerWriter.java index 98b19a240..b54b70b56 100644 --- a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/ControllerWriter.java +++ b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/ControllerWriter.java @@ -32,7 +32,7 @@ void write() { } private List getWriterMethods() { - return reader.getMethods().stream() + return reader.methods().stream() .filter(MethodReader::isWebMethod) .map(it -> new ControllerMethodWriter(it, writer, ctx)) .collect(Collectors.toList()); diff --git a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/HelidonPlatformAdapter.java b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/HelidonPlatformAdapter.java index 3287d5149..0648478c5 100644 --- a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/HelidonPlatformAdapter.java +++ b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/HelidonPlatformAdapter.java @@ -84,7 +84,7 @@ public void writeReadParameter(Append writer, ParamType paramType, String paramN case BEANPARAM: case FORM: default: - writer.append("null // TODO req.%s().param(\"%s\")", paramType.getType(), paramName); + writer.append("null // TODO req.%s().param(\"%s\")", paramType.type(), paramName); } } @@ -110,7 +110,7 @@ public void writeReadParameter(Append writer, ParamType paramType, String paramN case BEANPARAM: case FORM: default: - writer.append("null // TODO req.%s().param(\"%s\")", paramType.getType(), paramName); + writer.append("null // TODO req.%s().param(\"%s\")", paramType.type(), paramName); } } } diff --git a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java index 19dd3791a..8be565419 100644 --- a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java +++ b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java @@ -17,25 +17,25 @@ class ControllerMethodWriter { ControllerMethodWriter(MethodReader method, Append writer, ProcessingContext ctx, boolean useJsonB) { this.method = method; this.writer = writer; - this.webMethod = method.getWebMethod(); + this.webMethod = method.webMethod(); this.ctx = ctx; this.useJsonB = useJsonB; } void write(boolean requestScoped) { - final var segments = method.getPathSegments(); + final var segments = method.pathSegments(); final var fullPath = segments.fullPath(); writer.append(" ApiBuilder.%s(\"%s\", ctx -> {", webMethod.name().toLowerCase(), fullPath).eol(); - writer.append(" ctx.status(%s);", method.getStatusCode()).eol(); + writer.append(" ctx.status(%s);", method.statusCode()).eol(); final var matrixSegments = segments.matrixSegments(); for (final PathSegments.Segment matrixSegment : matrixSegments) { matrixSegment.writeCreateSegment(writer, ctx.platform()); } - final var params = method.getParams(); + final var params = method.params(); for (final MethodParam param : params) { param.writeCtxGet(writer, segments); } @@ -85,10 +85,10 @@ void write(boolean requestScoped) { } private void writeContextReturn() { - final var produces = method.getProduces(); + final var produces = method.produces(); if (produces == null || MediaType.APPLICATION_JSON.equalsIgnoreCase(produces)) { if (useJsonB) { - final var uType = UType.parse(method.getReturnType()); + final var uType = UType.parse(method.returnType()); writer.append(" %sJsonType.toJson(result, ctx.contentType(\"application/json\").outputStream());", uType.shortName()); } else { writer.append(" ctx.json(result);"); diff --git a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java index 59de8005a..7f19e1ccc 100644 --- a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java +++ b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java @@ -21,7 +21,7 @@ class ControllerWriter extends BaseControllerWriter { if (useJsonB) { reader.addImportType("io.avaje.jsonb.Jsonb"); reader.addImportType("io.avaje.jsonb.JsonType"); - this.jsonTypes = JsonBUtil.getJsonTypes(reader); + this.jsonTypes = JsonBUtil.jsonTypes(reader); } else { this.jsonTypes = Map.of(); } @@ -39,7 +39,7 @@ void write() { private void writeAddRoutes() { writer.append(" @Override").eol(); writer.append(" public void registerRoutes() {").eol().eol(); - for (final MethodReader method : reader.getMethods()) { + for (final MethodReader method : reader.methods()) { if (method.isWebMethod()) { writeForMethod(method); } diff --git a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java index 5f62f574e..6c49eef25 100644 --- a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java +++ b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java @@ -24,24 +24,24 @@ class ControllerMethodWriter { ControllerMethodWriter(MethodReader method, Append writer, ProcessingContext ctx) { this.method = method; this.writer = writer; - this.webMethod = method.getWebMethod(); + this.webMethod = method.webMethod(); this.ctx = ctx; } void write(boolean requestScoped) { - final PathSegments segments = method.getPathSegments(); + final PathSegments segments = method.pathSegments(); final String fullPath = segments.fullPath(); writer.append(" routing.%s(\"%s\", ctx -> {", webMethod.name().toLowerCase(), fullPath).eol(); - writer.append(" ctx.status(%s);", method.getStatusCode()).eol(); + writer.append(" ctx.status(%s);", method.statusCode()).eol(); List matrixSegments = segments.matrixSegments(); for (PathSegments.Segment matrixSegment : matrixSegments) { matrixSegment.writeCreateSegment(writer, ctx.platform()); } - final List params = method.getParams(); + final List params = method.params(); for (MethodParam param : params) { param.writeCtxGet(writer, segments); } @@ -88,7 +88,7 @@ void write(boolean requestScoped) { } private void writeContextReturn() { - final String produces = method.getProduces(); + final String produces = method.produces(); if (produces == null || produces.equalsIgnoreCase(MediaType.APPLICATION_JSON)) { writer.append("ctx.json("); } else if (produces.equalsIgnoreCase(MediaType.TEXT_HTML)) { diff --git a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerWriter.java b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerWriter.java index 17df515d4..cd5fc108d 100644 --- a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerWriter.java +++ b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerWriter.java @@ -30,7 +30,7 @@ void write() { private void writeAddRoutes() { writer.append(" @Override").eol(); writer.append(" public void add(Routing routing) {").eol().eol(); - for (MethodReader method : reader.getMethods()) { + for (MethodReader method : reader.methods()) { if (method.isWebMethod()) { writeForMethod(method); } diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java index 628afa7c0..668837ffc 100644 --- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java +++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java @@ -27,39 +27,39 @@ class ControllerMethodWriter { ControllerMethodWriter(MethodReader method, Append writer, ProcessingContext ctx, boolean useJsonB) { this.method = method; this.writer = writer; - this.webMethod = method.getWebMethod(); + this.webMethod = method.webMethod(); this.ctx = ctx; this.useJsonB = useJsonB; } void writeRule() { writer.append(" rules.%s(\"%s\", this::_%s);", - webMethod.name().toLowerCase(), method.getFullPath(), method.simpleName()) + webMethod.name().toLowerCase(), method.fullPath(), method.simpleName()) .eol(); } void writeHandler(boolean requestScoped) { writer.append(" private void _%s(ServerRequest req, ServerResponse res) {", method.simpleName()).eol(); - final var bodyType = method.getBodyType(); + final var bodyType = method.bodyType(); if (bodyType != null) { if (useJsonB) { final var fieldName = - method.getParams().stream() + method.params().stream() .filter(MethodParam::isBody) .findFirst() .orElseThrow() - .getUType() + .utype() .shortName(); - writer.append(" var %s = %sJsonType.fromJson(req.content().inputStream());", method.getBodyName(), fieldName).eol(); + writer.append(" var %s = %sJsonType.fromJson(req.content().inputStream());", method.bodyName(), fieldName).eol(); } else { // use default helidon content negotiation - method.getParams().stream() + method.params().stream() .filter(MethodParam::isBody) .forEach( param -> { - final var type = param.getUType(); - writer.append(" var %s = req.content().as(", method.getBodyName()); + final var type = param.utype(); + writer.append(" var %s = req.content().as(", method.bodyName()); if (type.param0() != null) { writer.append("new io.helidon.common.GenericType<%s>() {}", type.full()); } else { @@ -72,7 +72,7 @@ void writeHandler(boolean requestScoped) { writer.append(" var formParams = req.content().as(Parameters.class);").eol(); } - final var segments = method.getPathSegments(); + final var segments = method.pathSegments(); if (!segments.isEmpty()) { writer.append(" var pathParams = req.path().pathParameters();").eol(); } @@ -81,7 +81,7 @@ void writeHandler(boolean requestScoped) { matrixSegment.writeCreateSegment(writer, ctx.platform()); } - final var params = method.getParams(); + final var params = method.params(); for (final MethodParam param : params) { param.writeCtxGet(writer, segments); } @@ -113,7 +113,7 @@ void writeHandler(boolean requestScoped) { if (!method.isVoid()) { writeContextReturn(); if (producesJson()) { - final UType uType = UType.parse(method.getReturnType()); + final UType uType = UType.parse(method.returnType()); writer.append(" %sJsonType.toJson(result, res.outputStream());", uType.shortName()).eol(); } else { writer.append(" res.send(result);").eol(); @@ -124,20 +124,20 @@ void writeHandler(boolean requestScoped) { private boolean producesJson() { return useJsonB - && !"byte[]".equals(method.getReturnType().toString()) - && (method.getProduces() == null || method.getProduces().toLowerCase().contains("json")); + && !"byte[]".equals(method.returnType().toString()) + && (method.produces() == null || method.produces().toLowerCase().contains("json")); } private boolean missingServerResponse(List params) { - return method.isVoid() && params.stream().noneMatch(p -> "ServerResponse".equals(p.getShortType())); + return method.isVoid() && params.stream().noneMatch(p -> "ServerResponse".equals(p.shortType())); } private boolean usesFormParams() { - return method.getParams().stream().anyMatch(p -> p.isForm() || ParamType.FORMPARAM.equals(p.getParamType())); + return method.params().stream().anyMatch(p -> p.isForm() || ParamType.FORMPARAM.equals(p.paramType())); } private void writeContextReturn() { - final var producesOp = Optional.ofNullable(method.getProduces()); + final var producesOp = Optional.ofNullable(method.produces()); if (producesOp.isEmpty() && !useJsonB) { return; } diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java index c50153082..1d78d70ab 100644 --- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java +++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java @@ -21,7 +21,7 @@ class ControllerWriter extends BaseControllerWriter { if (useJsonB) { reader.addImportType("io.avaje.jsonb.Jsonb"); reader.addImportType("io.avaje.jsonb.JsonType"); - this.jsonTypes = JsonBUtil.getJsonTypes(reader); + this.jsonTypes = JsonBUtil.jsonTypes(reader); } else { this.jsonTypes = Map.of(); } @@ -43,7 +43,7 @@ void write() { } private List writerMethods() { - return reader.getMethods().stream() + return reader.methods().stream() .filter(MethodReader::isWebMethod) .map(it -> new ControllerMethodWriter(it, writer, ctx, useJsonB)) .toList(); diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/NimaPlatformAdapter.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/NimaPlatformAdapter.java index 990e95f63..101d07cda 100644 --- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/NimaPlatformAdapter.java +++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/NimaPlatformAdapter.java @@ -78,7 +78,7 @@ public void writeReadParameter(Append writer, ParamType paramType, String paramN break; case BODY, BEANPARAM, FORM: default: - writer.append("null // TODO req.%s().param(\"%s\")", paramType.getType(), paramName); + writer.append("null // TODO req.%s().param(\"%s\")", paramType.type(), paramName); } } @@ -104,7 +104,7 @@ public void writeReadParameter(Append writer, ParamType paramType, String paramN case BEANPARAM: case FORM: default: - writer.append("null // TODO req.%s().param(\"%s\")", paramType.getType(), paramName); + writer.append("null // TODO req.%s().param(\"%s\")", paramType.type(), paramName); } } } From 676efbcf9920ac311f9eee07768db7188b364dba Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Fri, 21 Oct 2022 10:09:37 -0500 Subject: [PATCH 0394/1323] add startup step/jsonB --- README.md | 142 +++++++++++++++++++++++++++++++----------------------- 1 file changed, 83 insertions(+), 59 deletions(-) diff --git a/README.md b/README.md index 27791c35d..c13cc5321 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ Http server and client libraries and code generation. -## http server +## Http Server A jax-rs style controllers with annotations (`@Path`, `@Get` ...) that is lightweight by using source code generation (annotation processors) @@ -11,8 +11,39 @@ to generate adapter code for Javalin and Helidon SE/Nima. - Lightweight as in 65Kb library + generated source code - Full use of Javalin or Helidon SE/Nima as desired +## Add dependencies -## Define a Controller (Note that these APT processors works with both Java and Kotlin.) +```xml + + io.avaje + avaje-http-api + ${avaje.http.version} + +``` +Add the generator module for your desired microframework as a annotation processor. + +```xml + + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler-plugin.version} + + + + io.avaje + avaje-http-javalin-generator + ${avaje.http.version} + + + + + + +``` + +## Define a Controller (These APT processors work with both Java and Kotlin.) ```java package org.example.hello; @@ -41,7 +72,6 @@ public class WidgetController { record Widget(int id, String name){}; } - ``` ## Usage with Javalin @@ -95,59 +125,39 @@ WebServer.builder() ### (Javalin) The generated WidgetController$Route.java is: ```java -package org.example.hello; - -import static io.avaje.http.api.PathTypeConversion.*; -import io.avaje.http.api.WebRoutes; -import io.javalin.apibuilder.ApiBuilder; -import javax.annotation.Generated; -import javax.inject.Singleton; -import org.example.hello.WidgetController; - -@Generated("io.avaje.javalin-generator") -@Singleton +@Generated("avaje-javalin-generator") +@Component public class WidgetController$Route implements WebRoutes { - private final WidgetController controller; + private final WidgetController controller; - public WidgetController$route(WidgetController controller) { - this.controller = controller; - } + public WidgetController$Route(WidgetController controller) { + this.controller = controller; + } @Override public void registerRoutes() { ApiBuilder.get("/widgets/{id}", ctx -> { - int id = asInt(ctx.pathParam("id")); - ctx.json(controller.getById(id)); ctx.status(200); + var id = asInt(ctx.pathParam("id")); + var result = controller.getById(id); + ctx.json(result); }); ApiBuilder.get("/widgets", ctx -> { - ctx.json(controller.getAll()); ctx.status(200); + var result = controller.getAll(); + ctx.json(result); }); } + } ``` ### (Helidon SE) The generated WidgetController$Route.java is: ```java -package org.example.hello; - -import static io.avaje.http.api.PathTypeConversion.*; - -import io.avaje.http.api.*; -import io.helidon.common.http.FormParams; -import io.helidon.webserver.Handler; -import io.helidon.webserver.Routing; -import io.helidon.webserver.ServerRequest; -import io.helidon.webserver.ServerResponse; -import io.helidon.webserver.Service; -import jakarta.inject.Singleton; -import org.example.hello.WidgetController; - @Generated("io.dinject.helidon-generator") @Singleton public class WidgetController$Route implements Service { @@ -180,19 +190,6 @@ public class WidgetController$Route implements Service { ### (Helidon Nima) The generated WidgetController$Route.java is: ```java -package org.example.hello; - -import static io.avaje.http.api.PathTypeConversion.*; - -import io.avaje.http.api.*; -import io.avaje.inject.Component; -import io.helidon.nima.webserver.http.HttpRouting; -import io.helidon.nima.webserver.http.HttpRules; -import io.helidon.nima.webserver.http.HttpService; -import io.helidon.nima.webserver.http.ServerRequest; -import io.helidon.nima.webserver.http.ServerResponse; -import org.example.hello.WidgetController; - @Generated("avaje-helidon-nima-generator") @Component public class WidgetController$Route implements HttpService { @@ -224,22 +221,49 @@ public class WidgetController$Route implements HttpService { } ``` -### (Helidon Nima with Avaje-Jsonb) The generated WidgetController$Route.java is: +## Generated sources ([Avaje-Jsonb](https://github.com/avaje/avaje-jsonb)) +If [Avaje-Jsonb](https://github.com/avaje/avaje-jsonb) is detected, http generators with support will use it for faster Json message processing. +### (Javalin) The generated WidgetController$Route.java is: ```java -package org.example.hello; +@Generated("avaje-javalin-generator") +@Component +public class WidgetController$Route implements WebRoutes { -import static io.avaje.http.api.PathTypeConversion.*; + private final WidgetController controller; + private final JsonType> listWidgetJsonType; + private final JsonType widgetJsonType; + + public WidgetController$Route(WidgetController controller, Jsonb jsonB) { + this.controller = controller; + this.listWidgetJsonType = jsonB.type(org.example.hello.WidgetController.Widget.class).list(); + this.widgetJsonType = jsonB.type(org.example.hello.WidgetController.Widget.class); + } + + @Override + public void registerRoutes() { + + ApiBuilder.get("/widgets/{id}", ctx -> { + ctx.status(200); + var id = asInt(ctx.pathParam("id")); + var result = controller.getById(id); + widgetJsonType.toJson(result, ctx.contentType("application/json").outputStream()); + }); -import io.avaje.http.api.*; -import io.avaje.inject.Component; -import io.helidon.nima.webserver.http.HttpRouting; -import io.helidon.nima.webserver.http.HttpRules; -import io.helidon.nima.webserver.http.HttpService; -import io.helidon.nima.webserver.http.ServerRequest; -import io.helidon.nima.webserver.http.ServerResponse; -import org.example.hello.WidgetController; + ApiBuilder.get("/widgets", ctx -> { + ctx.status(200); + var result = controller.getAll(); + listWidgetJsonType.toJson(result, ctx.contentType("application/json").outputStream()); + }); + + } +} +``` + +### (Helidon Nima) The generated WidgetController$Route.java is: + +```java @Generated("avaje-helidon-nima-generator") @Component public class WidgetController$Route implements HttpService { From 5129caa0df48e2c070935da03f4193c935a80e60 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Tue, 25 Oct 2022 21:45:45 -0400 Subject: [PATCH 0395/1323] add retry exception handler --- .../client/DHttpClientRequestWithRetry.java | 32 +++++++++++++++---- .../io/avaje/http/client/RetryHandler.java | 12 ++++++- 2 files changed, 37 insertions(+), 7 deletions(-) diff --git a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequestWithRetry.java b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequestWithRetry.java index 6d5d26606..eb7cdbfde 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequestWithRetry.java +++ b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequestWithRetry.java @@ -22,14 +22,34 @@ final class DHttpClientRequestWithRetry extends DHttpClientRequest { @Override protected HttpResponse performSend(HttpResponse.BodyHandler responseHandler) { HttpResponse res; - res = super.performSend(responseHandler); - if (res.statusCode() < 300) { - return res; - } - while (retryHandler.isRetry(retryCount++, res)) { - res = super.performSend(responseHandler); + HttpException ex; + + do { + try { + res = super.performSend(responseHandler); + ex = null; + } catch (final HttpException e) { + ex = e; + res = null; + } + if (res != null && res.statusCode() < 300) { + return res; + } + retryCount++; + } while (retry(res, ex)); + + if (res == null && ex != null) { + throw ex; } + return res; } + protected boolean retry(HttpResponse res, HttpException ex) { + + if (res != null) { + return retryHandler.isRetry(retryCount, res); + } + return retryHandler.isExceptionRetry(retryCount, ex); + } } diff --git a/http-client/client/src/main/java/io/avaje/http/client/RetryHandler.java b/http-client/client/src/main/java/io/avaje/http/client/RetryHandler.java index 67ed83dd0..e9d16ba5c 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/RetryHandler.java +++ b/http-client/client/src/main/java/io/avaje/http/client/RetryHandler.java @@ -11,9 +11,19 @@ public interface RetryHandler { * Return true if the request should be retried. * * @param retryCount The number of retry attempts already executed - * @param response The HTTP response + * @param response The HTTP response * @return True if the request should be retried or false if not */ boolean isRetry(int retryCount, HttpResponse response); + /** + * Return true if the request should be retried. + * + * @param retryCount The number of retry attempts already executed + * @param exception The Wrapped Error thrown by the underlying Http Client + * @return True if the request should be retried or false if not + */ + default boolean isExceptionRetry(int retryCount, HttpException exception) { + throw exception; + } } From 6773fc1dc74f2e6ae2c159691ca860d50a4c8417 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Wed, 26 Oct 2022 18:50:48 -0400 Subject: [PATCH 0396/1323] now httpclient exception doesn't thro nullpointer on missing body --- .../io/avaje/http/client/HttpException.java | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/http-client/client/src/main/java/io/avaje/http/client/HttpException.java b/http-client/client/src/main/java/io/avaje/http/client/HttpException.java index fe0fbdb39..0c8302017 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/HttpException.java +++ b/http-client/client/src/main/java/io/avaje/http/client/HttpException.java @@ -91,28 +91,37 @@ public HttpException(int statusCode, Throwable cause) { } /** - * Return the response body content as a bean + * Return the response body content as a bean, or else null if body content doesn't exist. * * @param cls The type of bean to convert the response to * @return The response as a bean */ public T bean(Class cls) { + if (httpResponse == null) { + return null; + } final BodyContent body = context.readErrorContent(responseAsBytes, httpResponse); return context.readBean(cls, body); } /** - * Return the response body content as a UTF8 string. + * Return the response body content as a UTF8 string, or else null if body content doesn't exist. */ public String bodyAsString() { + if (httpResponse == null) { + return null; + } final BodyContent body = context.readErrorContent(responseAsBytes, httpResponse); return new String(body.content(), StandardCharsets.UTF_8); } - /** - * Return the response body content as raw bytes. + /** + * Return the response body content as raw bytes, or else null if body content doesn't exist. */ public byte[] bodyAsBytes() { + if (httpResponse == null) { + return null; + } final BodyContent body = context.readErrorContent(responseAsBytes, httpResponse); return body.content(); } From ef5c782a8d1a929a6f7e442b5e39ed211dfc89e5 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Mon, 31 Oct 2022 08:35:25 +1300 Subject: [PATCH 0397/1323] [maven-release-plugin] prepare release avaje-http-client-1.20 --- http-client/client/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/http-client/client/pom.xml b/http-client/client/pom.xml index b29cd98c1..f68464e1b 100644 --- a/http-client/client/pom.xml +++ b/http-client/client/pom.xml @@ -10,11 +10,11 @@ io.avaje avaje-http-client - 1.20-SNAPSHOT + 1.20 scm:git:git@github.com:avaje/avaje-http-client.git - HEAD + avaje-http-client-1.20 From bd8dcbab905e35e13669c44628286e25f4542b6b Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Mon, 31 Oct 2022 08:35:31 +1300 Subject: [PATCH 0398/1323] [maven-release-plugin] prepare for next development iteration --- http-client/client/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/http-client/client/pom.xml b/http-client/client/pom.xml index f68464e1b..bf5c54f9b 100644 --- a/http-client/client/pom.xml +++ b/http-client/client/pom.xml @@ -10,11 +10,11 @@ io.avaje avaje-http-client - 1.20 + 1.21-SNAPSHOT scm:git:git@github.com:avaje/avaje-http-client.git - avaje-http-client-1.20 + HEAD From f296700f399a0b4055cc326e4cccc75a389df830 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Mon, 31 Oct 2022 08:37:57 +1300 Subject: [PATCH 0399/1323] release gson --- http-client/gson-adapter/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/http-client/gson-adapter/pom.xml b/http-client/gson-adapter/pom.xml index 0f7f59109..7e587711b 100644 --- a/http-client/gson-adapter/pom.xml +++ b/http-client/gson-adapter/pom.xml @@ -28,7 +28,7 @@ io.avaje avaje-http-client - 1.20-SNAPSHOT + 1.20 provided From f86dca3ecceb216a1cdb825416925783f9689a61 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Mon, 31 Oct 2022 08:38:28 +1300 Subject: [PATCH 0400/1323] [maven-release-plugin] prepare release avaje-http-client-gson-1.20 --- http-client/gson-adapter/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/http-client/gson-adapter/pom.xml b/http-client/gson-adapter/pom.xml index 7e587711b..ae44d3e8a 100644 --- a/http-client/gson-adapter/pom.xml +++ b/http-client/gson-adapter/pom.xml @@ -10,11 +10,11 @@ io.avaje avaje-http-client-gson - 1.20-SNAPSHOT + 1.20 scm:git:git@github.com:avaje/avaje-http-client.git - HEAD + avaje-http-client-gson-1.20 From 6fcce1b0fd6df046748f1523889b8309a026a2c2 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Mon, 31 Oct 2022 08:38:34 +1300 Subject: [PATCH 0401/1323] [maven-release-plugin] prepare for next development iteration --- http-client/gson-adapter/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/http-client/gson-adapter/pom.xml b/http-client/gson-adapter/pom.xml index ae44d3e8a..87ec415ab 100644 --- a/http-client/gson-adapter/pom.xml +++ b/http-client/gson-adapter/pom.xml @@ -10,11 +10,11 @@ io.avaje avaje-http-client-gson - 1.20 + 1.21-SNAPSHOT scm:git:git@github.com:avaje/avaje-http-client.git - avaje-http-client-gson-1.20 + HEAD From 3b75676df69741eaa737e15290b8cfea56369365 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Mon, 31 Oct 2022 08:41:05 +1300 Subject: [PATCH 0402/1323] Bump SNAPSHOT after release --- http-client/gson-adapter/pom.xml | 2 +- http-client/test/pom.xml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/http-client/gson-adapter/pom.xml b/http-client/gson-adapter/pom.xml index 87ec415ab..b33824e0c 100644 --- a/http-client/gson-adapter/pom.xml +++ b/http-client/gson-adapter/pom.xml @@ -28,7 +28,7 @@ io.avaje avaje-http-client - 1.20 + 1.21-SNAPSHOT provided diff --git a/http-client/test/pom.xml b/http-client/test/pom.xml index fa21a8bcd..3b80a17e7 100644 --- a/http-client/test/pom.xml +++ b/http-client/test/pom.xml @@ -16,13 +16,13 @@ io.avaje avaje-http-client - 1.20-SNAPSHOT + 1.21-SNAPSHOT io.avaje avaje-http-client-gson - 1.20-SNAPSHOT + 1.21-SNAPSHOT From 050e9e098038edea184f3141a3b54850f14ea4b1 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sun, 30 Oct 2022 15:28:25 -0500 Subject: [PATCH 0403/1323] add Retry example to README --- http-client/README.md | 36 ++++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/http-client/README.md b/http-client/README.md index 1b4d6e44a..f87cec7ee 100644 --- a/http-client/README.md +++ b/http-client/README.md @@ -24,7 +24,7 @@ A lightweight wrapper to the [JDK 11+ Java Http Client](http://openjdk.java.net/ io.avaje avaje-http-client - 1.17 + ${avaje.client.version} ``` @@ -63,7 +63,7 @@ From HttpClientContext: ## Limitations: -- NO support for POSTing multipart-form currently +- No support for POSTing multipart-form currently - Retry (when specified) does not apply to `async` response processing` @@ -299,7 +299,39 @@ HttpResponse res = clientContext.request() assertThat(res.statusCode()).isEqualTo(201); ``` +## Retry (Sync Requests Only) +To add Retry funtionality, use `.retryHandler(yourhandler)` on the builder to provide your retry handler. The `RetryHandler` interface provides two methods, one for status exceptions (e.g. you get a 4xx/5xx from the server) and another for exceptions thrown by the underlying client (e.g. server times out or client couldn't send request). Here is example implementation of `RetryHandler`. +``` +public final class ExampleRetry implements RetryHandler { + private static final int MAX_RETRIES = 2; + @Override + public boolean isRetry(int retryCount, HttpResponse response) { + + final var code = response.statusCode(); + + if (retryCount >= MAX_RETRIES || code >= 400) { + + return false; + } + + return true; + } + + @Override + public boolean isExceptionRetry(int retryCount, HttpException response) { + //unwrap the exception + final var cause = response.getCause(); + if (retryCount >= MAX_RETRIES) { + return false; + } + if (cause instanceof ConnectException) { + return true; + } + + return false; + } +``` ## Async processing From 844ad4b47e000b361c01dad88af05c8ca3df9610 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 1 Nov 2022 08:35:51 +1300 Subject: [PATCH 0404/1323] [maven-release-plugin] prepare release avaje-http-generator-parent-1.19 --- http-api/pom.xml | 4 ++-- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 4 ++-- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-generator-nima/pom.xml | 2 +- pom.xml | 4 ++-- 8 files changed, 11 insertions(+), 11 deletions(-) diff --git a/http-api/pom.xml b/http-api/pom.xml index b13bc1242..d54eb4d52 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-generator-parent - 1.19-SNAPSHOT + 1.19 .. @@ -12,7 +12,7 @@ scm:git:git@github.com:avaje/avaje-http.git - HEAD + avaje-http-generator-parent-1.19 diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index 6bad232f4..3e7e681d1 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -5,7 +5,7 @@ io.avaje avaje-http-generator-parent - 1.19-SNAPSHOT + 1.19 .. diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 92a6f1062..3e6682b82 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-generator-parent - 1.19-SNAPSHOT + 1.19 .. @@ -33,7 +33,7 @@ io.avaje avaje-http-api - 1.19-SNAPSHOT + 1.19 diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index 818d866b1..e5bcc7af1 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-generator-parent - 1.19-SNAPSHOT + 1.19 .. diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index 8c4eb3d4e..3943fdc1d 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-generator-parent - 1.19-SNAPSHOT + 1.19 .. diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index bde2581b2..58053ea3a 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-generator-parent - 1.19-SNAPSHOT + 1.19 .. diff --git a/http-generator-nima/pom.xml b/http-generator-nima/pom.xml index 1a0a692f4..e2ec9b711 100644 --- a/http-generator-nima/pom.xml +++ b/http-generator-nima/pom.xml @@ -3,7 +3,7 @@ avaje-http-generator-parent io.avaje - 1.19-SNAPSHOT + 1.19 4.0.0 diff --git a/pom.xml b/pom.xml index 3fb84b90b..e7b578311 100644 --- a/pom.xml +++ b/pom.xml @@ -9,12 +9,12 @@ io.avaje avaje-http-generator-parent - 1.19-SNAPSHOT + 1.19 pom scm:git:git@github.com:avaje/avaje-http.git - HEAD + avaje-http-generator-parent-1.19 From 31460a99836682a8fb88b982b46b8ea43822bb1a Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 1 Nov 2022 08:37:18 +1300 Subject: [PATCH 0405/1323] [maven-release-plugin] prepare for next development iteration --- http-api/pom.xml | 2 +- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 4 ++-- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-generator-nima/pom.xml | 2 +- pom.xml | 2 +- 8 files changed, 9 insertions(+), 9 deletions(-) diff --git a/http-api/pom.xml b/http-api/pom.xml index d54eb4d52..15293cdc9 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-generator-parent - 1.19 + 1.20-SNAPSHOT .. diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index 3e7e681d1..cc0df7831 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -5,7 +5,7 @@ io.avaje avaje-http-generator-parent - 1.19 + 1.20-SNAPSHOT .. diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 3e6682b82..e3e9236d7 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-generator-parent - 1.19 + 1.20-SNAPSHOT .. @@ -33,7 +33,7 @@ io.avaje avaje-http-api - 1.19 + 1.20-SNAPSHOT diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index e5bcc7af1..551486e79 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-generator-parent - 1.19 + 1.20-SNAPSHOT .. diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index 3943fdc1d..dcc9a1220 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-generator-parent - 1.19 + 1.20-SNAPSHOT .. diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index 58053ea3a..abf4b2d64 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-generator-parent - 1.19 + 1.20-SNAPSHOT .. diff --git a/http-generator-nima/pom.xml b/http-generator-nima/pom.xml index e2ec9b711..8bb69cadf 100644 --- a/http-generator-nima/pom.xml +++ b/http-generator-nima/pom.xml @@ -3,7 +3,7 @@ avaje-http-generator-parent io.avaje - 1.19 + 1.20-SNAPSHOT 4.0.0 diff --git a/pom.xml b/pom.xml index e7b578311..f5d9ab8aa 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-generator-parent - 1.19 + 1.20-SNAPSHOT pom From b2d75dd302c6f1b33630a99285dc1fad961be0f1 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 1 Nov 2022 08:44:05 +1300 Subject: [PATCH 0406/1323] Bump version after release --- tests/test-client/pom.xml | 6 +++--- tests/test-helidon/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-jsonb/.factorypath | 2 +- tests/test-nima-jsonb/pom.xml | 8 ++++---- tests/test-nima/pom.xml | 6 +++--- 8 files changed, 15 insertions(+), 15 deletions(-) diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index e602bd308..26e8c1560 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -36,7 +36,7 @@ io.avaje avaje-http-api - 1.19-SNAPSHOT + 1.20-SNAPSHOT @@ -108,12 +108,12 @@ io.avaje avaje-http-client-generator - 1.19-SNAPSHOT + 1.20-SNAPSHOT io.avaje avaje-http-jex-generator - 1.19-SNAPSHOT + 1.20-SNAPSHOT io.avaje diff --git a/tests/test-helidon/pom.xml b/tests/test-helidon/pom.xml index bacfe107f..2fa14df45 100644 --- a/tests/test-helidon/pom.xml +++ b/tests/test-helidon/pom.xml @@ -17,7 +17,7 @@ true org.example.Main 2.3.0 - 1.19-SNAPSHOT + 1.20-SNAPSHOT diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 4305cfd54..6805b7360 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -21,7 +21,7 @@ 2.0.8 1.3.71 2.13.4.1 - 1.19-SNAPSHOT + 1.20-SNAPSHOT diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index b8dd68970..7d559f14f 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -20,7 +20,7 @@ 2.0.8 1.3.71 2.13.4.1 - 1.19-SNAPSHOT + 1.20-SNAPSHOT diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 6f207acdb..40b0bac4e 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -20,7 +20,7 @@ 2.0.8 2.13.4.1 8.9 - 1.19-SNAPSHOT + 1.20-SNAPSHOT diff --git a/tests/test-nima-jsonb/.factorypath b/tests/test-nima-jsonb/.factorypath index 52e4d0c30..d67a0ad00 100644 --- a/tests/test-nima-jsonb/.factorypath +++ b/tests/test-nima-jsonb/.factorypath @@ -1,7 +1,7 @@ - + diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 47474ed70..33585a43e 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -4,7 +4,7 @@ avaje-http-generator-parent io.avaje - 1.19-SNAPSHOT + 1.20-SNAPSHOT ../../pom.xml @@ -28,7 +28,7 @@ io.avaje avaje-http-api - 1.19-SNAPSHOT + 1.20-SNAPSHOT io.avaje @@ -48,7 +48,7 @@ io.avaje avaje-http-nima-generator - 1.19-SNAPSHOT + 1.20-SNAPSHOT test @@ -75,7 +75,7 @@ io.avaje avaje-http-nima-generator - 1.19-SNAPSHOT + 1.20-SNAPSHOT io.avaje diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index 5e866083b..f9da5a3a1 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -6,7 +6,7 @@ avaje-http-generator-parent io.avaje - 1.19-SNAPSHOT + 1.20-SNAPSHOT ../../pom.xml @@ -30,7 +30,7 @@ io.avaje avaje-http-api - 1.19-SNAPSHOT + 1.20-SNAPSHOT io.helidon.nima.webserver @@ -67,7 +67,7 @@ io.avaje avaje-http-nima-generator - 1.19-SNAPSHOT + 1.20-SNAPSHOT io.avaje From 9183e1c8a72361edc9922d4206209eecf1327f59 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sat, 10 Dec 2022 21:02:40 -0500 Subject: [PATCH 0407/1323] support list type in client generation --- .../avaje/http/generator/client/ClientMethodWriter.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java index ff0c4f3b2..975ec40d8 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java @@ -33,8 +33,13 @@ class ClientMethodWriter { void addImportTypes(ControllerReader reader) { reader.addImportTypes(returnType.importTypes()); - for (MethodParam param : method.params()) { - param.addImports(reader); + for (final MethodParam param : method.params()) { + final var type = param.utype(); + final var type0 = type.param0(); + final var type1 = type.param1(); + reader.addImportType(type.mainType()); + if (type0 != null) reader.addImportType(type0); + if (type1 != null) reader.addImportType(type1); } } From 807ab3251b961742d90d761abf494e442cd401bf Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sat, 10 Dec 2022 21:07:01 -0500 Subject: [PATCH 0408/1323] doesn't break on arrays --- .../generator/client/ClientMethodWriter.java | 145 +++++++++--------- 1 file changed, 76 insertions(+), 69 deletions(-) diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java index 975ec40d8..a8d11a39b 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java @@ -1,13 +1,22 @@ package io.avaje.http.generator.client; -import io.avaje.http.generator.core.*; +import java.util.Set; import javax.lang.model.element.TypeElement; -import java.util.Set; -/** - * Write code to register Web route for a given controller method. - */ +import io.avaje.http.generator.core.Append; +import io.avaje.http.generator.core.BeanParamReader; +import io.avaje.http.generator.core.ControllerReader; +import io.avaje.http.generator.core.MethodParam; +import io.avaje.http.generator.core.MethodReader; +import io.avaje.http.generator.core.ParamType; +import io.avaje.http.generator.core.PathSegments; +import io.avaje.http.generator.core.ProcessingContext; +import io.avaje.http.generator.core.UType; +import io.avaje.http.generator.core.Util; +import io.avaje.http.generator.core.WebMethod; + +/** Write code to register Web route for a given controller method. */ class ClientMethodWriter { private static final KnownResponse KNOWN_RESPONSE = new KnownResponse(); @@ -37,21 +46,22 @@ void addImportTypes(ControllerReader reader) { final var type = param.utype(); final var type0 = type.param0(); final var type1 = type.param1(); - reader.addImportType(type.mainType()); - if (type0 != null) reader.addImportType(type0); - if (type1 != null) reader.addImportType(type1); + reader.addImportType(type.mainType().replace("[]", "")); + if (type0 != null) reader.addImportType(type0.replace("[]", "")); + if (type1 != null) reader.addImportType(type1.replace("[]", "")); } } private void methodStart(Append writer) { - for (MethodParam param : method.params()) { + for (final MethodParam param : method.params()) { checkBodyHandler(param); } writer.append(" // %s %s", webMethod, method.webMethodPath()).eol(); writer.append(" @Override").eol(); - writer.append(" public %s%s %s(", methodGenericParams, returnType.shortType(), method.simpleName()); - int count = 0; - for (MethodParam param : method.params()) { + writer.append( + " public %s%s %s(", methodGenericParams, returnType.shortType(), method.simpleName()); + var count = 0; + for (final MethodParam param : method.params()) { if (count++ > 0) { writer.append(", "); } @@ -61,9 +71,7 @@ private void methodStart(Append writer) { writer.append(") {").eol(); } - /** - * Assign a method parameter as *the* BodyHandler. - */ + /** Assign a method parameter as *the* BodyHandler. */ private void checkBodyHandler(MethodParam param) { if (param.rawType().startsWith(BODY_HANDLER)) { param.setResponseHandler(); @@ -80,8 +88,8 @@ void write() { } writer.append("clientContext.request()").eol(); - PathSegments pathSegments = method.pathSegments(); - Set segments = pathSegments.segments(); + final var pathSegments = method.pathSegments(); + final var segments = pathSegments.segments(); writeHeaders(); writePaths(segments); @@ -93,45 +101,43 @@ void write() { } private void writeEnd() { - WebMethod webMethod = method.webMethod(); + final var webMethod = method.webMethod(); writer.append(" .%s()", webMethod.name()).eol(); if (returnType == UType.VOID) { writer.append(" .asVoid();").eol(); } else { - String known = KNOWN_RESPONSE.get(returnType.full()); + final var known = KNOWN_RESPONSE.get(returnType.full()); if (known != null) { writer.append(" %s", known).eol(); - } else { - if (COMPLETABLE_FUTURE.equals(returnType.mainType())) { - writeAsyncResponse(); - } else if (HTTP_CALL.equals(returnType.mainType())) { - writeCallResponse(); - } else { - writeSyncResponse(); - } - } + }else if (COMPLETABLE_FUTURE.equals(returnType.mainType())) { + writeAsyncResponse(); + } else if (HTTP_CALL.equals(returnType.mainType())) { + writeCallResponse(); + } else { + writeSyncResponse(); + } } writer.append(" }").eol().eol(); } private void writeSyncResponse() { writer.append(" "); - String type0 = returnType.mainType(); - String type1 = returnType.param0(); + final var type0 = returnType.mainType(); + final var type1 = returnType.param0(); writeResponse(type0, type1); } private void writeAsyncResponse() { writer.append(" .async()"); - String type0 = returnType.param0(); - String type1 = returnType.param1(); + final var type0 = returnType.param0(); + final var type1 = returnType.param1(); writeResponse(type0, type1); } private void writeCallResponse() { writer.append(" .call()"); - String type0 = returnType.param0(); - String type1 = returnType.param1(); + final var type0 = returnType.param0(); + final var type1 = returnType.param1(); writeResponse(type0, type1); } @@ -140,7 +146,7 @@ private void writeResponse(String type0, String type1) { writer.append(".list(%s.class);", Util.shortName(type1)).eol(); } else if (isStream(type0)) { writer.append(".stream(%s.class);", Util.shortName(type1)).eol(); - } else if (isHttpResponse(type0)){ + } else if (isHttpResponse(type0)) { writeWithHandler(); } else { writer.append(".bean(%s.class);", Util.shortName(type0)).eol(); @@ -156,23 +162,21 @@ private void writeWithHandler() { } private void writeQueryParams(PathSegments pathSegments) { - for (MethodParam param : method.params()) { - ParamType paramType = param.paramType(); - if (paramType == ParamType.QUERYPARAM) { - if (pathSegments.segment(param.paramName()) == null) { - if (isMap(param)) { - writer.append(" .queryParam(%s)", param.name()).eol(); - } else { - writer.append(" .queryParam(\"%s\", %s)", param.paramName(), param.name()).eol(); - } - } - } + for (final MethodParam param : method.params()) { + final var paramType = param.paramType(); + if ((paramType == ParamType.QUERYPARAM) && (pathSegments.segment(param.paramName()) == null)) { + if (isMap(param)) { + writer.append(" .queryParam(%s)", param.name()).eol(); + } else { + writer.append(" .queryParam(\"%s\", %s)", param.paramName(), param.name()).eol(); + } + } } } private void writeHeaders() { - for (MethodParam param : method.params()) { - ParamType paramType = param.paramType(); + for (final MethodParam param : method.params()) { + final var paramType = param.paramType(); if (paramType == ParamType.HEADER) { if (isMap(param)) { writer.append(" .header(%s)", param.name()).eol(); @@ -184,23 +188,25 @@ private void writeHeaders() { } private void writeBeanParams(PathSegments segments) { - for (MethodParam param : method.params()) { - final String varName = param.name(); - ParamType paramType = param.paramType(); - PathSegments.Segment segment = segments.segment(varName); + for (final MethodParam param : method.params()) { + final var varName = param.name(); + final var paramType = param.paramType(); + final var segment = segments.segment(varName); if (segment == null && paramType == ParamType.BEANPARAM) { - TypeElement formBeanType = ctx.typeElement(param.rawType()); - BeanParamReader form = new BeanParamReader(ctx, formBeanType, param.name(), param.shortType(), ParamType.QUERYPARAM); + final var formBeanType = ctx.typeElement(param.rawType()); + final var form = + new BeanParamReader( + ctx, formBeanType, param.name(), param.shortType(), ParamType.QUERYPARAM); form.writeFormParams(writer); } } } private void writeFormParams(PathSegments segments) { - for (MethodParam param : method.params()) { - final String varName = param.name(); - ParamType paramType = param.paramType(); - PathSegments.Segment segment = segments.segment(varName); + for (final MethodParam param : method.params()) { + final var varName = param.name(); + final var paramType = param.paramType(); + final var segment = segments.segment(varName); if (segment == null) { // not a path or matrix parameter writeFormParam(param, paramType); @@ -216,15 +222,17 @@ private void writeFormParam(MethodParam param, ParamType paramType) { writer.append(" .formParam(\"%s\", %s)", param.paramName(), param.name()).eol(); } } else if (paramType == ParamType.FORM) { - TypeElement formBeanType = ctx.typeElement(param.rawType()); - BeanParamReader form = new BeanParamReader(ctx, formBeanType, param.name(), param.shortType(), ParamType.FORMPARAM); + final var formBeanType = ctx.typeElement(param.rawType()); + final var form = + new BeanParamReader( + ctx, formBeanType, param.name(), param.shortType(), ParamType.FORMPARAM); form.writeFormParams(writer); } } private void writeBody() { - for (MethodParam param : method.params()) { - ParamType paramType = param.paramType(); + for (final MethodParam param : method.params()) { + final var paramType = param.paramType(); if (paramType == ParamType.BODY) { writer.append(" .body(%s)", param.name()).eol(); } @@ -235,12 +243,12 @@ private void writePaths(Set segments) { if (!segments.isEmpty()) { writer.append(" "); } - for (PathSegments.Segment segment : segments) { + for (final PathSegments.Segment segment : segments) { if (segment.isLiteral()) { writer.append(".path(\"").append(segment.literalSection()).append("\")"); } else { writer.append(".path(").append(segment.name()).append(")"); - //TODO: matrix params + // TODO: matrix params } } if (!segments.isEmpty()) { @@ -253,19 +261,18 @@ private boolean isMap(MethodParam param) { } private boolean isMap(String type0) { - return type0.equals("java.util.Map"); + return "java.util.Map".equals(type0); } private boolean isList(String type0) { - return type0.equals("java.util.List"); + return "java.util.List".equals(type0); } private boolean isStream(String type0) { - return type0.equals("java.util.stream.Stream"); + return "java.util.stream.Stream".equals(type0); } private boolean isHttpResponse(String type0) { - return type0.equals("java.net.http.HttpResponse"); + return "java.net.http.HttpResponse".equals(type0); } - } From 60d6e94b920a18e6c2e9015251dc59e262f07ca3 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sat, 10 Dec 2022 21:24:39 -0500 Subject: [PATCH 0409/1323] format --- .../generator/client/ClientMethodWriter.java | 119 +++++++++--------- 1 file changed, 56 insertions(+), 63 deletions(-) diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java index a8d11a39b..0b701658f 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java @@ -1,20 +1,9 @@ package io.avaje.http.generator.client; -import java.util.Set; +import io.avaje.http.generator.core.*; import javax.lang.model.element.TypeElement; - -import io.avaje.http.generator.core.Append; -import io.avaje.http.generator.core.BeanParamReader; -import io.avaje.http.generator.core.ControllerReader; -import io.avaje.http.generator.core.MethodParam; -import io.avaje.http.generator.core.MethodReader; -import io.avaje.http.generator.core.ParamType; -import io.avaje.http.generator.core.PathSegments; -import io.avaje.http.generator.core.ProcessingContext; -import io.avaje.http.generator.core.UType; -import io.avaje.http.generator.core.Util; -import io.avaje.http.generator.core.WebMethod; +import java.util.Set; /** Write code to register Web route for a given controller method. */ class ClientMethodWriter { @@ -53,15 +42,15 @@ void addImportTypes(ControllerReader reader) { } private void methodStart(Append writer) { - for (final MethodParam param : method.params()) { + for (MethodParam param : method.params()) { checkBodyHandler(param); } writer.append(" // %s %s", webMethod, method.webMethodPath()).eol(); writer.append(" @Override").eol(); writer.append( " public %s%s %s(", methodGenericParams, returnType.shortType(), method.simpleName()); - var count = 0; - for (final MethodParam param : method.params()) { + int count = 0; + for (MethodParam param : method.params()) { if (count++ > 0) { writer.append(", "); } @@ -88,8 +77,8 @@ void write() { } writer.append("clientContext.request()").eol(); - final var pathSegments = method.pathSegments(); - final var segments = pathSegments.segments(); + PathSegments pathSegments = method.pathSegments(); + Set segments = pathSegments.segments(); writeHeaders(); writePaths(segments); @@ -101,43 +90,45 @@ void write() { } private void writeEnd() { - final var webMethod = method.webMethod(); + WebMethod webMethod = method.webMethod(); writer.append(" .%s()", webMethod.name()).eol(); if (returnType == UType.VOID) { writer.append(" .asVoid();").eol(); } else { - final var known = KNOWN_RESPONSE.get(returnType.full()); + String known = KNOWN_RESPONSE.get(returnType.full()); if (known != null) { writer.append(" %s", known).eol(); - }else if (COMPLETABLE_FUTURE.equals(returnType.mainType())) { - writeAsyncResponse(); - } else if (HTTP_CALL.equals(returnType.mainType())) { - writeCallResponse(); - } else { - writeSyncResponse(); - } + } else { + if (COMPLETABLE_FUTURE.equals(returnType.mainType())) { + writeAsyncResponse(); + } else if (HTTP_CALL.equals(returnType.mainType())) { + writeCallResponse(); + } else { + writeSyncResponse(); + } + } } writer.append(" }").eol().eol(); } private void writeSyncResponse() { writer.append(" "); - final var type0 = returnType.mainType(); - final var type1 = returnType.param0(); + String type0 = returnType.mainType(); + String type1 = returnType.param0(); writeResponse(type0, type1); } private void writeAsyncResponse() { writer.append(" .async()"); - final var type0 = returnType.param0(); - final var type1 = returnType.param1(); + String type0 = returnType.param0(); + String type1 = returnType.param1(); writeResponse(type0, type1); } private void writeCallResponse() { writer.append(" .call()"); - final var type0 = returnType.param0(); - final var type1 = returnType.param1(); + String type0 = returnType.param0(); + String type1 = returnType.param1(); writeResponse(type0, type1); } @@ -162,21 +153,23 @@ private void writeWithHandler() { } private void writeQueryParams(PathSegments pathSegments) { - for (final MethodParam param : method.params()) { - final var paramType = param.paramType(); - if ((paramType == ParamType.QUERYPARAM) && (pathSegments.segment(param.paramName()) == null)) { - if (isMap(param)) { - writer.append(" .queryParam(%s)", param.name()).eol(); - } else { - writer.append(" .queryParam(\"%s\", %s)", param.paramName(), param.name()).eol(); - } - } + for (MethodParam param : method.params()) { + ParamType paramType = param.paramType(); + if (paramType == ParamType.QUERYPARAM) { + if (pathSegments.segment(param.paramName()) == null) { + if (isMap(param)) { + writer.append(" .queryParam(%s)", param.name()).eol(); + } else { + writer.append(" .queryParam(\"%s\", %s)", param.paramName(), param.name()).eol(); + } + } + } } } private void writeHeaders() { - for (final MethodParam param : method.params()) { - final var paramType = param.paramType(); + for (MethodParam param : method.params()) { + ParamType paramType = param.paramType(); if (paramType == ParamType.HEADER) { if (isMap(param)) { writer.append(" .header(%s)", param.name()).eol(); @@ -188,13 +181,13 @@ private void writeHeaders() { } private void writeBeanParams(PathSegments segments) { - for (final MethodParam param : method.params()) { - final var varName = param.name(); - final var paramType = param.paramType(); - final var segment = segments.segment(varName); + for (MethodParam param : method.params()) { + final String varName = param.name(); + ParamType paramType = param.paramType(); + PathSegments.Segment segment = segments.segment(varName); if (segment == null && paramType == ParamType.BEANPARAM) { - final var formBeanType = ctx.typeElement(param.rawType()); - final var form = + TypeElement formBeanType = ctx.typeElement(param.rawType()); + BeanParamReader form = new BeanParamReader( ctx, formBeanType, param.name(), param.shortType(), ParamType.QUERYPARAM); form.writeFormParams(writer); @@ -203,10 +196,10 @@ private void writeBeanParams(PathSegments segments) { } private void writeFormParams(PathSegments segments) { - for (final MethodParam param : method.params()) { - final var varName = param.name(); - final var paramType = param.paramType(); - final var segment = segments.segment(varName); + for (MethodParam param : method.params()) { + final String varName = param.name(); + ParamType paramType = param.paramType(); + PathSegments.Segment segment = segments.segment(varName); if (segment == null) { // not a path or matrix parameter writeFormParam(param, paramType); @@ -222,8 +215,8 @@ private void writeFormParam(MethodParam param, ParamType paramType) { writer.append(" .formParam(\"%s\", %s)", param.paramName(), param.name()).eol(); } } else if (paramType == ParamType.FORM) { - final var formBeanType = ctx.typeElement(param.rawType()); - final var form = + TypeElement formBeanType = ctx.typeElement(param.rawType()); + BeanParamReader form = new BeanParamReader( ctx, formBeanType, param.name(), param.shortType(), ParamType.FORMPARAM); form.writeFormParams(writer); @@ -231,8 +224,8 @@ private void writeFormParam(MethodParam param, ParamType paramType) { } private void writeBody() { - for (final MethodParam param : method.params()) { - final var paramType = param.paramType(); + for (MethodParam param : method.params()) { + ParamType paramType = param.paramType(); if (paramType == ParamType.BODY) { writer.append(" .body(%s)", param.name()).eol(); } @@ -243,7 +236,7 @@ private void writePaths(Set segments) { if (!segments.isEmpty()) { writer.append(" "); } - for (final PathSegments.Segment segment : segments) { + for (PathSegments.Segment segment : segments) { if (segment.isLiteral()) { writer.append(".path(\"").append(segment.literalSection()).append("\")"); } else { @@ -261,18 +254,18 @@ private boolean isMap(MethodParam param) { } private boolean isMap(String type0) { - return "java.util.Map".equals(type0); + return type0.equals("java.util.Map"); } private boolean isList(String type0) { - return "java.util.List".equals(type0); + return type0.equals("java.util.List"); } private boolean isStream(String type0) { - return "java.util.stream.Stream".equals(type0); + return type0.equals("java.util.stream.Stream"); } private boolean isHttpResponse(String type0) { - return "java.net.http.HttpResponse".equals(type0); + return type0.equals("java.net.http.HttpResponse"); } } From 2ef121c15d80c292fdd67dd8df9a173c06240e35 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sat, 10 Dec 2022 21:27:11 -0500 Subject: [PATCH 0410/1323] reset format --- .../generator/client/ClientMethodWriter.java | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java index 0b701658f..5c0abe1d2 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java @@ -5,7 +5,9 @@ import javax.lang.model.element.TypeElement; import java.util.Set; -/** Write code to register Web route for a given controller method. */ +/** + * Write code to register Web route for a given controller method. + */ class ClientMethodWriter { private static final KnownResponse KNOWN_RESPONSE = new KnownResponse(); @@ -47,8 +49,7 @@ private void methodStart(Append writer) { } writer.append(" // %s %s", webMethod, method.webMethodPath()).eol(); writer.append(" @Override").eol(); - writer.append( - " public %s%s %s(", methodGenericParams, returnType.shortType(), method.simpleName()); + writer.append(" public %s%s %s(", methodGenericParams, returnType.shortType(), method.simpleName()); int count = 0; for (MethodParam param : method.params()) { if (count++ > 0) { @@ -60,7 +61,9 @@ private void methodStart(Append writer) { writer.append(") {").eol(); } - /** Assign a method parameter as *the* BodyHandler. */ + /** + * Assign a method parameter as *the* BodyHandler. + */ private void checkBodyHandler(MethodParam param) { if (param.rawType().startsWith(BODY_HANDLER)) { param.setResponseHandler(); @@ -102,7 +105,7 @@ private void writeEnd() { if (COMPLETABLE_FUTURE.equals(returnType.mainType())) { writeAsyncResponse(); } else if (HTTP_CALL.equals(returnType.mainType())) { - writeCallResponse(); + writeCallResponse(); } else { writeSyncResponse(); } @@ -137,7 +140,7 @@ private void writeResponse(String type0, String type1) { writer.append(".list(%s.class);", Util.shortName(type1)).eol(); } else if (isStream(type0)) { writer.append(".stream(%s.class);", Util.shortName(type1)).eol(); - } else if (isHttpResponse(type0)) { + } else if (isHttpResponse(type0)){ writeWithHandler(); } else { writer.append(".bean(%s.class);", Util.shortName(type0)).eol(); @@ -187,9 +190,7 @@ private void writeBeanParams(PathSegments segments) { PathSegments.Segment segment = segments.segment(varName); if (segment == null && paramType == ParamType.BEANPARAM) { TypeElement formBeanType = ctx.typeElement(param.rawType()); - BeanParamReader form = - new BeanParamReader( - ctx, formBeanType, param.name(), param.shortType(), ParamType.QUERYPARAM); + BeanParamReader form = new BeanParamReader(ctx, formBeanType, param.name(), param.shortType(), ParamType.QUERYPARAM); form.writeFormParams(writer); } } @@ -216,9 +217,7 @@ private void writeFormParam(MethodParam param, ParamType paramType) { } } else if (paramType == ParamType.FORM) { TypeElement formBeanType = ctx.typeElement(param.rawType()); - BeanParamReader form = - new BeanParamReader( - ctx, formBeanType, param.name(), param.shortType(), ParamType.FORMPARAM); + BeanParamReader form = new BeanParamReader(ctx, formBeanType, param.name(), param.shortType(), ParamType.FORMPARAM); form.writeFormParams(writer); } } @@ -241,7 +240,7 @@ private void writePaths(Set segments) { writer.append(".path(\"").append(segment.literalSection()).append("\")"); } else { writer.append(".path(").append(segment.name()).append(")"); - // TODO: matrix params + //TODO: matrix params } } if (!segments.isEmpty()) { @@ -268,4 +267,5 @@ private boolean isStream(String type0) { private boolean isHttpResponse(String type0) { return type0.equals("java.net.http.HttpResponse"); } -} + +} \ No newline at end of file From 609c1fe3cbed6a8bfd0cb19e7203dbe3c3b1dc99 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Fri, 16 Dec 2022 11:35:00 +1300 Subject: [PATCH 0411/1323] Bump dependencies in test-nima-jsonb --- tests/test-nima-jsonb/pom.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 33585a43e..dfd1f07d3 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -23,7 +23,7 @@ io.avaje avaje-inject - 8.9 + 8.10 io.avaje @@ -33,7 +33,7 @@ io.avaje avaje-jsonb - 1.0-RC2 + 1.1-RC2 io.helidon.nima.webserver @@ -80,12 +80,12 @@ io.avaje avaje-inject-generator - 8.9 + 8.10 io.avaje avaje-jsonb-generator - 1.0-RC2 + 1.1-RC2 From b1008e46dd0c80692a8c1e5cdcf593aee038cc73 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Fri, 16 Dec 2022 11:36:51 +1300 Subject: [PATCH 0412/1323] [maven-release-plugin] prepare release avaje-http-generator-parent-1.20 --- http-api/pom.xml | 4 ++-- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 4 ++-- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-generator-nima/pom.xml | 2 +- pom.xml | 4 ++-- 8 files changed, 11 insertions(+), 11 deletions(-) diff --git a/http-api/pom.xml b/http-api/pom.xml index 15293cdc9..564c818a4 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-generator-parent - 1.20-SNAPSHOT + 1.20 .. @@ -12,7 +12,7 @@ scm:git:git@github.com:avaje/avaje-http.git - avaje-http-generator-parent-1.19 + avaje-http-generator-parent-1.20 diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index cc0df7831..c8f267064 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -5,7 +5,7 @@ io.avaje avaje-http-generator-parent - 1.20-SNAPSHOT + 1.20 .. diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index e3e9236d7..49a8c77a7 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-generator-parent - 1.20-SNAPSHOT + 1.20 .. @@ -33,7 +33,7 @@ io.avaje avaje-http-api - 1.20-SNAPSHOT + 1.20 diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index 551486e79..8345a5366 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-generator-parent - 1.20-SNAPSHOT + 1.20 .. diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index dcc9a1220..33d2df2b7 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-generator-parent - 1.20-SNAPSHOT + 1.20 .. diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index abf4b2d64..c7895c980 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-generator-parent - 1.20-SNAPSHOT + 1.20 .. diff --git a/http-generator-nima/pom.xml b/http-generator-nima/pom.xml index 8bb69cadf..e196775df 100644 --- a/http-generator-nima/pom.xml +++ b/http-generator-nima/pom.xml @@ -3,7 +3,7 @@ avaje-http-generator-parent io.avaje - 1.20-SNAPSHOT + 1.20 4.0.0 diff --git a/pom.xml b/pom.xml index f5d9ab8aa..ea2459940 100644 --- a/pom.xml +++ b/pom.xml @@ -9,12 +9,12 @@ io.avaje avaje-http-generator-parent - 1.20-SNAPSHOT + 1.20 pom scm:git:git@github.com:avaje/avaje-http.git - avaje-http-generator-parent-1.19 + avaje-http-generator-parent-1.20 From 892c213e9f4a414ec46f6f69f28fa3ec0016e1ba Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Fri, 16 Dec 2022 11:36:58 +1300 Subject: [PATCH 0413/1323] [maven-release-plugin] prepare for next development iteration --- http-api/pom.xml | 4 ++-- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 4 ++-- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-generator-nima/pom.xml | 2 +- pom.xml | 4 ++-- 8 files changed, 11 insertions(+), 11 deletions(-) diff --git a/http-api/pom.xml b/http-api/pom.xml index 564c818a4..99072f048 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-generator-parent - 1.20 + 1.21-SNAPSHOT .. @@ -12,7 +12,7 @@ scm:git:git@github.com:avaje/avaje-http.git - avaje-http-generator-parent-1.20 + avaje-http-generator-parent-1.19 diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index c8f267064..158015e4a 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -5,7 +5,7 @@ io.avaje avaje-http-generator-parent - 1.20 + 1.21-SNAPSHOT .. diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 49a8c77a7..e59d3110d 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-generator-parent - 1.20 + 1.21-SNAPSHOT .. @@ -33,7 +33,7 @@ io.avaje avaje-http-api - 1.20 + 1.21-SNAPSHOT diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index 8345a5366..ab9bab52b 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-generator-parent - 1.20 + 1.21-SNAPSHOT .. diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index 33d2df2b7..1fa74eca8 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-generator-parent - 1.20 + 1.21-SNAPSHOT .. diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index c7895c980..9809fa5b4 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-generator-parent - 1.20 + 1.21-SNAPSHOT .. diff --git a/http-generator-nima/pom.xml b/http-generator-nima/pom.xml index e196775df..18c11c5d6 100644 --- a/http-generator-nima/pom.xml +++ b/http-generator-nima/pom.xml @@ -3,7 +3,7 @@ avaje-http-generator-parent io.avaje - 1.20 + 1.21-SNAPSHOT 4.0.0 diff --git a/pom.xml b/pom.xml index ea2459940..7c0270395 100644 --- a/pom.xml +++ b/pom.xml @@ -9,12 +9,12 @@ io.avaje avaje-http-generator-parent - 1.20 + 1.21-SNAPSHOT pom scm:git:git@github.com:avaje/avaje-http.git - avaje-http-generator-parent-1.20 + avaje-http-generator-parent-1.19 From 1dc3bc42de131a7566b40c12bbb9153acb23ed3c Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Fri, 16 Dec 2022 11:41:12 +1300 Subject: [PATCH 0414/1323] Bump test module dependencies after release --- tests/test-client/pom.xml | 6 +++--- tests/test-helidon/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-jsonb/.factorypath | 2 +- tests/test-nima-jsonb/pom.xml | 8 ++++---- tests/test-nima/pom.xml | 6 +++--- 8 files changed, 15 insertions(+), 15 deletions(-) diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index 26e8c1560..8dc3b7938 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -36,7 +36,7 @@ io.avaje avaje-http-api - 1.20-SNAPSHOT + 1.21-SNAPSHOT @@ -108,12 +108,12 @@ io.avaje avaje-http-client-generator - 1.20-SNAPSHOT + 1.21-SNAPSHOT io.avaje avaje-http-jex-generator - 1.20-SNAPSHOT + 1.21-SNAPSHOT io.avaje diff --git a/tests/test-helidon/pom.xml b/tests/test-helidon/pom.xml index 2fa14df45..4d1607e4d 100644 --- a/tests/test-helidon/pom.xml +++ b/tests/test-helidon/pom.xml @@ -17,7 +17,7 @@ true org.example.Main 2.3.0 - 1.20-SNAPSHOT + 1.21-SNAPSHOT diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 6805b7360..a68527ba7 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -21,7 +21,7 @@ 2.0.8 1.3.71 2.13.4.1 - 1.20-SNAPSHOT + 1.21-SNAPSHOT diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 7d559f14f..d562c30d8 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -20,7 +20,7 @@ 2.0.8 1.3.71 2.13.4.1 - 1.20-SNAPSHOT + 1.21-SNAPSHOT diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 40b0bac4e..ea44c178d 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -20,7 +20,7 @@ 2.0.8 2.13.4.1 8.9 - 1.20-SNAPSHOT + 1.21-SNAPSHOT diff --git a/tests/test-nima-jsonb/.factorypath b/tests/test-nima-jsonb/.factorypath index d67a0ad00..9b0ba4d09 100644 --- a/tests/test-nima-jsonb/.factorypath +++ b/tests/test-nima-jsonb/.factorypath @@ -1,7 +1,7 @@ - + diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index dfd1f07d3..c7cf695a3 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -4,7 +4,7 @@ avaje-http-generator-parent io.avaje - 1.20-SNAPSHOT + 1.21-SNAPSHOT ../../pom.xml @@ -28,7 +28,7 @@ io.avaje avaje-http-api - 1.20-SNAPSHOT + 1.21-SNAPSHOT io.avaje @@ -48,7 +48,7 @@ io.avaje avaje-http-nima-generator - 1.20-SNAPSHOT + 1.21-SNAPSHOT test @@ -75,7 +75,7 @@ io.avaje avaje-http-nima-generator - 1.20-SNAPSHOT + 1.21-SNAPSHOT io.avaje diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index f9da5a3a1..f6c42b1b2 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -6,7 +6,7 @@ avaje-http-generator-parent io.avaje - 1.20-SNAPSHOT + 1.21-SNAPSHOT ../../pom.xml @@ -30,7 +30,7 @@ io.avaje avaje-http-api - 1.20-SNAPSHOT + 1.21-SNAPSHOT io.helidon.nima.webserver @@ -67,7 +67,7 @@ io.avaje avaje-http-nima-generator - 1.20-SNAPSHOT + 1.21-SNAPSHOT io.avaje From b9b49b29527c13ad01e68676e618aee74993af34 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Fri, 16 Dec 2022 13:34:29 +1300 Subject: [PATCH 0415/1323] Change pom autoReleaseAfterClose to true so artifacts release automatically from maven central staging --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 7c0270395..a9a53c9c9 100644 --- a/pom.xml +++ b/pom.xml @@ -18,7 +18,7 @@ - false + true From 81fe165bbb61a5a2ef441aeb02e8facb3af768de Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sat, 24 Dec 2022 12:03:47 -0500 Subject: [PATCH 0416/1323] fix param open api generation --- .../http/generator/core/openapi/MethodParamDocBuilder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/MethodParamDocBuilder.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/MethodParamDocBuilder.java index 7352c9a1d..6248b2aa4 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/MethodParamDocBuilder.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/MethodParamDocBuilder.java @@ -32,7 +32,7 @@ public MethodParamDocBuilder(MethodDocBuilder methodDoc, ElementReader param) { this.paramType = param.paramType(); this.paramName = param.paramName(); this.varName = param.varName(); - this.rawType = param.rawType(); + this.rawType = param.type().full(); this.element = param.element(); } From 5a1d8d424fe4d000f5d70ad5fa707c5d1826cf43 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sun, 25 Dec 2022 01:32:01 -0500 Subject: [PATCH 0417/1323] use swagger APIResponse for more openAPI generation --- .../http/generator/core/MethodReader.java | 41 +++++++++++++------ .../core/openapi/MethodDocBuilder.java | 17 +++++++- 2 files changed, 45 insertions(+), 13 deletions(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java index bfd0addae..c712bdf24 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java @@ -1,5 +1,17 @@ package io.avaje.http.generator.core; +import java.lang.annotation.Annotation; +import java.util.ArrayList; +import java.util.List; + +import javax.lang.model.element.Element; +import javax.lang.model.element.ExecutableElement; +import javax.lang.model.element.VariableElement; +import javax.lang.model.type.ExecutableType; +import javax.lang.model.type.TypeKind; +import javax.lang.model.type.TypeMirror; +import javax.validation.Valid; + import io.avaje.http.api.Delete; import io.avaje.http.api.Form; import io.avaje.http.api.Get; @@ -9,20 +21,10 @@ import io.avaje.http.api.Put; import io.avaje.http.generator.core.javadoc.Javadoc; import io.avaje.http.generator.core.openapi.MethodDocBuilder; +import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tags; -import javax.lang.model.element.Element; -import javax.lang.model.element.ExecutableElement; -import javax.lang.model.element.VariableElement; -import javax.lang.model.type.ExecutableType; -import javax.lang.model.type.TypeKind; -import javax.lang.model.type.TypeMirror; -import javax.validation.Valid; -import java.lang.annotation.Annotation; -import java.util.ArrayList; -import java.util.List; - public class MethodReader { private final ProcessingContext ctx; @@ -46,13 +48,19 @@ public class MethodReader { private final String produces; + private final ApiResponse[] apiResponses; + private final ExecutableType actualExecutable; private final List actualParams; private final PathSegments pathSegments; private final boolean hasValid; - MethodReader(ControllerReader bean, ExecutableElement element, ExecutableType actualExecutable, ProcessingContext ctx) { + MethodReader( + ControllerReader bean, + ExecutableElement element, + ExecutableType actualExecutable, + ProcessingContext ctx) { this.ctx = ctx; this.bean = bean; this.element = element; @@ -62,6 +70,7 @@ public class MethodReader { this.methodRoles = Util.findRoles(element); this.javadoc = Javadoc.parse(ctx.getDocComment(element)); this.produces = produces(bean); + this.apiResponses = getApiResponses(); initWebMethodViaAnnotation(); if (isWebMethod()) { this.hasValid = findAnnotation(Valid.class) != null; @@ -122,6 +131,10 @@ private String produces(ControllerReader bean) { return (produces != null) ? produces.value() : bean.produces(); } + private ApiResponse[] getApiResponses() { + return element.getAnnotationsByType(ApiResponse.class); + } + public A findAnnotation(Class type) { A annotation = element.getAnnotation(type); if (annotation != null) { @@ -216,6 +229,10 @@ public String produces() { return produces; } + public ApiResponse[] apiResponses() { + return apiResponses; + } + public TypeMirror returnType() { if (actualExecutable != null) { return actualExecutable.getReturnType(); diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/MethodDocBuilder.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/MethodDocBuilder.java index 3d4d3139f..d04379f55 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/MethodDocBuilder.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/MethodDocBuilder.java @@ -82,7 +82,22 @@ public void build() { String contentMediaType = (produces == null) ? MediaType.APPLICATION_JSON : produces; response.setContent(ctx.createContent(methodReader.returnType(), contentMediaType)); } - responses.addApiResponse(methodReader.statusCode(), response); + var override2xx = false; + for (final var responseAnnotation : methodReader.apiResponses()) { + final var newResponse = new ApiResponse(); + + if (responseAnnotation.description().isEmpty()) + newResponse.setDescription(response.getDescription()); + else newResponse.setDescription(responseAnnotation.description()); + + // if user wants to define their own 2xx status code + if (responseAnnotation.responseCode().startsWith("2")) { + newResponse.setContent(response.getContent()); + override2xx = true; + } + responses.addApiResponse(responseAnnotation.responseCode(), newResponse); + } + if (!override2xx) responses.addApiResponse(methodReader.statusCode(), response); } DocContext getContext() { From 7bccc8c77c0995b23be34f78a56e2a70424b392b Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sun, 25 Dec 2022 16:03:04 -0500 Subject: [PATCH 0418/1323] use custom annotation --- .../io/avaje/http/api/OpenAPIReturns.java | 43 +++++++++++++++++++ .../http/api/OpenAPIReturnsContainer.java | 13 ++++++ .../http/generator/core/MethodReader.java | 9 ++-- .../core/openapi/MethodDocBuilder.java | 28 +++++++++--- 4 files changed, 84 insertions(+), 9 deletions(-) create mode 100644 http-api/src/main/java/io/avaje/http/api/OpenAPIReturns.java create mode 100644 http-api/src/main/java/io/avaje/http/api/OpenAPIReturnsContainer.java diff --git a/http-api/src/main/java/io/avaje/http/api/OpenAPIReturns.java b/http-api/src/main/java/io/avaje/http/api/OpenAPIReturns.java new file mode 100644 index 000000000..cab052100 --- /dev/null +++ b/http-api/src/main/java/io/avaje/http/api/OpenAPIReturns.java @@ -0,0 +1,43 @@ +package io.avaje.http.api; + +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import java.lang.annotation.Repeatable; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +/** + * Specify endpoint response status code/description/type. + * + *

When not specified the default 2xx openAPI generation is based on the javadoc of the method. + *

Will not override the default 2xx generated openapi unless status code is 2xx + *

{@code
+ * @Post("/post")
+ * @OpenAPIReturns(responseCode = "200", description = "from annotaion")
+ * @OpenAPIReturns(responseCode = "201")
+ * @OpenAPIReturns(responseCode = "500", description = "Some other Error", type=ErrorResponse.class)
+ * ResponseModel endpoint() {}
+ *
+ * }
+ */ +@Target(value = METHOD) +@Retention(value = RUNTIME) +@Repeatable(OpenAPIReturnsContainer.class) +public @interface OpenAPIReturns { + + /** the http status code of this response */ + String responseCode(); + + /** + * The description of the return value. By default uses the @return javadoc of the method as the + * description + */ + String description() default ""; + + /** + * The concrete type that that this endpoint returns. If status code is a 2xx code it will default + * to the return type of the method + */ + Class type() default Void.class; +} diff --git a/http-api/src/main/java/io/avaje/http/api/OpenAPIReturnsContainer.java b/http-api/src/main/java/io/avaje/http/api/OpenAPIReturnsContainer.java new file mode 100644 index 000000000..90de6cc00 --- /dev/null +++ b/http-api/src/main/java/io/avaje/http/api/OpenAPIReturnsContainer.java @@ -0,0 +1,13 @@ +package io.avaje.http.api; + +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +@Target(value = METHOD) +@Retention(value = RUNTIME) +public @interface OpenAPIReturnsContainer { + OpenAPIReturns[] value(); +} diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java index c712bdf24..fdf0c5052 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java @@ -15,6 +15,7 @@ import io.avaje.http.api.Delete; import io.avaje.http.api.Form; import io.avaje.http.api.Get; +import io.avaje.http.api.OpenAPIReturns; import io.avaje.http.api.Patch; import io.avaje.http.api.Post; import io.avaje.http.api.Produces; @@ -48,7 +49,7 @@ public class MethodReader { private final String produces; - private final ApiResponse[] apiResponses; + private final OpenAPIReturns[] apiResponses; private final ExecutableType actualExecutable; private final List actualParams; @@ -131,8 +132,8 @@ private String produces(ControllerReader bean) { return (produces != null) ? produces.value() : bean.produces(); } - private ApiResponse[] getApiResponses() { - return element.getAnnotationsByType(ApiResponse.class); + private OpenAPIReturns[] getApiResponses() { + return element.getAnnotationsByType(OpenAPIReturns.class); } public A findAnnotation(Class type) { @@ -229,7 +230,7 @@ public String produces() { return produces; } - public ApiResponse[] apiResponses() { + public OpenAPIReturns[] apiResponses() { return apiResponses; } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/MethodDocBuilder.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/MethodDocBuilder.java index d04379f55..8f13ae663 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/MethodDocBuilder.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/MethodDocBuilder.java @@ -1,5 +1,8 @@ package io.avaje.http.generator.core.openapi; +import javax.lang.model.type.MirroredTypeException; +import javax.lang.model.type.TypeMirror; + import io.avaje.http.api.MediaType; import io.avaje.http.generator.core.MethodParam; import io.avaje.http.generator.core.MethodReader; @@ -73,28 +76,43 @@ public void build() { ApiResponse response = new ApiResponse(); response.setDescription(javadoc.getReturnDescription()); + final var produces = methodReader.produces(); + final var contentMediaType = (produces == null) ? MediaType.APPLICATION_JSON : produces; + if (methodReader.isVoid()) { if (isEmpty(response.getDescription())) { response.setDescription("No content"); } } else { - final String produces = methodReader.produces(); - String contentMediaType = (produces == null) ? MediaType.APPLICATION_JSON : produces; - response.setContent(ctx.createContent(methodReader.returnType(), contentMediaType)); + response.setContent(ctx.createContent(methodReader.returnType(), contentMediaType)); } var override2xx = false; for (final var responseAnnotation : methodReader.apiResponses()) { final var newResponse = new ApiResponse(); - if (responseAnnotation.description().isEmpty()) + if (responseAnnotation.description().isEmpty()) { newResponse.setDescription(response.getDescription()); - else newResponse.setDescription(responseAnnotation.description()); + } else { + newResponse.setDescription(responseAnnotation.description()); + } // if user wants to define their own 2xx status code if (responseAnnotation.responseCode().startsWith("2")) { newResponse.setContent(response.getContent()); override2xx = true; } + TypeMirror returnType = null; + try { + // this will always throw + responseAnnotation.type(); + } catch (final MirroredTypeException mte) { + returnType = mte.getTypeMirror(); + } + + if (!"java.lang.Void".equals(returnType.toString())) { + newResponse.setContent(ctx.createContent(returnType, contentMediaType)); + } + responses.addApiResponse(responseAnnotation.responseCode(), newResponse); } if (!override2xx) responses.addApiResponse(methodReader.statusCode(), response); From 6efb448b6c31a0096b15b7956107cf8c9b51cf37 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sun, 25 Dec 2022 20:54:11 -0500 Subject: [PATCH 0419/1323] Update OpenAPIReturnsContainer.java --- .../src/main/java/io/avaje/http/api/OpenAPIReturnsContainer.java | 1 + 1 file changed, 1 insertion(+) diff --git a/http-api/src/main/java/io/avaje/http/api/OpenAPIReturnsContainer.java b/http-api/src/main/java/io/avaje/http/api/OpenAPIReturnsContainer.java index 90de6cc00..a8e9a66cd 100644 --- a/http-api/src/main/java/io/avaje/http/api/OpenAPIReturnsContainer.java +++ b/http-api/src/main/java/io/avaje/http/api/OpenAPIReturnsContainer.java @@ -6,6 +6,7 @@ import java.lang.annotation.Retention; import java.lang.annotation.Target; +/** a container for the OpenAPIReturns annotation to make it repeatable */ @Target(value = METHOD) @Retention(value = RUNTIME) public @interface OpenAPIReturnsContainer { From 314e3144055cf2acb1746889a16a7595faf4f55c Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Mon, 26 Dec 2022 16:06:48 -0500 Subject: [PATCH 0420/1323] tests --- .../example/myapp/web/test/ErrorResponse.java | 7 + .../myapp/web/test/OpenAPIController.java | 73 +++++++++ .../http/generator/JavalinProcessorTest.java | 39 ++++- .../java/io/avaje/http/generator/openapi.json | 151 ++++++++++++++++++ 4 files changed, 263 insertions(+), 7 deletions(-) create mode 100644 tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/ErrorResponse.java create mode 100644 tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/OpenAPIController.java create mode 100644 tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/openapi.json diff --git a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/ErrorResponse.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/ErrorResponse.java new file mode 100644 index 000000000..4611cc712 --- /dev/null +++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/ErrorResponse.java @@ -0,0 +1,7 @@ +package org.example.myapp.web.test; + +public class ErrorResponse { + + public String id; + public String text; +} diff --git a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/OpenAPIController.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/OpenAPIController.java new file mode 100644 index 000000000..109b63e35 --- /dev/null +++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/OpenAPIController.java @@ -0,0 +1,73 @@ +package org.example.myapp.web.test; + +import java.util.List; + +import io.avaje.http.api.Controller; +import io.avaje.http.api.Get; +import io.avaje.http.api.MediaType; +import io.avaje.http.api.OpenAPIReturns; +import io.avaje.http.api.Path; +import io.avaje.http.api.Post; +import io.avaje.http.api.Produces; +import io.javalin.http.Context; +import io.swagger.v3.oas.annotations.OpenAPIDefinition; +import io.swagger.v3.oas.annotations.info.Info; +import io.swagger.v3.oas.annotations.tags.Tag; + +@OpenAPIDefinition( + info = + @Info( + title = "Example service", + description = "Example Javalin controllers with Java and Maven")) +@Controller +@Path("openapi/") +public class OpenAPIController { + + /** + * Example of Open API Get (up to the first period is the summary). When using Javalin Context + * only
+ * This Javadoc description is added to the generated openapi.json + * + * @return funny phrase (this part of the javadoc is added to the response desc) + */ + @Get("/get") + @Produces(MediaType.TEXT_PLAIN) + @OpenAPIReturns(responseCode = "200", type = String.class) + void ctxEndpoint(Context ctx) { + ctx.contentType(MediaType.TEXT_PLAIN).result("healthlmao"); + } + + /** + * Standard Post. uses tag annotation to add tags to openapi json + * + * @param b the body (this is used for generated request body desc) + * @return the response body (from javadoc) + */ + @Post("/post") + @Tag(name = "tag1", description = "this is added to openapi tags") + @OpenAPIReturns(responseCode = "200", description = "overrides @return javadoc description") + @OpenAPIReturns(responseCode = "201") + @OpenAPIReturns( + responseCode = "400", + description = "User not found (Will not have an associated response schema)") + @OpenAPIReturns( + responseCode = "500", + description = "Some other Error (Will have this error class as the response class)", + type = ErrorResponse.class) + Person testPost(Person b) { + return new Person(0, "baby"); + } + + /** + * Standard Post. The Deprecated annotation adds "deprecacted:true" to the generated json + * + * @param b the body + * @return the response body (from javadoc) + */ + @Deprecated + @Post("/post1") + Person testPostl(List m) { + + return new Person(0, "baby"); + } +} diff --git a/tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/JavalinProcessorTest.java b/tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/JavalinProcessorTest.java index d460fd3fc..cc70d44ca 100644 --- a/tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/JavalinProcessorTest.java +++ b/tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/JavalinProcessorTest.java @@ -21,6 +21,8 @@ import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; +import com.fasterxml.jackson.databind.ObjectMapper; + import io.avaje.http.generator.javalin.JavalinProcessor; import io.avaje.jsonb.generator.Processor; @@ -48,12 +50,7 @@ public void runAnnoationProcessor() throws Exception { final var task = compiler.getTask( - new PrintWriter(System.out), - null, - null, - List.of("--release=11"), - null, - files); + new PrintWriter(System.out), null, null, List.of("--release=11"), null, files); task.setProcessors(List.of(new JavalinProcessor())); assertThat(task.call()).isTrue(); @@ -67,6 +64,27 @@ public void runAnnoationProcessorJsonB() throws Exception { final var compiler = ToolProvider.getSystemJavaCompiler(); + final var task = + compiler.getTask( + new PrintWriter(System.out), null, null, List.of("--release=11"), null, files); + task.setProcessors(List.of(new JavalinProcessor(false), new Processor())); + + assertThat(task.call()).isTrue(); + } + + @Test + public void testOpenAPIGeneration() throws Exception { + final var source = Paths.get("src").toAbsolutePath().toString(); + // OpenAPIController + final var files = getSourceFiles(source); + + Iterable openAPIController = null; + for (final var file : files) { + if (file.isNameCompatible("OpenAPIController", Kind.SOURCE)) + openAPIController = List.of(file); + } + final var compiler = ToolProvider.getSystemJavaCompiler(); + final var task = compiler.getTask( new PrintWriter(System.out), @@ -74,10 +92,17 @@ public void runAnnoationProcessorJsonB() throws Exception { null, List.of("--release=11"), null, - files); + openAPIController); task.setProcessors(List.of(new JavalinProcessor(false), new Processor())); assertThat(task.call()).isTrue(); + + final var mapper = new ObjectMapper(); + final var expectedOpenApiJson = + mapper.readTree(new File("src/test/java/io/avaje/http/generator/openapi.json")); + final var generatedOpenApi = mapper.readTree(new File("openapi.json")); + + assert expectedOpenApiJson.equals(generatedOpenApi); } private Iterable getSourceFiles(String source) throws Exception { diff --git a/tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/openapi.json b/tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/openapi.json new file mode 100644 index 000000000..725fbb0b0 --- /dev/null +++ b/tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/openapi.json @@ -0,0 +1,151 @@ +{ + "openapi": "3.0.1", + "info": { + "title": "Example service", + "description": "Example Javalin controllers with Java and Maven", + "version": "" + }, + "tags": [ + { + "name": "tag1", + "description": "this is added to openapi tags" + } + ], + "paths": { + "/openapi/get": { + "get": { + "tags": [], + "summary": "Example of Open API Get (up to the first period is the summary)", + "description": "When using Javalin Context only This Javadoc description is added to the generated openapi.json", + "responses": { + "200": { + "description": "funny phrase (this part of the javadoc is added to the response desc)", + "content": { + "text/plain": { + "schema": { + "type": "string" + } + } + } + } + } + } + }, + "/openapi/post": { + "post": { + "tags": [ + "tag1" + ], + "summary": "Standard Post", + "description": "uses tag annotation to add tags to openapi json", + "requestBody": { + "description": "the body (this is used for generated request body desc)", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Person" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "overrides @return javadoc description", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Person" + } + } + } + }, + "201": { + "description": "the response body (from javadoc)", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Person" + } + } + } + }, + "400": { + "description": "User not found (Will not have an associated response schema)" + }, + "500": { + "description": "Some other Error (Will have this error class as the response class)", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + } + } + } + }, + "/openapi/post1": { + "post": { + "tags": [], + "summary": "Standard Post", + "description": "The Deprecated annotation adds \"deprecacted:true\" to the generated json", + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Person" + } + } + } + }, + "required": true + }, + "responses": { + "201": { + "description": "the response body (from javadoc)", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Person" + } + } + } + } + }, + "deprecated": true + } + } + }, + "components": { + "schemas": { + "ErrorResponse": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "text": { + "type": "string" + } + } + }, + "Person": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "nullable": false + }, + "name": { + "type": "string" + } + } + } + } + } +} From 80f3949f3c79fc011900204df0e83dc02800ab43 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Mon, 26 Dec 2022 16:10:47 -0500 Subject: [PATCH 0421/1323] desc --- .../main/java/org/example/myapp/web/test/OpenAPIController.java | 2 +- .../src/test/java/io/avaje/http/generator/openapi.json | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/OpenAPIController.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/OpenAPIController.java index 109b63e35..3076e624c 100644 --- a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/OpenAPIController.java +++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/OpenAPIController.java @@ -61,7 +61,7 @@ Person testPost(Person b) { /** * Standard Post. The Deprecated annotation adds "deprecacted:true" to the generated json * - * @param b the body + * @param m the body * @return the response body (from javadoc) */ @Deprecated diff --git a/tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/openapi.json b/tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/openapi.json index 725fbb0b0..1ab067df4 100644 --- a/tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/openapi.json +++ b/tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/openapi.json @@ -92,6 +92,7 @@ "summary": "Standard Post", "description": "The Deprecated annotation adds \"deprecacted:true\" to the generated json", "requestBody": { + "description": "the body", "content": { "application/json": { "schema": { From fdf5b587a40e3b072f8a05ee8d5eb04aaf3dfa34 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Mon, 26 Dec 2022 16:13:17 -0500 Subject: [PATCH 0422/1323] rename test file --- .../test/java/io/avaje/http/generator/JavalinProcessorTest.java | 2 +- .../avaje/http/generator/{openapi.json => expectedOpenApi.json} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/{openapi.json => expectedOpenApi.json} (100%) diff --git a/tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/JavalinProcessorTest.java b/tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/JavalinProcessorTest.java index cc70d44ca..617676246 100644 --- a/tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/JavalinProcessorTest.java +++ b/tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/JavalinProcessorTest.java @@ -99,7 +99,7 @@ public void testOpenAPIGeneration() throws Exception { final var mapper = new ObjectMapper(); final var expectedOpenApiJson = - mapper.readTree(new File("src/test/java/io/avaje/http/generator/openapi.json")); + mapper.readTree(new File("src/test/java/io/avaje/http/generator/expectedOpenApi.json")); final var generatedOpenApi = mapper.readTree(new File("openapi.json")); assert expectedOpenApiJson.equals(generatedOpenApi); diff --git a/tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/openapi.json b/tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/expectedOpenApi.json similarity index 100% rename from tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/openapi.json rename to tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/expectedOpenApi.json From ef652c6706a27341b2b1878bdd32cfa605f2933f Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Mon, 26 Dec 2022 16:44:25 -0500 Subject: [PATCH 0423/1323] rename annotation --- ...enAPIReturns.java => OpenAPIResponse.java} | 4 +-- ...nsContainer.java => OpenAPIResponses.java} | 10 ++++--- .../http/generator/core/MethodReader.java | 26 ++++++++++++++----- .../myapp/web/test/OpenAPIController.java | 20 +++++++++----- .../avaje/http/generator/expectedOpenApi.json | 13 ++++++++++ 5 files changed, 55 insertions(+), 18 deletions(-) rename http-api/src/main/java/io/avaje/http/api/{OpenAPIReturns.java => OpenAPIResponse.java} (94%) rename http-api/src/main/java/io/avaje/http/api/{OpenAPIReturnsContainer.java => OpenAPIResponses.java} (62%) diff --git a/http-api/src/main/java/io/avaje/http/api/OpenAPIReturns.java b/http-api/src/main/java/io/avaje/http/api/OpenAPIResponse.java similarity index 94% rename from http-api/src/main/java/io/avaje/http/api/OpenAPIReturns.java rename to http-api/src/main/java/io/avaje/http/api/OpenAPIResponse.java index cab052100..6bd59c10b 100644 --- a/http-api/src/main/java/io/avaje/http/api/OpenAPIReturns.java +++ b/http-api/src/main/java/io/avaje/http/api/OpenAPIResponse.java @@ -23,8 +23,8 @@ */ @Target(value = METHOD) @Retention(value = RUNTIME) -@Repeatable(OpenAPIReturnsContainer.class) -public @interface OpenAPIReturns { +@Repeatable(OpenAPIResponses.class) +public @interface OpenAPIResponse { /** the http status code of this response */ String responseCode(); diff --git a/http-api/src/main/java/io/avaje/http/api/OpenAPIReturnsContainer.java b/http-api/src/main/java/io/avaje/http/api/OpenAPIResponses.java similarity index 62% rename from http-api/src/main/java/io/avaje/http/api/OpenAPIReturnsContainer.java rename to http-api/src/main/java/io/avaje/http/api/OpenAPIResponses.java index a8e9a66cd..cf21e8688 100644 --- a/http-api/src/main/java/io/avaje/http/api/OpenAPIReturnsContainer.java +++ b/http-api/src/main/java/io/avaje/http/api/OpenAPIResponses.java @@ -6,9 +6,13 @@ import java.lang.annotation.Retention; import java.lang.annotation.Target; -/** a container for the OpenAPIReturns annotation to make it repeatable */ +/** + * Container for repeatable {@link OpenAPIResponse} annotation + * + * @see OpenAPIResponse + */ @Target(value = METHOD) @Retention(value = RUNTIME) -public @interface OpenAPIReturnsContainer { - OpenAPIReturns[] value(); +public @interface OpenAPIResponses { + OpenAPIResponse[] value(); } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java index fdf0c5052..64512d6fc 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java @@ -2,7 +2,11 @@ import java.lang.annotation.Annotation; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; +import java.util.stream.Stream; import javax.lang.model.element.Element; import javax.lang.model.element.ExecutableElement; @@ -15,7 +19,8 @@ import io.avaje.http.api.Delete; import io.avaje.http.api.Form; import io.avaje.http.api.Get; -import io.avaje.http.api.OpenAPIReturns; +import io.avaje.http.api.OpenAPIResponse; +import io.avaje.http.api.OpenAPIResponses; import io.avaje.http.api.Patch; import io.avaje.http.api.Post; import io.avaje.http.api.Produces; @@ -49,7 +54,7 @@ public class MethodReader { private final String produces; - private final OpenAPIReturns[] apiResponses; + private final List apiResponses; private final ExecutableType actualExecutable; private final List actualParams; @@ -128,12 +133,20 @@ public Javadoc javadoc() { } private String produces(ControllerReader bean) { - final Produces produces = findAnnotation(Produces.class); + final var produces = findAnnotation(Produces.class); return (produces != null) ? produces.value() : bean.produces(); } - private OpenAPIReturns[] getApiResponses() { - return element.getAnnotationsByType(OpenAPIReturns.class); + private List getApiResponses() { + final var container = + Optional.ofNullable(findAnnotation(OpenAPIResponses.class)).stream() + .map(OpenAPIResponses::value) + .flatMap(Arrays::stream); + + return Stream.concat(container, Arrays.stream(element.getAnnotationsByType(OpenAPIResponse.class))) + .collect(Collectors.toList()); + + } public
A findAnnotation(Class type) { @@ -230,7 +243,7 @@ public String produces() { return produces; } - public OpenAPIReturns[] apiResponses() { + public List apiResponses() { return apiResponses; } @@ -291,5 +304,4 @@ public String bodyName() { } return "body"; } - } diff --git a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/OpenAPIController.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/OpenAPIController.java index 3076e624c..98a89cd12 100644 --- a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/OpenAPIController.java +++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/OpenAPIController.java @@ -5,7 +5,8 @@ import io.avaje.http.api.Controller; import io.avaje.http.api.Get; import io.avaje.http.api.MediaType; -import io.avaje.http.api.OpenAPIReturns; +import io.avaje.http.api.OpenAPIResponse; +import io.avaje.http.api.OpenAPIResponses; import io.avaje.http.api.Path; import io.avaje.http.api.Post; import io.avaje.http.api.Produces; @@ -32,7 +33,7 @@ public class OpenAPIController { */ @Get("/get") @Produces(MediaType.TEXT_PLAIN) - @OpenAPIReturns(responseCode = "200", type = String.class) + @OpenAPIResponse(responseCode = "200", type = String.class) void ctxEndpoint(Context ctx) { ctx.contentType(MediaType.TEXT_PLAIN).result("healthlmao"); } @@ -45,12 +46,12 @@ void ctxEndpoint(Context ctx) { */ @Post("/post") @Tag(name = "tag1", description = "this is added to openapi tags") - @OpenAPIReturns(responseCode = "200", description = "overrides @return javadoc description") - @OpenAPIReturns(responseCode = "201") - @OpenAPIReturns( + @OpenAPIResponse(responseCode = "200", description = "overrides @return javadoc description") + @OpenAPIResponse(responseCode = "201") + @OpenAPIResponse( responseCode = "400", description = "User not found (Will not have an associated response schema)") - @OpenAPIReturns( + @OpenAPIResponse( responseCode = "500", description = "Some other Error (Will have this error class as the response class)", type = ErrorResponse.class) @@ -66,6 +67,13 @@ Person testPost(Person b) { */ @Deprecated @Post("/post1") + @OpenAPIResponses({ + @OpenAPIResponse(responseCode = "400", description = "User not found"), + @OpenAPIResponse( + responseCode = "500", + description = "Some other Error", + type = ErrorResponse.class) + }) Person testPostl(List m) { return new Person(0, "baby"); diff --git a/tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/expectedOpenApi.json b/tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/expectedOpenApi.json index 1ab067df4..0648f7a2f 100644 --- a/tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/expectedOpenApi.json +++ b/tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/expectedOpenApi.json @@ -106,6 +106,19 @@ "required": true }, "responses": { + "400": { + "description": "User not found" + }, + "500": { + "description": "Some other Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, "201": { "description": "the response body (from javadoc)", "content": { From 82286bdb3ab7ae323c49d9b1731a9937ed5e5256 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Wed, 28 Dec 2022 00:11:26 -0500 Subject: [PATCH 0424/1323] support generic jsonb types --- .../avaje/http/generator/core/JsonBUtil.java | 18 ++++++++++++++++-- .../io/avaje/http/generator/core/UType.java | 16 ++++++++++++++++ .../generator/javalin/ControllerWriter.java | 12 ++++++++++-- 3 files changed, 42 insertions(+), 4 deletions(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java index 78365b3f2..a3bc7dc38 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java @@ -1,8 +1,10 @@ package io.avaje.http.generator.core; +import java.util.Collection; import java.util.LinkedHashMap; import java.util.Map; import java.util.function.Consumer; +import java.util.stream.Collectors; public class JsonBUtil { private JsonBUtil() {} @@ -53,8 +55,20 @@ public static void writeJsonbType(UType type, Append writer) { writer.append("%s.class).map()", type.param1()); break; default: - throw new UnsupportedOperationException( - "Only java.util Map, Set and List are supported JsonB Controller Collection Types"); + { + try { + if (Collection.class.isAssignableFrom(Class.forName(type.mainType()))) + throw new UnsupportedOperationException( + "Only java.util Map, Set and List are supported JsonB Controller Collection Types"); + } catch (final ClassNotFoundException e) { + throw new UnsupportedOperationException( + "Only java.util Map, Set and List are supported JsonB Controller Collection Types"); + } + final var params = + type.allTypes().stream().skip(1).collect(Collectors.joining(".class, ")) + ".class"; + + writer.append("Types.newParameterizedType(%s.class, %s))", type.mainType(), params); + } } } writer.append(";").eol(); diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java index dd2f2d4d6..7f0d58196 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java @@ -40,6 +40,12 @@ static UType parse(TypeMirror type) { default String param0() { return null; } + /** + * Return all types associated with this Utype. + */ + default List allTypes() { + return null; + } /** * Return the second generic parameter. @@ -123,6 +129,11 @@ public String shortName() { public String mainType() { return rawType; } + + @Override + public List allTypes() { + return List.of(rawType); + } } /** @@ -201,6 +212,11 @@ public String mainType() { return allTypes.isEmpty() ? null : allTypes.get(0); } + @Override + public List allTypes() { + return allTypes; + } + @Override public String param0() { return allTypes.size() < 2 ? null : allTypes.get(1); diff --git a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java index 7f19e1ccc..0ddae845f 100644 --- a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java +++ b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java @@ -1,10 +1,17 @@ package io.avaje.http.generator.javalin; -import io.avaje.http.generator.core.*; - import java.io.IOException; import java.util.Map; +import io.avaje.http.generator.core.BaseControllerWriter; +import io.avaje.http.generator.core.Constants; +import io.avaje.http.generator.core.ControllerReader; +import io.avaje.http.generator.core.JsonBUtil; +import io.avaje.http.generator.core.MethodReader; +import io.avaje.http.generator.core.PrimitiveUtil; +import io.avaje.http.generator.core.ProcessingContext; +import io.avaje.http.generator.core.UType; + /** * Write Javalin specific Controller WebRoute handling adapter. */ @@ -21,6 +28,7 @@ class ControllerWriter extends BaseControllerWriter { if (useJsonB) { reader.addImportType("io.avaje.jsonb.Jsonb"); reader.addImportType("io.avaje.jsonb.JsonType"); + reader.addImportType("io.avaje.jsonb.Types"); this.jsonTypes = JsonBUtil.jsonTypes(reader); } else { this.jsonTypes = Map.of(); From 47fb3efc679ad2f28d514a7f3c6167c9a502556d Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Wed, 28 Dec 2022 02:29:39 -0500 Subject: [PATCH 0425/1323] add jsonb types to imports --- .../java/io/avaje/http/generator/core/JsonBUtil.java | 9 ++------- .../main/java/io/avaje/http/generator/core/UType.java | 2 +- .../avaje/http/generator/javalin/ControllerWriter.java | 10 +++++++++- .../http/generator/helidon/nima/ControllerWriter.java | 10 +++++++++- 4 files changed, 21 insertions(+), 10 deletions(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java index a3bc7dc38..c28ec8977 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java @@ -1,6 +1,5 @@ package io.avaje.http.generator.core; -import java.util.Collection; import java.util.LinkedHashMap; import java.util.Map; import java.util.function.Consumer; @@ -56,14 +55,10 @@ public static void writeJsonbType(UType type, Append writer) { break; default: { - try { - if (Collection.class.isAssignableFrom(Class.forName(type.mainType()))) - throw new UnsupportedOperationException( - "Only java.util Map, Set and List are supported JsonB Controller Collection Types"); - } catch (final ClassNotFoundException e) { + if (type.mainType().contains("java.util")) throw new UnsupportedOperationException( "Only java.util Map, Set and List are supported JsonB Controller Collection Types"); - } + final var params = type.allTypes().stream().skip(1).collect(Collectors.joining(".class, ")) + ".class"; diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java index 7f0d58196..d5fc543ab 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java @@ -44,7 +44,7 @@ default String param0() { * Return all types associated with this Utype. */ default List allTypes() { - return null; + return List.of(); } /** diff --git a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java index 0ddae845f..2ecc9a753 100644 --- a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java +++ b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java @@ -1,6 +1,7 @@ package io.avaje.http.generator.javalin; import java.io.IOException; +import java.util.List; import java.util.Map; import io.avaje.http.generator.core.BaseControllerWriter; @@ -30,6 +31,11 @@ class ControllerWriter extends BaseControllerWriter { reader.addImportType("io.avaje.jsonb.JsonType"); reader.addImportType("io.avaje.jsonb.Types"); this.jsonTypes = JsonBUtil.jsonTypes(reader); + jsonTypes.values().stream() + .map(UType::allTypes) + .flatMap(List::stream) + .filter(s -> !s.contains("java.lang")) + .forEach(reader::addImportType); } else { this.jsonTypes = Map.of(); } @@ -85,7 +91,9 @@ private void writeClassStart() { } for (final UType type : jsonTypes.values()) { - writer.append(" private final JsonType<%s> %sJsonType;", PrimitiveUtil.wrap(type.full()), type.shortName()).eol(); + final var typeString = PrimitiveUtil.wrap(type.shortType()).replace(",", ", "); + + writer.append(" private final JsonType<%s> %sJsonType;", typeString, type.shortName()).eol(); } writer.eol(); diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java index 1d78d70ab..7346df625 100644 --- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java +++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java @@ -21,7 +21,13 @@ class ControllerWriter extends BaseControllerWriter { if (useJsonB) { reader.addImportType("io.avaje.jsonb.Jsonb"); reader.addImportType("io.avaje.jsonb.JsonType"); + reader.addImportType("io.avaje.jsonb.Types"); this.jsonTypes = JsonBUtil.jsonTypes(reader); + jsonTypes.values().stream() + .map(UType::allTypes) + .flatMap(List::stream) + .filter(s -> !s.contains("java.lang")) + .forEach(reader::addImportType); } else { this.jsonTypes = Map.of(); } @@ -87,7 +93,9 @@ private void writeClassStart() { writer.append(" private final Validator validator;").eol(); } for (final UType type : jsonTypes.values()) { - writer.append(" private final JsonType<%s> %sJsonType;", PrimitiveUtil.wrap(type.full()), type.shortName()).eol(); + final var typeString = PrimitiveUtil.wrap(type.shortType()).replace(",", ", "); + + writer.append(" private final JsonType<%s> %sJsonType;", typeString, type.shortName()).eol(); } writer.eol(); From b2dc32feabb1af5122e4aace7c55d740b8b362d3 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Wed, 28 Dec 2022 15:45:07 -0500 Subject: [PATCH 0426/1323] add support for Jsonb generics --- http-client/client/pom.xml | 10 ++-- .../io/avaje/http/client/BodyAdapter.java | 19 ++++++++ .../avaje/http/client/DHttpClientContext.java | 14 ++++++ .../avaje/http/client/DHttpClientRequest.java | 28 ++++++++++- .../avaje/http/client/HttpClientResponse.java | 47 +++++++++++++++++++ .../avaje/http/client/JsonbBodyAdapter.java | 30 ++++++++---- .../http/client/HelloControllerTest.java | 2 +- 7 files changed, 135 insertions(+), 15 deletions(-) diff --git a/http-client/client/pom.xml b/http-client/client/pom.xml index bf5c54f9b..cb428658d 100644 --- a/http-client/client/pom.xml +++ b/http-client/client/pom.xml @@ -39,14 +39,14 @@ io.avaje avaje-jsonb - 1.0-RC1 + 1.1-RC2 true io.avaje avaje-inject - 8.6 + 8.10 true @@ -76,14 +76,14 @@ io.javalin javalin - 4.1.1 + 5.2.0 test io.avaje avaje-http-api - 1.16 + 1.20 test @@ -125,7 +125,7 @@ io.avaje avaje-inject-generator - 8.6 + 8.10 diff --git a/http-client/client/src/main/java/io/avaje/http/client/BodyAdapter.java b/http-client/client/src/main/java/io/avaje/http/client/BodyAdapter.java index 3c0ffa4ea..012e50349 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/BodyAdapter.java +++ b/http-client/client/src/main/java/io/avaje/http/client/BodyAdapter.java @@ -1,5 +1,6 @@ package io.avaje.http.client; +import java.lang.reflect.ParameterizedType; import java.util.List; /** @@ -23,6 +24,16 @@ public interface BodyAdapter { */ BodyReader beanReader(Class type); + /** + * Return a BodyReader to read response content and convert to a bean. + * + * @param type The bean type to convert the content to. + */ + default BodyReader beanReader(ParameterizedType type) { + throw new UnsupportedOperationException("Parameterized types not supported for this adapter"); + } + + /** * Return a BodyReader to read response content and convert to a list of beans. * @@ -30,4 +41,12 @@ public interface BodyAdapter { */ BodyReader> listReader(Class type); + /** + * Return a BodyReader to read response content and convert to a list of beans. + * + * @param type The bean type to convert the content to. + */ + default BodyReader> listReader(ParameterizedType type) { + throw new UnsupportedOperationException("Parameterized types not supported for this adapter"); + } } diff --git a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContext.java b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContext.java index afa764f29..d2c1064ed 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContext.java +++ b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContext.java @@ -2,6 +2,7 @@ import java.io.IOException; import java.lang.reflect.Constructor; +import java.lang.reflect.ParameterizedType; import java.net.http.HttpClient; import java.net.http.HttpHeaders; import java.net.http.HttpRequest; @@ -273,6 +274,10 @@ BodyReader beanReader(Class cls) { return bodyAdapter.beanReader(cls); } + BodyReader beanReader(ParameterizedType cls) { + return bodyAdapter.beanReader(cls); + } + T readBean(Class cls, BodyContent content) { return bodyAdapter.beanReader(cls).read(content); } @@ -281,6 +286,15 @@ List readList(Class cls, BodyContent content) { return bodyAdapter.listReader(cls).read(content); } + @SuppressWarnings("unchecked") + T readBean(ParameterizedType cls, BodyContent content) { + return (T) bodyAdapter.beanReader(cls).read(content); + } + + List readList(ParameterizedType cls, BodyContent content) { + return (List) bodyAdapter.listReader(cls).read(content); + } + void afterResponse(DHttpClientRequest request) { metricResTotal.add(1); metricResMicros.add(request.responseTimeMicros()); diff --git a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java index 8d7fed754..5fc3e6c59 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java +++ b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java @@ -3,6 +3,7 @@ import javax.net.ssl.SSLSession; import java.io.FileNotFoundException; import java.io.InputStream; +import java.lang.reflect.ParameterizedType; import java.net.URI; import java.net.URLEncoder; import java.net.http.HttpClient; @@ -433,7 +434,7 @@ public List list(Class cls) { readResponseContent(); return context.readList(cls, encodedResponseBody); } - + @Override public Stream stream(Class cls) { final HttpResponse> res = handler(HttpResponse.BodyHandlers.ofLines()); @@ -445,6 +446,31 @@ public Stream stream(Class cls) { return res.body().map(bodyReader::readBody); } + + @Override + public T bean(ParameterizedType cls) { + readResponseContent(); + return context.readBean(cls, encodedResponseBody); + } + + @Override + public List list(ParameterizedType cls) { + readResponseContent(); + return context.readList(cls, encodedResponseBody); + } + + + @Override + public Stream stream(ParameterizedType cls) { + final HttpResponse> res = handler(HttpResponse.BodyHandlers.ofLines()); + this.httpResponse = res; + if (res.statusCode() >= 300) { + throw new HttpException(res, context); + } + final BodyReader bodyReader = context.beanReader(cls); + return res.body().map(bodyReader::readBody); + } + @Override public HttpResponse handler(HttpResponse.BodyHandler responseHandler) { final HttpResponse response = sendWith(responseHandler); diff --git a/http-client/client/src/main/java/io/avaje/http/client/HttpClientResponse.java b/http-client/client/src/main/java/io/avaje/http/client/HttpClientResponse.java index 10c2d82e4..13f4e6537 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/HttpClientResponse.java +++ b/http-client/client/src/main/java/io/avaje/http/client/HttpClientResponse.java @@ -1,6 +1,7 @@ package io.avaje.http.client; import java.io.InputStream; +import java.lang.reflect.ParameterizedType; import java.net.http.HttpResponse; import java.nio.file.Path; import java.util.List; @@ -85,6 +86,7 @@ public interface HttpClientResponse { */ List list(Class type); + /** * Return the response as a stream of beans. *

@@ -106,6 +108,51 @@ public interface HttpClientResponse { */ Stream stream(Class type); + /** + * Return the response as a single bean. + *

+ * If the HTTP statusCode is not in the 2XX range a HttpException is throw which contains + * the HttpResponse. This is the cause in the CompletionException. + * + * @param type The parameterized type of the bean to convert the response content into. + * @return The bean the response is converted into. + * @throws HttpException when the response has error status codes + */ + T bean(ParameterizedType type); + + /** + * Return the response as a list of beans. + *

+ * If the HTTP statusCode is not in the 2XX range a HttpException is throw which contains + * the HttpResponse. This is the cause in the CompletionException. + * + * @param type The parameterized type of the bean to convert the response content into. + * @return The list of beans the response is converted into. + * @throws HttpException when the response has error status codes + */ + List list(ParameterizedType type); + + /** + * Return the response as a stream of beans. + *

+ * Typically the response is expected to be {@literal application/x-json-stream} + * newline delimited json payload. + *

+ * Note that for this stream request the response content is not deemed + * 'loggable' by avaje-http-client. This is because the entire response + * may not be available at the time of the callback. As such {@link RequestLogger} + * will not include response content when logging stream request/response + *

+ * If the HTTP statusCode is not in the 2XX range a HttpException is throw which contains + * the HttpResponse. This is the cause in the CompletionException. + * + * @param type The parameterized type of the bean to convert the response content into. + * @return The stream of beans from the response + * @throws HttpException when the response has error status codes + */ + Stream stream(ParameterizedType type); + + /** * Return the response with check for 200 range status code. *

diff --git a/http-client/client/src/main/java/io/avaje/http/client/JsonbBodyAdapter.java b/http-client/client/src/main/java/io/avaje/http/client/JsonbBodyAdapter.java index b6780724f..610c87720 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/JsonbBodyAdapter.java +++ b/http-client/client/src/main/java/io/avaje/http/client/JsonbBodyAdapter.java @@ -1,13 +1,15 @@ package io.avaje.http.client; -import io.avaje.jsonb.JsonType; -import io.avaje.jsonb.Jsonb; - +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; import java.util.List; import java.util.concurrent.ConcurrentHashMap; +import io.avaje.jsonb.JsonType; +import io.avaje.jsonb.Jsonb; + /** - * avaje jsonb BodyAdapter to read and write beans as JSON. + * Avaje Jsonb BodyAdapter to read and write beans as JSON. * *

{@code
  *
@@ -21,9 +23,9 @@
 public final class JsonbBodyAdapter implements BodyAdapter {
 
   private final Jsonb jsonb;
-  private final ConcurrentHashMap, BodyWriter> beanWriterCache = new ConcurrentHashMap<>();
-  private final ConcurrentHashMap, BodyReader> beanReaderCache = new ConcurrentHashMap<>();
-  private final ConcurrentHashMap, BodyReader> listReaderCache = new ConcurrentHashMap<>();
+  private final ConcurrentHashMap> beanWriterCache = new ConcurrentHashMap<>();
+  private final ConcurrentHashMap> beanReaderCache = new ConcurrentHashMap<>();
+  private final ConcurrentHashMap> listReaderCache = new ConcurrentHashMap<>();
 
   /**
    * Create passing the Jsonb to use.
@@ -36,7 +38,7 @@ public JsonbBodyAdapter(Jsonb jsonb) {
    * Create with a default Jsonb that allows unknown properties.
    */
   public JsonbBodyAdapter() {
-    this.jsonb = Jsonb.newBuilder().build();
+    this.jsonb = Jsonb.builder().build();
   }
 
   @SuppressWarnings("unchecked")
@@ -51,6 +53,18 @@ public  BodyReader beanReader(Class cls) {
     return (BodyReader) beanReaderCache.computeIfAbsent(cls, aClass -> new JReader<>(jsonb.type(cls)));
   }
 
+  @SuppressWarnings("unchecked")
+  @Override
+  public  BodyReader beanReader(ParameterizedType cls) {
+    return (BodyReader) beanReaderCache.computeIfAbsent(cls, aClass -> new JReader<>(jsonb.type(cls)));
+  }
+
+  @SuppressWarnings("unchecked")
+  @Override
+  public  BodyReader> listReader(ParameterizedType cls) {
+    return (BodyReader>) listReaderCache.computeIfAbsent(cls, aClass -> new JReader<>(jsonb.type(cls).list()));
+  }
+
   @SuppressWarnings("unchecked")
   @Override
   public  BodyReader> listReader(Class cls) {
diff --git a/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java b/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java
index 516b11843..6b308add2 100644
--- a/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java
+++ b/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java
@@ -394,7 +394,7 @@ void get_notFound() {
     final HttpResponse hres = request.GET().asString();
 
     assertThat(hres.statusCode()).isEqualTo(404);
-    assertThat(hres.body()).contains("Not found");
+    assertThat(hres.body()).contains("Not Found");
     HttpClientContext.Metrics metrics = clientContext.metrics(true);
     assertThat(metrics.totalCount()).isEqualTo(1);
     assertThat(metrics.errorCount()).isEqualTo(1);

From 328c7cbfb0e69a0683896105159120f758890c85 Mon Sep 17 00:00:00 2001
From: Josiah Noel <32279667+SentryMan@users.noreply.github.com>
Date: Wed, 28 Dec 2022 15:58:27 -0500
Subject: [PATCH 0427/1323] I was redundant

---
 .../io/avaje/http/generator/core/UType.java     | 17 +----------------
 .../generator/javalin/ControllerWriter.java     |  7 +++----
 .../helidon/nima/ControllerWriter.java          |  6 +++---
 3 files changed, 7 insertions(+), 23 deletions(-)

diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java
index d5fc543ab..5ba2f424e 100644
--- a/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java
+++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java
@@ -40,12 +40,6 @@ static UType parse(TypeMirror type) {
   default String param0() {
     return null;
   }
-  /**
-   * Return all types associated with this Utype.
-   */
-  default List allTypes() {
-    return List.of();
-  }
 
   /**
    * Return the second generic parameter.
@@ -112,7 +106,7 @@ public String full() {
 
     @Override
     public Set importTypes() {
-      return Collections.singleton(rawType);
+      return rawType.startsWith("java.lang.") ? Set.of() : Collections.singleton(rawType);
     }
 
     @Override
@@ -130,10 +124,6 @@ public String mainType() {
       return rawType;
     }
 
-    @Override
-    public List allTypes() {
-      return List.of(rawType);
-    }
   }
 
   /**
@@ -212,11 +202,6 @@ public String mainType() {
       return allTypes.isEmpty() ? null : allTypes.get(0);
     }
 
-    @Override
-    public List allTypes() {
-      return allTypes;
-    }
-
     @Override
     public String param0() {
       return allTypes.size() < 2 ? null : allTypes.get(1);
diff --git a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java
index 2ecc9a753..e388f5f20 100644
--- a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java
+++ b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java
@@ -1,8 +1,8 @@
 package io.avaje.http.generator.javalin;
 
 import java.io.IOException;
-import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
 import io.avaje.http.generator.core.BaseControllerWriter;
 import io.avaje.http.generator.core.Constants;
@@ -32,9 +32,8 @@ class ControllerWriter extends BaseControllerWriter {
       reader.addImportType("io.avaje.jsonb.Types");
       this.jsonTypes = JsonBUtil.jsonTypes(reader);
       jsonTypes.values().stream()
-          .map(UType::allTypes)
-          .flatMap(List::stream)
-          .filter(s -> !s.contains("java.lang"))
+          .map(UType::importTypes)
+          .flatMap(Set::stream)
           .forEach(reader::addImportType);
     } else {
       this.jsonTypes = Map.of();
diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java
index 7346df625..e67fde8a4 100644
--- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java
+++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java
@@ -5,6 +5,7 @@
 import java.io.IOException;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
 /**
  * Write Helidon specific web route adapter (a Helidon Service).
@@ -24,9 +25,8 @@ class ControllerWriter extends BaseControllerWriter {
       reader.addImportType("io.avaje.jsonb.Types");
       this.jsonTypes = JsonBUtil.jsonTypes(reader);
       jsonTypes.values().stream()
-          .map(UType::allTypes)
-          .flatMap(List::stream)
-          .filter(s -> !s.contains("java.lang"))
+          .map(UType::importTypes)
+          .flatMap(Set::stream)
           .forEach(reader::addImportType);
     } else {
       this.jsonTypes = Map.of();

From c243fc56e0063eb8ead0d54dfec7dae82d37519c Mon Sep 17 00:00:00 2001
From: Josiah Noel <32279667+SentryMan@users.noreply.github.com>
Date: Wed, 28 Dec 2022 16:12:54 -0500
Subject: [PATCH 0428/1323] handle array

---
 .../io/avaje/http/generator/client/ClientMethodWriter.java | 7 +------
 .../main/java/io/avaje/http/generator/core/JsonBUtil.java  | 2 +-
 .../src/main/java/io/avaje/http/generator/core/UType.java  | 6 ++++--
 .../io/avaje/http/generator/javalin/ControllerWriter.java  | 3 +--
 .../http/generator/helidon/nima/ControllerWriter.java      | 3 +--
 5 files changed, 8 insertions(+), 13 deletions(-)

diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java
index 5c0abe1d2..0f6b782a4 100644
--- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java
+++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java
@@ -34,12 +34,7 @@ class ClientMethodWriter {
   void addImportTypes(ControllerReader reader) {
     reader.addImportTypes(returnType.importTypes());
     for (final MethodParam param : method.params()) {
-      final var type = param.utype();
-      final var type0 = type.param0();
-      final var type1 = type.param1();
-      reader.addImportType(type.mainType().replace("[]", ""));
-      if (type0 != null) reader.addImportType(type0.replace("[]", ""));
-      if (type1 != null) reader.addImportType(type1.replace("[]", ""));
+      reader.addImportTypes(param.utype().importTypes());
     }
   }
 
diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java
index c28ec8977..4b367a9ee 100644
--- a/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java
+++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java
@@ -60,7 +60,7 @@ public static void writeJsonbType(UType type, Append writer) {
                   "Only java.util Map, Set and List are supported JsonB Controller Collection Types");
 
             final var params =
-                type.allTypes().stream().skip(1).collect(Collectors.joining(".class, ")) + ".class";
+                type.importTypes().stream().skip(1).collect(Collectors.joining(".class, ")) + ".class";
 
             writer.append("Types.newParameterizedType(%s.class, %s))", type.mainType(), params);
           }
diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java
index 5ba2f424e..9d26e5ac8 100644
--- a/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java
+++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java
@@ -106,7 +106,9 @@ public String full() {
 
     @Override
     public Set importTypes() {
-      return rawType.startsWith("java.lang.") ? Set.of() : Collections.singleton(rawType);
+      return rawType.startsWith("java.lang.") && rawType.indexOf('.') > -1
+          ? Set.of()
+          : Collections.singleton(rawType.replace("[]", ""));
     }
 
     @Override
@@ -164,7 +166,7 @@ public Set importTypes() {
       Set set = new LinkedHashSet<>();
       for (String type : allTypes) {
         if (!type.startsWith("java.lang.") && type.indexOf('.') > -1) {
-          set.add(type);
+          set.add(type.replace("[]", ""));
         }
       }
       return set;
diff --git a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java
index e388f5f20..a437c3311 100644
--- a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java
+++ b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java
@@ -33,8 +33,7 @@ class ControllerWriter extends BaseControllerWriter {
       this.jsonTypes = JsonBUtil.jsonTypes(reader);
       jsonTypes.values().stream()
           .map(UType::importTypes)
-          .flatMap(Set::stream)
-          .forEach(reader::addImportType);
+          .forEach(reader::addImportTypes);
     } else {
       this.jsonTypes = Map.of();
     }
diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java
index e67fde8a4..03118e01e 100644
--- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java
+++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java
@@ -26,8 +26,7 @@ class ControllerWriter extends BaseControllerWriter {
       this.jsonTypes = JsonBUtil.jsonTypes(reader);
       jsonTypes.values().stream()
           .map(UType::importTypes)
-          .flatMap(Set::stream)
-          .forEach(reader::addImportType);
+          .forEach(reader::addImportTypes);
     } else {
       this.jsonTypes = Map.of();
     }

From a1550613996a8b1e412c6ebe621b2e5f284df631 Mon Sep 17 00:00:00 2001
From: Josiah Noel <32279667+SentryMan@users.noreply.github.com>
Date: Wed, 28 Dec 2022 16:13:54 -0500
Subject: [PATCH 0429/1323] Update ControllerWriter.java

---
 .../java/io/avaje/http/generator/javalin/ControllerWriter.java   | 1 -
 1 file changed, 1 deletion(-)

diff --git a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java
index a437c3311..957c293fb 100644
--- a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java
+++ b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java
@@ -2,7 +2,6 @@
 
 import java.io.IOException;
 import java.util.Map;
-import java.util.Set;
 
 import io.avaje.http.generator.core.BaseControllerWriter;
 import io.avaje.http.generator.core.Constants;

From b7cbff7a904e77a12682295330b2d5da4b1ae356 Mon Sep 17 00:00:00 2001
From: Josiah Noel <32279667+SentryMan@users.noreply.github.com>
Date: Wed, 28 Dec 2022 19:53:09 -0500
Subject: [PATCH 0430/1323] Update BodyAdapter.java

---
 .../client/src/main/java/io/avaje/http/client/BodyAdapter.java  | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/http-client/client/src/main/java/io/avaje/http/client/BodyAdapter.java b/http-client/client/src/main/java/io/avaje/http/client/BodyAdapter.java
index 012e50349..33e82f81a 100644
--- a/http-client/client/src/main/java/io/avaje/http/client/BodyAdapter.java
+++ b/http-client/client/src/main/java/io/avaje/http/client/BodyAdapter.java
@@ -47,6 +47,6 @@ default  BodyReader beanReader(ParameterizedType type) {
    * @param type The bean type to convert the content to.
    */
   default  BodyReader> listReader(ParameterizedType type) {
-    throw new UnsupportedOperationException("Parameterized types not supported for this adapter");
+    throw new UnsupportedOperationException("Parameterized types not supported for this Body Adapter");
   }
 }

From 5fa229753b63803e70d22672ee9679ee0b678474 Mon Sep 17 00:00:00 2001
From: Josiah Noel <32279667+SentryMan@users.noreply.github.com>
Date: Wed, 28 Dec 2022 19:59:12 -0500
Subject: [PATCH 0431/1323] client processor jsonb generics

---
 .../generator/client/ClientMethodWriter.java  | 55 +++++++++++++------
 .../generator/client/ClientProcessor.java     | 17 +++++-
 .../http/generator/client/ClientWriter.java   |  7 ++-
 .../avaje/http/generator/core/JsonBUtil.java  | 33 ++++++++---
 .../io/avaje/http/generator/core/UType.java   | 37 +++++++++++--
 5 files changed, 115 insertions(+), 34 deletions(-)

diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java
index 0f6b782a4..4e48ab23c 100644
--- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java
+++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java
@@ -4,6 +4,7 @@
 
 import javax.lang.model.element.TypeElement;
 import java.util.Set;
+import java.util.stream.Collectors;
 
 /**
  * Write code to register Web route for a given controller method.
@@ -22,13 +23,15 @@ class ClientMethodWriter {
   private final UType returnType;
   private MethodParam bodyHandlerParam;
   private String methodGenericParams = "";
+  private final boolean useJsonb;
 
-  ClientMethodWriter(MethodReader method, Append writer, ProcessingContext ctx) {
+  ClientMethodWriter(MethodReader method, Append writer, ProcessingContext ctx, boolean useJsonb) {
     this.method = method;
     this.writer = writer;
     this.webMethod = method.webMethod();
     this.ctx = ctx;
     this.returnType = Util.parseType(method.returnType());
+    this.useJsonb = useJsonb;
   }
 
   void addImportTypes(ControllerReader reader) {
@@ -111,37 +114,55 @@ private void writeEnd() {
 
   private void writeSyncResponse() {
     writer.append("      ");
-    String type0 = returnType.mainType();
-    String type1 = returnType.param0();
-    writeResponse(type0, type1);
+    writeResponse(returnType);
   }
 
   private void writeAsyncResponse() {
     writer.append("      .async()");
-    String type0 = returnType.param0();
-    String type1 = returnType.param1();
-    writeResponse(type0, type1);
+    writeResponse(UType.parse(returnType.param0()));
   }
 
   private void writeCallResponse() {
     writer.append("      .call()");
-    String type0 = returnType.param0();
-    String type1 = returnType.param1();
-    writeResponse(type0, type1);
+    writeResponse(UType.parse(returnType.param0()));
   }
 
-  private void writeResponse(String type0, String type1) {
-    if (isList(type0)) {
-      writer.append(".list(%s.class);", Util.shortName(type1)).eol();
-    } else if (isStream(type0)) {
-      writer.append(".stream(%s.class);", Util.shortName(type1)).eol();
-    } else if (isHttpResponse(type0)){
+  private void writeResponse(UType type) {
+    final var mainType = type.mainType();
+    final var param1 = type.paramRaw();
+    if (isList(mainType)) {
+      writer.append(".list(");
+      writeGeneric(UType.parse(param1));
+    } else if (isStream(mainType)) {
+      writer.append(".stream(");
+      writeGeneric(UType.parse(param1));
+    } else if (isHttpResponse(mainType)) {
       writeWithHandler();
     } else {
-      writer.append(".bean(%s.class);", Util.shortName(type0)).eol();
+      writer.append(".bean(", Util.shortName(mainType)).eol();
+      writeGeneric(type);
     }
   }
 
+  void writeGeneric(UType type) {
+    if (useJsonb && type.isGeneric()) {
+      final var params =
+          type.importTypes().stream()
+                  .skip(1)
+                  .map(Util::shortName)
+                  .collect(Collectors.joining(".class, "))
+              + ".class";
+
+      writer.append(
+          "Types.newParameterizedType(%s.class, %s)", Util.shortName(type.mainType()), params);
+    } else {
+      writer.append("%s.class", Util.shortName(type.mainType()));
+    }
+    writer.append(");");
+
+    writer.eol();
+  }
+
   private void writeWithHandler() {
     if (bodyHandlerParam != null) {
       writer.append(".handler(%s);", bodyHandlerParam.name()).eol();
diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java
index 0a8b68605..14f297d03 100644
--- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java
+++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java
@@ -27,6 +27,21 @@ public class ClientProcessor extends AbstractProcessor {
 
   protected ProcessingContext ctx;
 
+  private boolean useJsonB;
+
+  public ClientProcessor() {
+    try {
+      Class.forName("io.avaje.jsonb.Jsonb");
+      this.useJsonB = true;
+    } catch (final ClassNotFoundException e) {
+      this.useJsonB = false;
+    }
+  }
+
+  public ClientProcessor(boolean useJsonb) {
+    useJsonB = useJsonb;
+  }
+
   @Override
   public SourceVersion getSupportedSourceVersion() {
     return SourceVersion.latest();
@@ -107,7 +122,7 @@ private void writeClient(Element controller) {
   }
 
   protected String writeClientAdapter(ProcessingContext ctx, ControllerReader reader) throws IOException {
-    return new ClientWriter(reader, ctx).write();
+    return new ClientWriter(reader, ctx,useJsonB).write();
   }
 
 }
diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientWriter.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientWriter.java
index 26dd12a6a..6f465bd73 100644
--- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientWriter.java
+++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientWriter.java
@@ -21,12 +21,15 @@ class ClientWriter extends BaseControllerWriter {
   private static final String SUFFIX = "HttpClient";
 
   private final List methodList = new ArrayList<>();
+  private final boolean useJsonb;
 
-  ClientWriter(ControllerReader reader, ProcessingContext ctx) throws IOException {
+  ClientWriter(ControllerReader reader, ProcessingContext ctx, boolean useJsonB) throws IOException {
     super(reader, ctx, SUFFIX);
     reader.addImportType(HTTP_CLIENT_CONTEXT);
     reader.addImportType(HTTP_API_PROVIDER);
+    this.useJsonb = useJsonB;
     readMethods();
+    if (useJsonB) reader.addImportType("io.avaje.jsonb.Types");
   }
 
   @Override
@@ -38,7 +41,7 @@ protected String initPackageName(String originName) {
   private void readMethods() {
     for (MethodReader method : reader.methods()) {
       if (method.isWebMethod()) {
-        ClientMethodWriter methodWriter = new ClientMethodWriter(method, writer, ctx);
+        final var methodWriter = new ClientMethodWriter(method, writer, ctx, useJsonb);
         methodWriter.addImportTypes(reader);
         methodList.add(methodWriter);
       }
diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java
index 4b367a9ee..a37eb443a 100644
--- a/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java
+++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java
@@ -41,31 +41,46 @@ public static void writeJsonbType(UType type, Append writer) {
 
     writer.append("    this.%sJsonType = jsonB.type(", type.shortName());
     if (!type.isGeneric()) {
-      writer.append("%s.class)", PrimitiveUtil.wrap(type.full()));
+      writer.append("%s.class)", Util.shortName(PrimitiveUtil.wrap(type.full())));
     } else {
       switch (type.mainType()) {
         case "java.util.List":
-          writer.append("%s.class).list()", type.param0());
+          writeType(UType.parse(type.paramRaw()), writer);
+          writer.append(".list()");
           break;
         case "java.util.Set":
-          writer.append("%s.class).set()", type.param0());
+          writeType(UType.parse(type.paramRaw()), writer);
+          writer.append(".set()");
           break;
         case "java.util.Map":
-          writer.append("%s.class).map()", type.param1());
+          writeType(UType.parse(type.paramRaw()), writer);
+          writer.append(".map()");
           break;
         default:
           {
             if (type.mainType().contains("java.util"))
               throw new UnsupportedOperationException(
                   "Only java.util Map, Set and List are supported JsonB Controller Collection Types");
-
-            final var params =
-                type.importTypes().stream().skip(1).collect(Collectors.joining(".class, ")) + ".class";
-
-            writer.append("Types.newParameterizedType(%s.class, %s))", type.mainType(), params);
+            writeType(type, writer);
           }
       }
     }
     writer.append(";").eol();
   }
+
+  static void writeType(UType type, Append writer) {
+    if (type.isGeneric()) {
+      final var params =
+          type.importTypes().stream()
+                  .skip(1)
+                  .map(Util::shortName)
+                  .collect(Collectors.joining(".class, "))
+              + ".class";
+
+      writer.append(
+          "Types.newParameterizedType(%s.class, %s))", Util.shortName(type.mainType()), params);
+    } else {
+      writer.append("%s.class)", Util.shortName(type.mainType()));
+    }
+  }
 }
diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java
index 9d26e5ac8..b2ba8b354 100644
--- a/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java
+++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java
@@ -48,9 +48,12 @@ default String param1() {
     return null;
   }
 
-  /**
-   * Return the raw type.
-   */
+  /** Return the raw generic parameter if this UType is a Collection. */
+  default String paramRaw() {
+    return null;
+  }
+
+  /** Return the raw type. */
   String full();
 
   default boolean isGeneric() {
@@ -125,7 +128,6 @@ public String shortName() {
     public String mainType() {
       return rawType;
     }
-
   }
 
   /**
@@ -133,15 +135,35 @@ public String mainType() {
    */
   class Generic implements UType {
     final String rawType;
+    final String rawParamType;
     final List allTypes;
     final String shortRawType;
     final String shortName;
 
     Generic(String rawTypeInput) {
-      this.rawType = rawTypeInput.replace(" ",""); // trim whitespace
+      this.rawType = rawTypeInput.replace(" ", ""); // trim whitespace
       this.allTypes = Arrays.asList(rawType.split("[<|>|,]"));
       this.shortRawType = shortRawType(rawType, allTypes);
       this.shortName = Util.name(shortRawType);
+      this.rawParamType = extractCollectionParam();
+    }
+
+    private String extractCollectionParam() {
+
+      switch (mainType()) {
+        case "java.util.Set":
+        case "java.util.Stream":
+        case "java.util.List":
+          var first = rawType.indexOf("<") + 1;
+          var end = rawType.lastIndexOf(">");
+          return rawType.substring(first, end);
+        case "java.util.Map":
+          first = rawType.indexOf(",") + 1;
+          end = rawType.lastIndexOf(">");
+          return rawType.substring(first, end);
+        default:
+          return rawType;
+      }
     }
 
     private String shortRawType(String rawType, List allTypes) {
@@ -213,5 +235,10 @@ public String param0() {
     public String param1() {
       return allTypes.size() < 3 ? null : allTypes.get(2);
     }
+
+    @Override
+    public String paramRaw() {
+      return rawParamType;
+    }
   }
 }

From daa28670f12e116d2f7679aac249991a373d34e1 Mon Sep 17 00:00:00 2001
From: Josiah Noel <32279667+SentryMan@users.noreply.github.com>
Date: Wed, 28 Dec 2022 20:01:57 -0500
Subject: [PATCH 0432/1323] Revert "Update BodyAdapter.java"

This reverts commit b7cbff7a904e77a12682295330b2d5da4b1ae356.
---
 .../client/src/main/java/io/avaje/http/client/BodyAdapter.java  | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/http-client/client/src/main/java/io/avaje/http/client/BodyAdapter.java b/http-client/client/src/main/java/io/avaje/http/client/BodyAdapter.java
index 33e82f81a..012e50349 100644
--- a/http-client/client/src/main/java/io/avaje/http/client/BodyAdapter.java
+++ b/http-client/client/src/main/java/io/avaje/http/client/BodyAdapter.java
@@ -47,6 +47,6 @@ default  BodyReader beanReader(ParameterizedType type) {
    * @param type The bean type to convert the content to.
    */
   default  BodyReader> listReader(ParameterizedType type) {
-    throw new UnsupportedOperationException("Parameterized types not supported for this Body Adapter");
+    throw new UnsupportedOperationException("Parameterized types not supported for this adapter");
   }
 }

From c5963d3837c59f75845e6091f67cdda9dd1f56cb Mon Sep 17 00:00:00 2001
From: Josiah Noel <32279667+SentryMan@users.noreply.github.com>
Date: Wed, 28 Dec 2022 20:38:29 -0500
Subject: [PATCH 0433/1323] directly get utype

---
 .../io/avaje/http/generator/core/JsonBUtil.java     |  6 +++---
 .../java/io/avaje/http/generator/core/UType.java    | 13 ++++++++-----
 tests/test-client/pom.xml                           |  2 +-
 3 files changed, 12 insertions(+), 9 deletions(-)

diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java
index a37eb443a..13c043a05 100644
--- a/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java
+++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java
@@ -45,15 +45,15 @@ public static void writeJsonbType(UType type, Append writer) {
     } else {
       switch (type.mainType()) {
         case "java.util.List":
-          writeType(UType.parse(type.paramRaw()), writer);
+          writeType(type.paramRaw(), writer);
           writer.append(".list()");
           break;
         case "java.util.Set":
-          writeType(UType.parse(type.paramRaw()), writer);
+          writeType(type.paramRaw(), writer);
           writer.append(".set()");
           break;
         case "java.util.Map":
-          writeType(UType.parse(type.paramRaw()), writer);
+          writeType(type.paramRaw(), writer);
           writer.append(".map()");
           break;
         default:
diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java
index b2ba8b354..8caa66bba 100644
--- a/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java
+++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java
@@ -135,7 +135,7 @@ public String mainType() {
    */
   class Generic implements UType {
     final String rawType;
-    final String rawParamType;
+    final UType rawParamType;
     final List allTypes;
     final String shortRawType;
     final String shortName;
@@ -145,15 +145,18 @@ class Generic implements UType {
       this.allTypes = Arrays.asList(rawType.split("[<|>|,]"));
       this.shortRawType = shortRawType(rawType, allTypes);
       this.shortName = Util.name(shortRawType);
-      this.rawParamType = extractCollectionParam();
+      final var paramTypeString = extractRawParam();
+      this.rawParamType = paramTypeString != null ? UType.parse(paramTypeString) : null;
     }
 
-    private String extractCollectionParam() {
+    private String extractRawParam() {
 
       switch (mainType()) {
         case "java.util.Set":
         case "java.util.Stream":
         case "java.util.List":
+        case "java.util.concurrent.CompletableFuture":
+        case "io.avaje.http.client.HttpCall":
           var first = rawType.indexOf("<") + 1;
           var end = rawType.lastIndexOf(">");
           return rawType.substring(first, end);
@@ -162,7 +165,7 @@ private String extractCollectionParam() {
           end = rawType.lastIndexOf(">");
           return rawType.substring(first, end);
         default:
-          return rawType;
+          return null;
       }
     }
 
@@ -237,7 +240,7 @@ public String param1() {
     }
 
     @Override
-    public String paramRaw() {
+    public UType paramRaw() {
       return rawParamType;
     }
   }
diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml
index 8dc3b7938..9babe4139 100644
--- a/tests/test-client/pom.xml
+++ b/tests/test-client/pom.xml
@@ -30,7 +30,7 @@
     
       io.avaje
       avaje-http-client
-      1.16
+      1.20
     
 
     

From 9eb390d4f9df02bb93eb9fe4e5cd878e504f96db Mon Sep 17 00:00:00 2001
From: Josiah Noel <32279667+SentryMan@users.noreply.github.com>
Date: Wed, 28 Dec 2022 20:39:18 -0500
Subject: [PATCH 0434/1323] I'll do client later

---
 .../generator/client/ClientMethodWriter.java  | 55 ++++++-------------
 .../generator/client/ClientProcessor.java     | 17 +-----
 .../http/generator/client/ClientWriter.java   |  7 +--
 3 files changed, 20 insertions(+), 59 deletions(-)

diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java
index 4e48ab23c..0f6b782a4 100644
--- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java
+++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java
@@ -4,7 +4,6 @@
 
 import javax.lang.model.element.TypeElement;
 import java.util.Set;
-import java.util.stream.Collectors;
 
 /**
  * Write code to register Web route for a given controller method.
@@ -23,15 +22,13 @@ class ClientMethodWriter {
   private final UType returnType;
   private MethodParam bodyHandlerParam;
   private String methodGenericParams = "";
-  private final boolean useJsonb;
 
-  ClientMethodWriter(MethodReader method, Append writer, ProcessingContext ctx, boolean useJsonb) {
+  ClientMethodWriter(MethodReader method, Append writer, ProcessingContext ctx) {
     this.method = method;
     this.writer = writer;
     this.webMethod = method.webMethod();
     this.ctx = ctx;
     this.returnType = Util.parseType(method.returnType());
-    this.useJsonb = useJsonb;
   }
 
   void addImportTypes(ControllerReader reader) {
@@ -114,55 +111,37 @@ private void writeEnd() {
 
   private void writeSyncResponse() {
     writer.append("      ");
-    writeResponse(returnType);
+    String type0 = returnType.mainType();
+    String type1 = returnType.param0();
+    writeResponse(type0, type1);
   }
 
   private void writeAsyncResponse() {
     writer.append("      .async()");
-    writeResponse(UType.parse(returnType.param0()));
+    String type0 = returnType.param0();
+    String type1 = returnType.param1();
+    writeResponse(type0, type1);
   }
 
   private void writeCallResponse() {
     writer.append("      .call()");
-    writeResponse(UType.parse(returnType.param0()));
+    String type0 = returnType.param0();
+    String type1 = returnType.param1();
+    writeResponse(type0, type1);
   }
 
-  private void writeResponse(UType type) {
-    final var mainType = type.mainType();
-    final var param1 = type.paramRaw();
-    if (isList(mainType)) {
-      writer.append(".list(");
-      writeGeneric(UType.parse(param1));
-    } else if (isStream(mainType)) {
-      writer.append(".stream(");
-      writeGeneric(UType.parse(param1));
-    } else if (isHttpResponse(mainType)) {
+  private void writeResponse(String type0, String type1) {
+    if (isList(type0)) {
+      writer.append(".list(%s.class);", Util.shortName(type1)).eol();
+    } else if (isStream(type0)) {
+      writer.append(".stream(%s.class);", Util.shortName(type1)).eol();
+    } else if (isHttpResponse(type0)){
       writeWithHandler();
     } else {
-      writer.append(".bean(", Util.shortName(mainType)).eol();
-      writeGeneric(type);
+      writer.append(".bean(%s.class);", Util.shortName(type0)).eol();
     }
   }
 
-  void writeGeneric(UType type) {
-    if (useJsonb && type.isGeneric()) {
-      final var params =
-          type.importTypes().stream()
-                  .skip(1)
-                  .map(Util::shortName)
-                  .collect(Collectors.joining(".class, "))
-              + ".class";
-
-      writer.append(
-          "Types.newParameterizedType(%s.class, %s)", Util.shortName(type.mainType()), params);
-    } else {
-      writer.append("%s.class", Util.shortName(type.mainType()));
-    }
-    writer.append(");");
-
-    writer.eol();
-  }
-
   private void writeWithHandler() {
     if (bodyHandlerParam != null) {
       writer.append(".handler(%s);", bodyHandlerParam.name()).eol();
diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java
index 14f297d03..0a8b68605 100644
--- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java
+++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java
@@ -27,21 +27,6 @@ public class ClientProcessor extends AbstractProcessor {
 
   protected ProcessingContext ctx;
 
-  private boolean useJsonB;
-
-  public ClientProcessor() {
-    try {
-      Class.forName("io.avaje.jsonb.Jsonb");
-      this.useJsonB = true;
-    } catch (final ClassNotFoundException e) {
-      this.useJsonB = false;
-    }
-  }
-
-  public ClientProcessor(boolean useJsonb) {
-    useJsonB = useJsonb;
-  }
-
   @Override
   public SourceVersion getSupportedSourceVersion() {
     return SourceVersion.latest();
@@ -122,7 +107,7 @@ private void writeClient(Element controller) {
   }
 
   protected String writeClientAdapter(ProcessingContext ctx, ControllerReader reader) throws IOException {
-    return new ClientWriter(reader, ctx,useJsonB).write();
+    return new ClientWriter(reader, ctx).write();
   }
 
 }
diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientWriter.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientWriter.java
index 6f465bd73..26dd12a6a 100644
--- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientWriter.java
+++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientWriter.java
@@ -21,15 +21,12 @@ class ClientWriter extends BaseControllerWriter {
   private static final String SUFFIX = "HttpClient";
 
   private final List methodList = new ArrayList<>();
-  private final boolean useJsonb;
 
-  ClientWriter(ControllerReader reader, ProcessingContext ctx, boolean useJsonB) throws IOException {
+  ClientWriter(ControllerReader reader, ProcessingContext ctx) throws IOException {
     super(reader, ctx, SUFFIX);
     reader.addImportType(HTTP_CLIENT_CONTEXT);
     reader.addImportType(HTTP_API_PROVIDER);
-    this.useJsonb = useJsonB;
     readMethods();
-    if (useJsonB) reader.addImportType("io.avaje.jsonb.Types");
   }
 
   @Override
@@ -41,7 +38,7 @@ protected String initPackageName(String originName) {
   private void readMethods() {
     for (MethodReader method : reader.methods()) {
       if (method.isWebMethod()) {
-        final var methodWriter = new ClientMethodWriter(method, writer, ctx, useJsonb);
+        ClientMethodWriter methodWriter = new ClientMethodWriter(method, writer, ctx);
         methodWriter.addImportTypes(reader);
         methodList.add(methodWriter);
       }

From 16efcd9cdfce5dc16079a34fa8ecd6c72c6fa1b7 Mon Sep 17 00:00:00 2001
From: Josiah Noel <32279667+SentryMan@users.noreply.github.com>
Date: Wed, 28 Dec 2022 20:43:47 -0500
Subject: [PATCH 0435/1323] fix tests

---
 .../src/main/java/io/avaje/http/generator/core/UType.java   | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java
index 8caa66bba..929658194 100644
--- a/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java
+++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java
@@ -11,6 +11,10 @@ public interface UType {
   static UType parse(TypeMirror type) {
     return Util.parseType(type);
   }
+  /** Create the UType from the given String. */
+  static UType parse(String type) {
+    return Util.parse(type);
+  }
 
   UType VOID = new VoidType();
 
@@ -49,7 +53,7 @@ default String param1() {
   }
 
   /** Return the raw generic parameter if this UType is a Collection. */
-  default String paramRaw() {
+  default UType paramRaw() {
     return null;
   }
 

From bbb320d7b0b00e5c58feb0f537862127e86518d9 Mon Sep 17 00:00:00 2001
From: Josiah Noel <32279667+SentryMan@users.noreply.github.com>
Date: Wed, 28 Dec 2022 21:52:15 -0500
Subject: [PATCH 0436/1323] heh, forgot about the async and httpcall

---
 .../java/io/avaje/http/client/DHttpAsync.java | 22 ++++++
 .../java/io/avaje/http/client/DHttpCall.java  | 67 +++++++++++++++++--
 .../avaje/http/client/DHttpClientRequest.java | 22 ++++++
 .../avaje/http/client/HttpAsyncResponse.java  | 26 +++++++
 .../avaje/http/client/HttpCallResponse.java   | 25 +++++++
 5 files changed, 156 insertions(+), 6 deletions(-)

diff --git a/http-client/client/src/main/java/io/avaje/http/client/DHttpAsync.java b/http-client/client/src/main/java/io/avaje/http/client/DHttpAsync.java
index 3ab02cb20..770f6d38b 100644
--- a/http-client/client/src/main/java/io/avaje/http/client/DHttpAsync.java
+++ b/http-client/client/src/main/java/io/avaje/http/client/DHttpAsync.java
@@ -1,6 +1,7 @@
 package io.avaje.http.client;
 
 import java.io.InputStream;
+import java.lang.reflect.ParameterizedType;
 import java.net.http.HttpResponse;
 import java.util.List;
 import java.util.concurrent.CompletableFuture;
@@ -78,4 +79,25 @@ public  CompletableFuture> stream(Class type) {
       .performSendAsync(false, HttpResponse.BodyHandlers.ofLines())
       .thenApply(httpResponse -> request.asyncStream(type, httpResponse));
   }
+
+  @Override
+  public  CompletableFuture bean(ParameterizedType type) {
+    return request
+      .performSendAsync(true, HttpResponse.BodyHandlers.ofByteArray())
+      .thenApply(httpResponse -> request.asyncBean(type, httpResponse));
+  }
+
+  @Override
+  public  CompletableFuture> list(ParameterizedType type) {
+    return request
+      .performSendAsync(true, HttpResponse.BodyHandlers.ofByteArray())
+      .thenApply(httpResponse -> request.asyncList(type, httpResponse));
+  }
+
+  @Override
+  public  CompletableFuture> stream(ParameterizedType type) {
+    return request
+      .performSendAsync(false, HttpResponse.BodyHandlers.ofLines())
+      .thenApply(httpResponse -> request.asyncStream(type, httpResponse));
+  }
 }
diff --git a/http-client/client/src/main/java/io/avaje/http/client/DHttpCall.java b/http-client/client/src/main/java/io/avaje/http/client/DHttpCall.java
index 3ee7a8eb0..31c94e97e 100644
--- a/http-client/client/src/main/java/io/avaje/http/client/DHttpCall.java
+++ b/http-client/client/src/main/java/io/avaje/http/client/DHttpCall.java
@@ -1,6 +1,7 @@
 package io.avaje.http.client;
 
 import java.io.InputStream;
+import java.lang.reflect.ParameterizedType;
 import java.net.http.HttpResponse;
 import java.util.List;
 import java.util.concurrent.CompletableFuture;
@@ -64,6 +65,21 @@ public  HttpCall> stream(Class type) {
     return new CallStream<>(type);
   }
 
+  @Override
+  public  HttpCall bean(ParameterizedType type) {
+    return new CallBean<>(type);
+  }
+
+  @Override
+  public  HttpCall> list(ParameterizedType type) {
+    return new CallList<>(type);
+  }
+
+  @Override
+  public  HttpCall> stream(ParameterizedType type) {
+    return new CallStream<>(type);
+  }
+
   private class CallVoid implements HttpCall> {
     @Override
     public HttpResponse execute() {
@@ -132,46 +148,85 @@ public CompletableFuture> async() {
 
   private class CallBean implements HttpCall {
     private final Class type;
+    private final ParameterizedType genericType;
+    private final boolean isGeneric;
+
     CallBean(Class type) {
+      this.isGeneric = false;
       this.type = type;
+      this.genericType = null;
     }
+
+    CallBean(ParameterizedType type) {
+      this.isGeneric = true;
+      this.type = null;
+      this.genericType = type;
+    }
+
     @Override
     public E execute() {
-      return request.bean(type);
+      return isGeneric ? request.bean(genericType) : request.bean(type);
     }
+
     @Override
     public CompletableFuture async() {
-      return request.async().bean(type);
+      return isGeneric ? request.async().bean(genericType) : request.async().bean(type);
     }
   }
 
   private class CallList implements HttpCall> {
     private final Class type;
+    private final ParameterizedType genericType;
+    private final boolean isGeneric;
+
     CallList(Class type) {
+      this.isGeneric = false;
       this.type = type;
+      this.genericType = null;
     }
+
+    CallList(ParameterizedType type) {
+      this.isGeneric = true;
+      this.type = null;
+      this.genericType = type;
+    }
+
     @Override
     public List execute() {
-      return request.list(type);
+      return isGeneric ? request.list(genericType) : request.list(type);
     }
+
     @Override
     public CompletableFuture> async() {
-      return request.async().list(type);
+      return isGeneric ? request.async().list(genericType) : request.async().list(type);
     }
   }
 
   private class CallStream implements HttpCall> {
     private final Class type;
+    private final ParameterizedType genericType;
+    private final boolean isGeneric;
+
     CallStream(Class type) {
+      this.isGeneric = false;
       this.type = type;
+      this.genericType = null;
+    }
+
+    CallStream(ParameterizedType type) {
+      this.isGeneric = true;
+      this.type = null;
+      this.genericType = type;
     }
+
     @Override
     public Stream execute() {
-      return request.stream(type);
+      return isGeneric ? request.stream(genericType) : request.stream(type);
     }
+
     @Override
     public CompletableFuture> async() {
-      return request.async().stream(type);
+      return isGeneric ? request.async().stream(genericType) : request.async().stream(type);
     }
   }
 
diff --git a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java
index 5fc3e6c59..22d885f18 100644
--- a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java
+++ b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java
@@ -532,6 +532,28 @@ protected  Stream asyncStream(Class type, HttpResponse>
     return response.body().map(bodyReader::readBody);
   }
 
+  protected  E asyncBean(ParameterizedType type, HttpResponse response) {
+    afterAsyncEncoded(response);
+    return context.readBean(type, encodedResponseBody);
+  }
+
+  protected  List asyncList(ParameterizedType type, HttpResponse response) {
+    afterAsyncEncoded(response);
+    return context.readList(type, encodedResponseBody);
+  }
+
+  protected  Stream asyncStream(
+      ParameterizedType type, HttpResponse> response) {
+    responseTimeNanos = System.nanoTime() - startAsyncNanos;
+    httpResponse = response;
+    context.afterResponse(this);
+    if (response.statusCode() >= 300) {
+      throw new HttpException(response, context);
+    }
+    final BodyReader bodyReader = context.beanReader(type);
+    return response.body().map(bodyReader::readBody);
+  }
+
   private void afterAsyncEncoded(HttpResponse response) {
     responseTimeNanos = System.nanoTime() - startAsyncNanos;
     httpResponse = response;
diff --git a/http-client/client/src/main/java/io/avaje/http/client/HttpAsyncResponse.java b/http-client/client/src/main/java/io/avaje/http/client/HttpAsyncResponse.java
index 45cea96b5..7e6dee89d 100644
--- a/http-client/client/src/main/java/io/avaje/http/client/HttpAsyncResponse.java
+++ b/http-client/client/src/main/java/io/avaje/http/client/HttpAsyncResponse.java
@@ -1,6 +1,7 @@
 package io.avaje.http.client;
 
 import java.io.InputStream;
+import java.lang.reflect.ParameterizedType;
 import java.net.http.HttpResponse;
 import java.util.List;
 import java.util.concurrent.CompletableFuture;
@@ -334,4 +335,29 @@ default  CompletableFuture> withHandler(HttpResponse.BodyHand
    * @return The CompletableFuture of the response
    */
    CompletableFuture> stream(Class type);
+
+  /**
+   * Process expecting a bean response body (typically from json content).
+   *
+   * @param type The parameterized type to convert the content to
+   * @return The CompletableFuture of the response
+   */
+   CompletableFuture bean(ParameterizedType type);
+
+  /**
+   * Process expecting a list of beans response body (typically from json content).
+   *
+   * @param type The parameterized type to convert the content to
+   * @return The CompletableFuture of the response
+   */
+   CompletableFuture> list(ParameterizedType type);
+
+  /**
+   * Process response as a stream of beans (x-json-stream).
+   *
+   * @param type The parameterized type to convert the content to
+   * @return The CompletableFuture of the response
+   */
+   CompletableFuture> stream(ParameterizedType type);
+
 }
diff --git a/http-client/client/src/main/java/io/avaje/http/client/HttpCallResponse.java b/http-client/client/src/main/java/io/avaje/http/client/HttpCallResponse.java
index d081a3216..96cccbe52 100644
--- a/http-client/client/src/main/java/io/avaje/http/client/HttpCallResponse.java
+++ b/http-client/client/src/main/java/io/avaje/http/client/HttpCallResponse.java
@@ -1,6 +1,7 @@
 package io.avaje.http.client;
 
 import java.io.InputStream;
+import java.lang.reflect.ParameterizedType;
 import java.net.http.HttpResponse;
 import java.util.List;
 import java.util.stream.Stream;
@@ -186,4 +187,28 @@ default  HttpCall> withHandler(HttpResponse.BodyHandler bo
    */
    HttpCall> stream(Class type);
 
+  /**
+   * A bean response to execute async or sync.
+   *
+   * @param type The parameterized type to convert the content to
+   * @return The HttpCall to allow sync or async execution
+   */
+   HttpCall bean(ParameterizedType type);
+
+  /**
+   * Process expecting a list of beans response body (typically from json content).
+   *
+   * @param type The parameterized type to convert the content to
+   * @return The HttpCall to execute sync or async
+   */
+   HttpCall> list(ParameterizedType type);
+
+  /**
+   * Process expecting a stream of beans response body (typically from json content).
+   *
+   * @param type The parameterized type to convert the content to
+   * @return The HttpCall to execute sync or async
+   */
+   HttpCall> stream(ParameterizedType type);
+
 }

From 32cb46e63fd0950cb961fd385ec6c6b5143227d1 Mon Sep 17 00:00:00 2001
From: Josiah Noel <32279667+SentryMan@users.noreply.github.com>
Date: Wed, 28 Dec 2022 22:06:17 -0500
Subject: [PATCH 0437/1323] Client is good now

---
 .../generator/client/ClientMethodWriter.java  | 54 +++++++++++++------
 .../generator/client/ClientProcessor.java     | 17 +++++-
 .../http/generator/client/ClientWriter.java   |  7 ++-
 .../avaje/http/generator/core/JsonBUtil.java  | 10 ++--
 .../io/avaje/http/generator/core/UType.java   |  2 +-
 5 files changed, 64 insertions(+), 26 deletions(-)

diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java
index 0f6b782a4..a45c2308d 100644
--- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java
+++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java
@@ -4,6 +4,7 @@
 
 import javax.lang.model.element.TypeElement;
 import java.util.Set;
+import java.util.stream.Collectors;
 
 /**
  * Write code to register Web route for a given controller method.
@@ -22,13 +23,15 @@ class ClientMethodWriter {
   private final UType returnType;
   private MethodParam bodyHandlerParam;
   private String methodGenericParams = "";
+  private final boolean useJsonb;
 
-  ClientMethodWriter(MethodReader method, Append writer, ProcessingContext ctx) {
+  ClientMethodWriter(MethodReader method, Append writer, ProcessingContext ctx, boolean useJsonb) {
     this.method = method;
     this.writer = writer;
     this.webMethod = method.webMethod();
     this.ctx = ctx;
     this.returnType = Util.parseType(method.returnType());
+    this.useJsonb = useJsonb;
   }
 
   void addImportTypes(ControllerReader reader) {
@@ -111,37 +114,54 @@ private void writeEnd() {
 
   private void writeSyncResponse() {
     writer.append("      ");
-    String type0 = returnType.mainType();
-    String type1 = returnType.param0();
-    writeResponse(type0, type1);
+    writeResponse(returnType);
   }
 
   private void writeAsyncResponse() {
     writer.append("      .async()");
-    String type0 = returnType.param0();
-    String type1 = returnType.param1();
-    writeResponse(type0, type1);
+    writeResponse(returnType.paramRaw());
   }
 
   private void writeCallResponse() {
     writer.append("      .call()");
-    String type0 = returnType.param0();
-    String type1 = returnType.param1();
-    writeResponse(type0, type1);
+    writeResponse(returnType.paramRaw());
   }
 
-  private void writeResponse(String type0, String type1) {
-    if (isList(type0)) {
-      writer.append(".list(%s.class);", Util.shortName(type1)).eol();
-    } else if (isStream(type0)) {
-      writer.append(".stream(%s.class);", Util.shortName(type1)).eol();
-    } else if (isHttpResponse(type0)){
+  private void writeResponse(UType type) {
+    final var mainType = type.mainType();
+    final var param1 = type.paramRaw();
+    if (isList(mainType)) {
+      writer.append(".list(");
+      writeGeneric(param1);
+    } else if (isStream(mainType)) {
+      writer.append(".stream(");
+      writeGeneric(param1);
+    } else if (isHttpResponse(mainType)) {
       writeWithHandler();
     } else {
-      writer.append(".bean(%s.class);", Util.shortName(type0)).eol();
+      writer.append(".bean(").eol();
+      writeGeneric(type);
     }
   }
 
+  void writeGeneric(UType type) {
+    if (useJsonb && type.isGeneric()) {
+      final var params =
+          type.importTypes().stream()
+                  .skip(1)
+                  .map(Util::shortName)
+                  .collect(Collectors.joining(".class, "));
+
+      writer.append(
+          "Types.newParameterizedType(%s.class, %s.class)", Util.shortName(type.mainType()), params);
+    } else {
+      writer.append("%s.class", Util.shortName(type.mainType()));
+    }
+    writer.append(");");
+
+    writer.eol();
+  }
+
   private void writeWithHandler() {
     if (bodyHandlerParam != null) {
       writer.append(".handler(%s);", bodyHandlerParam.name()).eol();
diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java
index 0a8b68605..14f297d03 100644
--- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java
+++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java
@@ -27,6 +27,21 @@ public class ClientProcessor extends AbstractProcessor {
 
   protected ProcessingContext ctx;
 
+  private boolean useJsonB;
+
+  public ClientProcessor() {
+    try {
+      Class.forName("io.avaje.jsonb.Jsonb");
+      this.useJsonB = true;
+    } catch (final ClassNotFoundException e) {
+      this.useJsonB = false;
+    }
+  }
+
+  public ClientProcessor(boolean useJsonb) {
+    useJsonB = useJsonb;
+  }
+
   @Override
   public SourceVersion getSupportedSourceVersion() {
     return SourceVersion.latest();
@@ -107,7 +122,7 @@ private void writeClient(Element controller) {
   }
 
   protected String writeClientAdapter(ProcessingContext ctx, ControllerReader reader) throws IOException {
-    return new ClientWriter(reader, ctx).write();
+    return new ClientWriter(reader, ctx,useJsonB).write();
   }
 
 }
diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientWriter.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientWriter.java
index 26dd12a6a..6f465bd73 100644
--- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientWriter.java
+++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientWriter.java
@@ -21,12 +21,15 @@ class ClientWriter extends BaseControllerWriter {
   private static final String SUFFIX = "HttpClient";
 
   private final List methodList = new ArrayList<>();
+  private final boolean useJsonb;
 
-  ClientWriter(ControllerReader reader, ProcessingContext ctx) throws IOException {
+  ClientWriter(ControllerReader reader, ProcessingContext ctx, boolean useJsonB) throws IOException {
     super(reader, ctx, SUFFIX);
     reader.addImportType(HTTP_CLIENT_CONTEXT);
     reader.addImportType(HTTP_API_PROVIDER);
+    this.useJsonb = useJsonB;
     readMethods();
+    if (useJsonB) reader.addImportType("io.avaje.jsonb.Types");
   }
 
   @Override
@@ -38,7 +41,7 @@ protected String initPackageName(String originName) {
   private void readMethods() {
     for (MethodReader method : reader.methods()) {
       if (method.isWebMethod()) {
-        ClientMethodWriter methodWriter = new ClientMethodWriter(method, writer, ctx);
+        final var methodWriter = new ClientMethodWriter(method, writer, ctx, useJsonb);
         methodWriter.addImportTypes(reader);
         methodList.add(methodWriter);
       }
diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java
index 13c043a05..f338f69d0 100644
--- a/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java
+++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java
@@ -72,13 +72,13 @@ static void writeType(UType type, Append writer) {
     if (type.isGeneric()) {
       final var params =
           type.importTypes().stream()
-                  .skip(1)
-                  .map(Util::shortName)
-                  .collect(Collectors.joining(".class, "))
-              + ".class";
+              .skip(1)
+              .map(Util::shortName)
+              .collect(Collectors.joining(".class, "));
 
       writer.append(
-          "Types.newParameterizedType(%s.class, %s))", Util.shortName(type.mainType()), params);
+          "Types.newParameterizedType(%s.class, %s.class))",
+          Util.shortName(type.mainType()), params);
     } else {
       writer.append("%s.class)", Util.shortName(type.mainType()));
     }
diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java
index 929658194..e4a4bd20b 100644
--- a/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java
+++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java
@@ -157,8 +157,8 @@ private String extractRawParam() {
 
       switch (mainType()) {
         case "java.util.Set":
-        case "java.util.Stream":
         case "java.util.List":
+        case "java.util.stream.Stream":
         case "java.util.concurrent.CompletableFuture":
         case "io.avaje.http.client.HttpCall":
           var first = rawType.indexOf("<") + 1;

From 1540cf8d476a4f1ba27348fb0361b9f516f27f88 Mon Sep 17 00:00:00 2001
From: Josiah Noel <32279667+SentryMan@users.noreply.github.com>
Date: Sat, 31 Dec 2022 13:42:43 -0600
Subject: [PATCH 0438/1323] Update README.md

---
 http-client/README.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/http-client/README.md b/http-client/README.md
index f87cec7ee..5513b53a9 100644
--- a/http-client/README.md
+++ b/http-client/README.md
@@ -310,7 +310,7 @@ public final class ExampleRetry implements RetryHandler {
 
     final var code = response.statusCode();
 
-    if (retryCount >= MAX_RETRIES || code >= 400) {
+    if (retryCount >= MAX_RETRIES || code <= 400) {
 
       return false;
     }

From b9f6471a4811524b423fecdf09deae756617969b Mon Sep 17 00:00:00 2001
From: Josiah Noel <32279667+SentryMan@users.noreply.github.com>
Date: Sat, 31 Dec 2022 15:34:04 -0600
Subject: [PATCH 0439/1323] Update README.md

---
 README.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/README.md b/README.md
index c13cc5321..44baa880c 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
 # avaje-http
 
-Http server and client libraries and code generation.
+HTTP server and client libraries via code generation.
 
 ## Http Server
 

From e4343fbfa6a148a0e62f209935ae2b12ec1801b0 Mon Sep 17 00:00:00 2001
From: Josiah Noel <32279667+SentryMan@users.noreply.github.com>
Date: Sat, 31 Dec 2022 15:57:22 -0600
Subject: [PATCH 0440/1323] Update README.md

---
 README.md | 1 +
 1 file changed, 1 insertion(+)

diff --git a/README.md b/README.md
index 44baa880c..38df8651e 100644
--- a/README.md
+++ b/README.md
@@ -2,6 +2,7 @@
 
 HTTP server and client libraries via code generation.
 
+Documentation at [avaje.io/http](https://avaje.io/http/)
 ## Http Server
 
 A jax-rs style controllers with annotations (`@Path`, `@Get` ...)

From 4fc8a8d6ebf4e5671b231249d9bb464990e28c68 Mon Sep 17 00:00:00 2001
From: Rob Bygrave 
Date: Tue, 3 Jan 2023 10:17:59 +1300
Subject: [PATCH 0441/1323] No effective change, format only

---
 .../main/java/io/avaje/http/client/DHttpClientRequest.java | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java
index 22d885f18..fd6988703 100644
--- a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java
+++ b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java
@@ -434,7 +434,7 @@ public  List list(Class cls) {
     readResponseContent();
     return context.readList(cls, encodedResponseBody);
   }
-  
+
   @Override
   public  Stream stream(Class cls) {
     final HttpResponse> res = handler(HttpResponse.BodyHandlers.ofLines());
@@ -459,7 +459,7 @@ public  List list(ParameterizedType cls) {
     return context.readList(cls, encodedResponseBody);
   }
 
-  
+
   @Override
   public  Stream stream(ParameterizedType cls) {
     final HttpResponse> res = handler(HttpResponse.BodyHandlers.ofLines());
@@ -542,8 +542,7 @@ protected  List asyncList(ParameterizedType type, HttpResponse res
     return context.readList(type, encodedResponseBody);
   }
 
-  protected  Stream asyncStream(
-      ParameterizedType type, HttpResponse> response) {
+  protected  Stream asyncStream(ParameterizedType type, HttpResponse> response) {
     responseTimeNanos = System.nanoTime() - startAsyncNanos;
     httpResponse = response;
     context.afterResponse(this);

From 36c817755382cc01d5bd91750a7110f3f1cf3d95 Mon Sep 17 00:00:00 2001
From: Rob Bygrave 
Date: Tue, 3 Jan 2023 10:22:42 +1300
Subject: [PATCH 0442/1323] Bump test dependencies

---
 http-client/client/pom.xml       | 4 ++--
 http-client/gson-adapter/pom.xml | 2 +-
 http-client/test/pom.xml         | 4 ++--
 3 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/http-client/client/pom.xml b/http-client/client/pom.xml
index cb428658d..4c96a3b1a 100644
--- a/http-client/client/pom.xml
+++ b/http-client/client/pom.xml
@@ -32,14 +32,14 @@
     
       com.fasterxml.jackson.core
       jackson-databind
-      2.13.3
+      2.14.1
       true
     
 
     
       io.avaje
       avaje-jsonb
-      1.1-RC2
+      1.1-RC3
       true
     
 
diff --git a/http-client/gson-adapter/pom.xml b/http-client/gson-adapter/pom.xml
index b33824e0c..4bb9f334d 100644
--- a/http-client/gson-adapter/pom.xml
+++ b/http-client/gson-adapter/pom.xml
@@ -22,7 +22,7 @@
     
       com.google.code.gson
       gson
-      2.9.0
+      2.10
     
 
     
diff --git a/http-client/test/pom.xml b/http-client/test/pom.xml
index 3b80a17e7..b5cfc94ee 100644
--- a/http-client/test/pom.xml
+++ b/http-client/test/pom.xml
@@ -28,13 +28,13 @@
     
       io.avaje
       avaje-http-api
-      1.16
+      1.20
     
 
     
       com.fasterxml.jackson.core
       jackson-databind
-      2.13.3
+      2.14.1
     
 
     

From a6f74a9cbdeaf13a51b8e028d2eb32ebc6ca309a Mon Sep 17 00:00:00 2001
From: Josiah Noel <32279667+SentryMan@users.noreply.github.com>
Date: Mon, 2 Jan 2023 15:25:24 -0600
Subject: [PATCH 0443/1323] Update generated sources

---
 README.md | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/README.md b/README.md
index c13cc5321..1f4333e94 100644
--- a/README.md
+++ b/README.md
@@ -231,13 +231,13 @@ If [Avaje-Jsonb](https://github.com/avaje/avaje-jsonb) is detected, http generat
 public class WidgetController$Route implements WebRoutes {
 
   private final WidgetController controller;
-  private final JsonType> listWidgetJsonType;
-  private final JsonType widgetJsonType;
+  private final JsonType> listWidgetJsonType;
+  private final JsonType widgetJsonType;
 
   public WidgetController$Route(WidgetController controller, Jsonb jsonB) {
     this.controller = controller;
-    this.listWidgetJsonType = jsonB.type(org.example.hello.WidgetController.Widget.class).list();
-    this.widgetJsonType = jsonB.type(org.example.hello.WidgetController.Widget.class);
+    this.listWidgetJsonType = jsonB.type(Widget.class).list();
+    this.widgetJsonType = jsonB.type(Widget.class);
   }
 
   @Override

From ce90612d0ebec791c9fc4b83bf6f25ebc6610b45 Mon Sep 17 00:00:00 2001
From: Josiah Noel <32279667+SentryMan@users.noreply.github.com>
Date: Mon, 2 Jan 2023 19:18:55 -0500
Subject: [PATCH 0444/1323] final jsonb

---
 .../avaje/http/generator/client/ClientMethodWriter.java  | 2 +-
 .../io/avaje/http/generator/client/ClientProcessor.java  | 9 +++++----
 .../avaje/http/generator/javalin/JavalinProcessor.java   | 7 ++++---
 .../avaje/http/generator/helidon/nima/NimaProcessor.java | 7 ++++---
 4 files changed, 14 insertions(+), 11 deletions(-)

diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java
index a45c2308d..927ad5fe7 100644
--- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java
+++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java
@@ -139,7 +139,7 @@ private void writeResponse(UType type) {
     } else if (isHttpResponse(mainType)) {
       writeWithHandler();
     } else {
-      writer.append(".bean(").eol();
+      writer.append(".bean(");
       writeGeneric(type);
     }
   }
diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java
index 14f297d03..c3f4010bf 100644
--- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java
+++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java
@@ -27,15 +27,16 @@ public class ClientProcessor extends AbstractProcessor {
 
   protected ProcessingContext ctx;
 
-  private boolean useJsonB;
+  private final boolean useJsonB;
 
   public ClientProcessor() {
+    var jsonBOnClassPath = false;
     try {
       Class.forName("io.avaje.jsonb.Jsonb");
-      this.useJsonB = true;
+      jsonBOnClassPath = true;
     } catch (final ClassNotFoundException e) {
-      this.useJsonB = false;
     }
+    useJsonB = jsonBOnClassPath;
   }
 
   public ClientProcessor(boolean useJsonb) {
@@ -122,7 +123,7 @@ private void writeClient(Element controller) {
   }
 
   protected String writeClientAdapter(ProcessingContext ctx, ControllerReader reader) throws IOException {
-    return new ClientWriter(reader, ctx,useJsonB).write();
+    return new ClientWriter(reader, ctx, useJsonB).write();
   }
 
 }
diff --git a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinProcessor.java b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinProcessor.java
index 4d6285675..ef65ccdf9 100644
--- a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinProcessor.java
+++ b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinProcessor.java
@@ -9,15 +9,16 @@
 
 public class JavalinProcessor extends BaseProcessor {
 
-  private boolean useJsonB;
+  private final boolean useJsonB;
 
   public JavalinProcessor() {
+    var jsonBOnClassPath = false;
     try {
       Class.forName("io.avaje.jsonb.Jsonb");
-      this.useJsonB = true;
+      jsonBOnClassPath = true;
     } catch (final ClassNotFoundException e) {
-      this.useJsonB = false;
     }
+    useJsonB = jsonBOnClassPath;
   }
 
   public JavalinProcessor(boolean useJsonb) {
diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/NimaProcessor.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/NimaProcessor.java
index c65a83b6a..cf3464093 100644
--- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/NimaProcessor.java
+++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/NimaProcessor.java
@@ -9,15 +9,16 @@
 
 public class NimaProcessor extends BaseProcessor {
 
-  private boolean jsonB;
+  private final boolean jsonB;
 
   public NimaProcessor() {
+    var jsonBOnClassPath = false;
     try {
       Class.forName("io.avaje.jsonb.Jsonb");
-      this.jsonB = true;
+      jsonBOnClassPath = true;
     } catch (final ClassNotFoundException e) {
-      this.jsonB = false;
     }
+    jsonB = jsonBOnClassPath;
   }
 
   public NimaProcessor(boolean useJsonb) {

From 2a331c049c4e22d59eed4b1c525e2fbdb40f01af Mon Sep 17 00:00:00 2001
From: Josiah Noel <32279667+SentryMan@users.noreply.github.com>
Date: Tue, 3 Jan 2023 10:10:28 -0600
Subject: [PATCH 0445/1323] Bring the README more in line with the Docs

---
 README.md | 328 ++++++++++++++++++++++++++++++++++++++++++++----------
 1 file changed, 267 insertions(+), 61 deletions(-)

diff --git a/README.md b/README.md
index 84359f626..377539d53 100644
--- a/README.md
+++ b/README.md
@@ -1,122 +1,328 @@
-# avaje-http
+# [Avaje-HTTP](https://avaje.io/http/)
 
-Http server and client libraries and code generation.
+HTTP server and client libraries via code generation.
 
-## http server
+## HTTP Server
 
 A jax-rs style controllers with annotations (`@Path`, `@Get` ...)
 that is lightweight by using source code generation (annotation processors)
-to generate adapter code for Javalin and Helidon SE.
+to generate adapter code for Javalin and Helidon SE/Nima.
 
 - Lightweight as in 65Kb library + generated source code
-- Full use of Javalin or Helidon SE as desired
+- Full use of Javalin or Helidon SE/Nima as desired
 
+## Quick Start
 
-## Define a Controller
+#### 1. Add dependencies
+```xml
+
+  io.avaje
+  avaje-http-api
+  ${avaje.http.version}
+
+```
+#### 2. Add the generator module for your desired microframework as a annotation processor.
+
+```xml
+
+
+  io.avaje
+  avaje-inject-generator
+  ${avaje-inject.version}
+  provided
+
+
+  io.avaje
+  avaje-http-javalin-generator
+  ${avaje-http.version}
+  provided
+
+```
+If there are other annotation processors and they are specified via maven-compiler-plugin then we add avaje-http-generator there instead.
+```xml
+
+  org.apache.maven.plugins
+  maven-compiler-plugin
+  
+     
+      
+        io.avaje
+        avaje-inject-generator
+        ${avaje-inject.version}
+      
+      
+        io.avaje
+        avaje-http-javalin-generator
+        ${avaje-http.version}
+      
+      
+          ... other annotation processor ...
+      
+    
+  
+
+```
+#### 3. Define a Controller (These APT processors work with both Java and Kotlin.)
 ```java
-package org.example.hello
+package org.example.hello;
 
-import io.avaje.http.api.Controller
-import io.avaje.http.api.Get
-import io.avaje.http.api.Path
+import io.avaje.http.api.Controller;
+import io.avaje.http.api.Get;
+import io.avaje.http.api.Path;
+import java.util.List;
 
 @Path("/widgets")
 @Controller
-class WidgetController(private val hello: HelloComponent) {
+public class WidgetController {
+  private final HelloComponent hello;
+  public WidgetController(HelloComponent hello) {
+    this.hello = hello;
+  }
+  
+  @Get("/{id}")
+  Widget getById(int id) {
+    return new Widget(id, "you got it"+ hello.hello());
+  }
 
-  @Get("/:id")
-  fun getById(id : Int): Widget {
-    return Widget(id, "you got it${hello.hello()}")
+  @Get()
+  List getAll() {
+    return List.of(new Widget(1, "Rob"), new Widget(2, "Fi"));
   }
 
-  @Get
-  fun getAll(): MutableList {
+  record Widget(int id, String name){};
+}
+```
 
-    val list = mutableListOf()
-    list.add(Widget(1, "Rob"))
-    list.add(Widget(2, "Fi"))
+## Usage
+The annotation processor will generate controller adapters that can register routes to Javalin/Helidon. The natural way to use the generated adapters is to get a DI library to find and wire them. This is what the below examples do and they use [Avaje-Inject](https://avaje.io/inject/) to do this.
 
-    return list
-  }
+Note that there isn't a requirement to use Avaje for dependency injection. Any DI library that can find and wire the generated @Singleton beans can be used. You can even use Dagger2 or Guice to wire the controllers if you so desire.
 
-  data class Widget(var id: Int, var name: String)
-}
+### Usage with Javalin
+
+The annotation processor will generate controller classes implementing the WebRoutes interface, which means we can
+get all the WebRoutes and register them with Javalin using:
 
+```java
+var routes = BeanScope.builder().build().list(WebRoutes.class); 
+
+Javalin.create()
+        .routes(() -> routes.forEach(WebRoutes::registerRoutes))
+        .start();
+```
+
+### Usage with Helidon SE
+
+The annotation processor will generate controller classes implementing the Helidon Service interface, which we can use
+get all the Services and register them with Helidon `RoutingBuilder`.
+
+```java
+var routes = BeanScope.builder().build().list(Service.class); 
+var routingBuilder = Routing.builder().register(routes.stream().toArray(Service[]::new));
+WebServer.builder()
+        .addMediaSupport(JacksonSupport.create())
+        .routing(routingBuilder)
+        .build()
+        .start();
 ```
 
-## Generated source
+### Usage with Helidon Nima
+
+The annotation processor will generate controller classes implementing the Helidon HttpService interface, which we can use
+get all the services and register them with the Helidon `HttpRouting`.
+
+```java
+var routes = BeanScope.builder().build().list(HttpService.class); 
+final var builder = HttpRouting.builder();
+
+for (final HttpService httpService : routes) {
+   httpService.routing(builder);
+}
 
-The annotation processor will generate a `$Route` for the controller like below.
+WebServer.builder()
+         .addRouting(builder.build())
+         .build()
+         .start();
+```
+## Generated sources
 
-Note that this class implements the WebRoutes interface, which means we can
-get all the WebRoutes and register them with Javalin using.
+### (Javalin) The generated WidgetController$Route.java is:
 
 ```java
-fun main(args: Array) {
+@Generated("avaje-javalin-generator")
+@Component
+public class WidgetController$Route implements WebRoutes {
 
-  // get all the webRoutes
-  val webRoutes = ApplicationScope.list(WebRoutes::class.java)
+  private final WidgetController controller;
 
-  val javalin = Javalin.create()
+  public WidgetController$Route(WidgetController controller) {
+    this.controller = controller;
+  }
 
-  javalin.routes {
-    // register all the routes with Javalin
-    webRoutes.forEach { it.registerRoutes() }
+  @Override
+  public void registerRoutes() {
+
+    ApiBuilder.get("/widgets/{id}", ctx -> {
+      ctx.status(200);
+      var id = asInt(ctx.pathParam("id"));
+      var result = controller.getById(id);
+      ctx.json(result);
+    });
+
+    ApiBuilder.get("/widgets", ctx -> {
+      ctx.status(200);
+      var result = controller.getAll();
+      ctx.json(result);
+    });
 
-    // other routes etc as desired
-    ApiBuilder.get("/foo") { ctx ->
-      ctx.html("bar")
-      ctx.status(200)
-    }
-    ...
   }
 
-  javalin.start(7000)
 }
-
 ```
 
-### The generated WidgetController$Route.java is:
+### (Helidon SE) The generated WidgetController$Route.java is:
+```java
+@Generated("io.dinject.helidon-generator")
+@Singleton
+public class WidgetController$Route implements Service {
+
+  private final WidgetController controller;
 
+  public WidgetController$Route(WidgetController controller) {
+    this.controller = controller;
+  }
+
+  @Override
+  public void update(Routing.Rules rules) {
+
+    rules.get("/widgets/{id}", this::_getById);
+    rules.post("/widgets", this::_getAll);
+  }
+
+  private void _getById(ServerRequest req, ServerResponse res) {
+    int id = asInt(req.path().param("id"));
+    res.send(controller.getById(id));
+  }
+
+  private void _getAll(ServerRequest req, ServerResponse res) {
+    res.send(controller.getAll());
+  }
+
+}
+```
+
+### (Helidon Nima) The generated WidgetController$Route.java is:
 
 ```java
-package org.example.hello;
+@Generated("avaje-helidon-nima-generator")
+@Component
+public class WidgetController$Route implements HttpService {
 
-import static io.avaje.http.api.PathTypeConversion.*;
-import io.avaje.http.api.WebRoutes;
-import io.javalin.apibuilder.ApiBuilder;
-import javax.annotation.Generated;
-import javax.inject.Singleton;
-import org.example.hello.WidgetController;
+  private final WidgetController controller;
+  public WidgetController$Route(WidgetController controller) {
+    this.controller = controller;
+  }
 
-@Generated("io.avaje.javalin-generator")
-@Singleton
+  @Override
+  public void routing(HttpRules rules) {
+    rules.get("/widgets/{id}", this::_getById);
+    rules.get("/widgets", this::_getAll);
+  }
+
+  private void _getById(ServerRequest req, ServerResponse res) {
+    var pathParams = req.path().pathParameters();
+    int id = asInt(pathParams.first("id").get());
+    var result = controller.getById(id);
+    res.send(result);
+  }
+
+  private void _getAll(ServerRequest req, ServerResponse res) {
+    var pathParams = req.path().pathParameters();
+    var result = controller.getAll();
+    res.send(result);
+  }
+
+}
+```
+
+## Generated sources ([Avaje-Jsonb](https://github.com/avaje/avaje-jsonb))
+If [Avaje-Jsonb](https://github.com/avaje/avaje-jsonb) is detected, http generators with support will use it for faster Json message processing.
+
+### (Javalin) The generated WidgetController$Route.java is:
+```java
+@Generated("avaje-javalin-generator")
+@Component
 public class WidgetController$Route implements WebRoutes {
 
- private final WidgetController controller;
+  private final WidgetController controller;
+  private final JsonType> listWidgetJsonType;
+  private final JsonType widgetJsonType;
 
- public WidgetController$route(WidgetController controller) {
-   this.controller = controller;
- }
+  public WidgetController$Route(WidgetController controller, Jsonb jsonB) {
+    this.controller = controller;
+    this.listWidgetJsonType = jsonB.type(Widget.class).list();
+    this.widgetJsonType = jsonB.type(Widget.class);
+  }
 
   @Override
   public void registerRoutes() {
 
-    ApiBuilder.get("/widgets/:id", ctx -> {
-      int id = asInt(ctx.pathParam("id"));
-      ctx.json(controller.getById(id));
+    ApiBuilder.get("/widgets/{id}", ctx -> {
       ctx.status(200);
+      var id = asInt(ctx.pathParam("id"));
+      var result = controller.getById(id);
+      widgetJsonType.toJson(result, ctx.contentType("application/json").outputStream());
     });
 
     ApiBuilder.get("/widgets", ctx -> {
-      ctx.json(controller.getAll());
       ctx.status(200);
+      var result = controller.getAll();
+      listWidgetJsonType.toJson(result, ctx.contentType("application/json").outputStream());
     });
 
   }
+
 }
 ```
 
-Note that this APT processor works with both Java and Kotlin.
+### (Helidon Nima) The generated WidgetController$Route.java is:
+
+```java
+@Generated("avaje-helidon-nima-generator")
+@Component
+public class WidgetController$Route implements HttpService {
+
+
+  private final WidgetController controller;
+  private final JsonType widgetJsonType;
+  private final JsonType> listWidgetJsonType;
 
+  public WidgetController$Route(WidgetController controller, Jsonb jsonB) {
+    this.controller = controller;
+    this.widgetJsonType = jsonB.type(Widget.class);
+    this.listWidgetJsonType = jsonB.type(Widget.class).list();
+  }
+
+  @Override
+  public void routing(HttpRules rules) {
+    rules.get("/widgets/{id}", this::_getById);
+    rules.get("/widgets", this::_getAll);
+  }
+
+  private void _getById(ServerRequest req, ServerResponse res) {
+    var pathParams = req.path().pathParameters();
+    int id = asInt(pathParams.first("id").get());
+    var result = controller.getById(id);
+    res.headers().contentType(io.helidon.common.http.HttpMediaType.APPLICATION_JSON);
+    widgetJsonType.toJson(result, res.outputStream());
+  }
+
+  private void _getAll(ServerRequest req, ServerResponse res) {
+    var pathParams = req.path().pathParameters();
+    var result = controller.getAll();
+    res.headers().contentType(io.helidon.common.http.HttpMediaType.APPLICATION_JSON);
+    listWidgetJsonType.toJson(result, res.outputStream());
+  }
 
+}
+```

From 93eca1fe6e525c4f7f37ba0e3b37fd539de5b231 Mon Sep 17 00:00:00 2001
From: Josiah Noel <32279667+SentryMan@users.noreply.github.com>
Date: Tue, 3 Jan 2023 10:14:38 -0600
Subject: [PATCH 0446/1323] Update README.md

---
 README.md | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/README.md b/README.md
index aeafce8fb..3c9a96784 100644
--- a/README.md
+++ b/README.md
@@ -15,6 +15,11 @@ to generate adapter code for Javalin and Helidon SE/Nima.
 
 #### 1. Add dependencies
 ```xml
+
+  io.avaje
+  avaje-inject
+  ${avaje-inject.version}
+
 
   io.avaje
   avaje-http-api

From e8334d042fe8066d2755b078e553a0bc33c5846c Mon Sep 17 00:00:00 2001
From: Josiah Noel <32279667+SentryMan@users.noreply.github.com>
Date: Tue, 3 Jan 2023 10:17:40 -0600
Subject: [PATCH 0447/1323] Update README.md

---
 README.md | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/README.md b/README.md
index 3c9a96784..379de37d7 100644
--- a/README.md
+++ b/README.md
@@ -11,9 +11,7 @@ to generate adapter code for Javalin and Helidon SE/Nima.
 - Lightweight as in 65Kb library + generated source code
 - Full use of Javalin or Helidon SE/Nima as desired
 
-## Quick Start
-
-#### 1. Add dependencies
+## Add dependencies
 ```xml
 
   io.avaje
@@ -26,7 +24,7 @@ to generate adapter code for Javalin and Helidon SE/Nima.
   ${avaje.http.version}
 
 ```
-#### 2. Add the generator module for your desired microframework as a annotation processor.
+#### Add the generator module for your desired microframework as a annotation processor.
 
 ```xml
 
@@ -67,7 +65,7 @@ If there are other annotation processors and they are specified via maven-com
   
 
 ```
-#### 3. Define a Controller (These APT processors work with both Java and Kotlin.)
+## Define a Controller (These APT processors work with both Java and Kotlin.)
 ```java
 package org.example.hello;
 

From 05833c69181fd0f80a02001867ba24680bd9a0de Mon Sep 17 00:00:00 2001
From: Josiah Noel <32279667+SentryMan@users.noreply.github.com>
Date: Tue, 3 Jan 2023 14:34:14 -0600
Subject: [PATCH 0448/1323] Update README.md

---
 README.md | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/README.md b/README.md
index 379de37d7..1aab095d1 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,7 @@
 # [Avaje-HTTP](https://avaje.io/http/)
+[![Build](https://github.com/avaje/avaje-http/actions/workflows/build.yml/badge.svg)](https://github.com/avaje/avaje-http/actions/workflows/build.yml)
+[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://github.com/avaje/avaje-inject/blob/master/LICENSE)
+
 
 HTTP server and client libraries via code generation.
 

From e902d91336a4b1435f6d0c1fe3dec4fda58dcf14 Mon Sep 17 00:00:00 2001
From: Josiah Noel <32279667+SentryMan@users.noreply.github.com>
Date: Tue, 3 Jan 2023 14:36:29 -0600
Subject: [PATCH 0449/1323] Update README.md

---
 README.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/README.md b/README.md
index 1aab095d1..60334e3a2 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@
 # [Avaje-HTTP](https://avaje.io/http/)
 [![Build](https://github.com/avaje/avaje-http/actions/workflows/build.yml/badge.svg)](https://github.com/avaje/avaje-http/actions/workflows/build.yml)
-[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://github.com/avaje/avaje-inject/blob/master/LICENSE)
 
+[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://github.com/avaje/avaje-inject/blob/master/LICENSE)
 
 HTTP server and client libraries via code generation.
 

From e6069bb071cccb05535e4d373e46d4e880d02d5f Mon Sep 17 00:00:00 2001
From: Josiah Noel <32279667+SentryMan@users.noreply.github.com>
Date: Thu, 5 Jan 2023 11:10:11 -0500
Subject: [PATCH 0450/1323] Update ControllerMethodWriter.java

---
 .../io/avaje/http/generator/helidon/ControllerMethodWriter.java | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/ControllerMethodWriter.java b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/ControllerMethodWriter.java
index e2df2842e..a43192644 100644
--- a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/ControllerMethodWriter.java
+++ b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/ControllerMethodWriter.java
@@ -103,7 +103,7 @@ private void writeContextReturn() {
     } else if (MediaType.TEXT_PLAIN.equalsIgnoreCase(produces)) {
       writer.append("    res.writerContext().contentType(io.helidon.common.http.MediaType.TEXT_PLAIN);").eol();
     } else {
-      writer.append(    "res.writerContext().contentType(io.helidon.common.http.MediaType.parse(\"%s\"));", produces).eol();
+      writer.append("    res.writerContext().contentType(io.helidon.common.http.MediaType.parse(\"%s\"));", produces).eol();
     }
   }
 

From 518e8b179df3b6cd71bff1644596340dd50340f8 Mon Sep 17 00:00:00 2001
From: Rob Bygrave 
Date: Fri, 6 Jan 2023 11:43:13 +1300
Subject: [PATCH 0451/1323] [maven-release-plugin] prepare release
 avaje-http-client-1.21

---
 http-client/client/pom.xml | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/http-client/client/pom.xml b/http-client/client/pom.xml
index 4c96a3b1a..3d7b2ed1b 100644
--- a/http-client/client/pom.xml
+++ b/http-client/client/pom.xml
@@ -10,11 +10,11 @@
 
   io.avaje
   avaje-http-client
-  1.21-SNAPSHOT
+  1.21
 
   
     scm:git:git@github.com:avaje/avaje-http-client.git
-    HEAD
+    avaje-http-client-1.21
   
 
   

From 6d9ebe1e764c3e16def70c48fd5d15640ea3d142 Mon Sep 17 00:00:00 2001
From: Rob Bygrave 
Date: Fri, 6 Jan 2023 11:43:21 +1300
Subject: [PATCH 0452/1323] [maven-release-plugin] prepare for next development
 iteration

---
 http-client/client/pom.xml | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/http-client/client/pom.xml b/http-client/client/pom.xml
index 3d7b2ed1b..70bdae8c2 100644
--- a/http-client/client/pom.xml
+++ b/http-client/client/pom.xml
@@ -10,11 +10,11 @@
 
   io.avaje
   avaje-http-client
-  1.21
+  1.22-SNAPSHOT
 
   
     scm:git:git@github.com:avaje/avaje-http-client.git
-    avaje-http-client-1.21
+    HEAD
   
 
   

From bad0874d8c7e50f1c92e568312d4d93ebec38b87 Mon Sep 17 00:00:00 2001
From: Rob Bygrave 
Date: Fri, 6 Jan 2023 11:49:04 +1300
Subject: [PATCH 0453/1323] Bump versions after release

---
 http-client/gson-adapter/pom.xml | 4 ++--
 http-client/test/pom.xml         | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/http-client/gson-adapter/pom.xml b/http-client/gson-adapter/pom.xml
index 4bb9f334d..9bd29fcb1 100644
--- a/http-client/gson-adapter/pom.xml
+++ b/http-client/gson-adapter/pom.xml
@@ -10,7 +10,7 @@
 
   io.avaje
   avaje-http-client-gson
-  1.21-SNAPSHOT
+  1.22-SNAPSHOT
 
   
     scm:git:git@github.com:avaje/avaje-http-client.git
@@ -28,7 +28,7 @@
     
       io.avaje
       avaje-http-client
-      1.21-SNAPSHOT
+      1.22-SNAPSHOT
       provided
     
 
diff --git a/http-client/test/pom.xml b/http-client/test/pom.xml
index b5cfc94ee..a6d110a47 100644
--- a/http-client/test/pom.xml
+++ b/http-client/test/pom.xml
@@ -16,13 +16,13 @@
     
       io.avaje
       avaje-http-client
-      1.21-SNAPSHOT
+      1.22-SNAPSHOT
     
 
     
       io.avaje
       avaje-http-client-gson
-      1.21-SNAPSHOT
+      1.22-SNAPSHOT
     
 
     

From f7909d9398268b248c274b0ddea44090a49bdf30 Mon Sep 17 00:00:00 2001
From: Rob Bygrave 
Date: Fri, 6 Jan 2023 13:28:02 +1300
Subject: [PATCH 0454/1323] No effective change, format only

---
 .../generator/client/ClientMethodWriter.java  |   9 +-
 .../generator/client/ClientProcessor.java     |   1 +
 .../avaje/http/generator/core/JsonBUtil.java  |  16 +-
 .../io/avaje/http/generator/core/UType.java   |  18 ++-
 .../generator/javalin/ControllerWriter.java   |   1 -
 .../generator/javalin/JavalinProcessor.java   |   1 +
 .../helidon/nima/ControllerWriter.java        |   1 -
 .../generator/helidon/nima/NimaProcessor.java |   1 +
 .../src/main/resources/public/openapi.json    | 137 +++++++++++++++++-
 9 files changed, 158 insertions(+), 27 deletions(-)

diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java
index 927ad5fe7..e2d65a4a8 100644
--- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java
+++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java
@@ -152,14 +152,11 @@ void writeGeneric(UType type) {
                   .map(Util::shortName)
                   .collect(Collectors.joining(".class, "));
 
-      writer.append(
-          "Types.newParameterizedType(%s.class, %s.class)", Util.shortName(type.mainType()), params);
+      writer.append("Types.newParameterizedType(%s.class, %s.class)", Util.shortName(type.mainType()), params);
     } else {
       writer.append("%s.class", Util.shortName(type.mainType()));
     }
-    writer.append(");");
-
-    writer.eol();
+    writer.append(");").eol();
   }
 
   private void writeWithHandler() {
@@ -283,4 +280,4 @@ private boolean isHttpResponse(String type0) {
     return type0.equals("java.net.http.HttpResponse");
   }
 
-}
\ No newline at end of file
+}
diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java
index c3f4010bf..f8d416c3e 100644
--- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java
+++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java
@@ -35,6 +35,7 @@ public ClientProcessor() {
       Class.forName("io.avaje.jsonb.Jsonb");
       jsonBOnClassPath = true;
     } catch (final ClassNotFoundException e) {
+      // intentionally ignored
     }
     useJsonB = jsonBOnClassPath;
   }
diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java
index f338f69d0..2cdf22778 100644
--- a/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java
+++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java
@@ -38,7 +38,6 @@ private static void addJsonBodyType(MethodReader methodReader, Consumer a
   }
 
   public static void writeJsonbType(UType type, Append writer) {
-
     writer.append("    this.%sJsonType = jsonB.type(", type.shortName());
     if (!type.isGeneric()) {
       writer.append("%s.class)", Util.shortName(PrimitiveUtil.wrap(type.full())));
@@ -56,13 +55,12 @@ public static void writeJsonbType(UType type, Append writer) {
           writeType(type.paramRaw(), writer);
           writer.append(".map()");
           break;
-        default:
-          {
-            if (type.mainType().contains("java.util"))
-              throw new UnsupportedOperationException(
-                  "Only java.util Map, Set and List are supported JsonB Controller Collection Types");
-            writeType(type, writer);
+        default: {
+          if (type.mainType().contains("java.util")) {
+            throw new UnsupportedOperationException("Only java.util Map, Set and List are supported JsonB Controller Collection Types");
           }
+          writeType(type, writer);
+        }
       }
     }
     writer.append(";").eol();
@@ -76,9 +74,7 @@ static void writeType(UType type, Append writer) {
               .map(Util::shortName)
               .collect(Collectors.joining(".class, "));
 
-      writer.append(
-          "Types.newParameterizedType(%s.class, %s.class))",
-          Util.shortName(type.mainType()), params);
+      writer.append("Types.newParameterizedType(%s.class, %s.class))", Util.shortName(type.mainType()), params);
     } else {
       writer.append("%s.class)", Util.shortName(type.mainType()));
     }
diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java
index e4a4bd20b..6743c189a 100644
--- a/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java
+++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java
@@ -11,7 +11,10 @@ public interface UType {
   static UType parse(TypeMirror type) {
     return Util.parseType(type);
   }
-  /** Create the UType from the given String. */
+
+  /**
+   * Create the UType from the given String.
+   */
   static UType parse(String type) {
     return Util.parse(type);
   }
@@ -52,12 +55,16 @@ default String param1() {
     return null;
   }
 
-  /** Return the raw generic parameter if this UType is a Collection. */
+  /**
+   * Return the raw generic parameter if this UType is a Collection.
+   */
   default UType paramRaw() {
     return null;
   }
 
-  /** Return the raw type. */
+  /**
+   * Return the raw type.
+   */
   String full();
 
   default boolean isGeneric() {
@@ -114,8 +121,8 @@ public String full() {
     @Override
     public Set importTypes() {
       return rawType.startsWith("java.lang.") && rawType.indexOf('.') > -1
-          ? Set.of()
-          : Collections.singleton(rawType.replace("[]", ""));
+        ? Set.of()
+        : Collections.singleton(rawType.replace("[]", ""));
     }
 
     @Override
@@ -154,7 +161,6 @@ class Generic implements UType {
     }
 
     private String extractRawParam() {
-
       switch (mainType()) {
         case "java.util.Set":
         case "java.util.List":
diff --git a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java
index 957c293fb..e0780cdf1 100644
--- a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java
+++ b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java
@@ -89,7 +89,6 @@ private void writeClassStart() {
 
     for (final UType type : jsonTypes.values()) {
       final var typeString = PrimitiveUtil.wrap(type.shortType()).replace(",", ", ");
-
       writer.append("  private final JsonType<%s> %sJsonType;", typeString, type.shortName()).eol();
     }
     writer.eol();
diff --git a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinProcessor.java b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinProcessor.java
index ef65ccdf9..ea13ad250 100644
--- a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinProcessor.java
+++ b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinProcessor.java
@@ -17,6 +17,7 @@ public JavalinProcessor() {
       Class.forName("io.avaje.jsonb.Jsonb");
       jsonBOnClassPath = true;
     } catch (final ClassNotFoundException e) {
+      // intentionally ignored
     }
     useJsonB = jsonBOnClassPath;
   }
diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java
index 03118e01e..c9ec3aaf4 100644
--- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java
+++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java
@@ -93,7 +93,6 @@ private void writeClassStart() {
     }
     for (final UType type : jsonTypes.values()) {
       final var typeString = PrimitiveUtil.wrap(type.shortType()).replace(",", ", ");
-
       writer.append("  private final JsonType<%s> %sJsonType;", typeString, type.shortName()).eol();
     }
     writer.eol();
diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/NimaProcessor.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/NimaProcessor.java
index cf3464093..9860a00d2 100644
--- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/NimaProcessor.java
+++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/NimaProcessor.java
@@ -17,6 +17,7 @@ public NimaProcessor() {
       Class.forName("io.avaje.jsonb.Jsonb");
       jsonBOnClassPath = true;
     } catch (final ClassNotFoundException e) {
+      // intentionally ignored
     }
     jsonB = jsonBOnClassPath;
   }
diff --git a/tests/test-javalin-jsonb/src/main/resources/public/openapi.json b/tests/test-javalin-jsonb/src/main/resources/public/openapi.json
index 212c84cb7..f4ce7754e 100644
--- a/tests/test-javalin-jsonb/src/main/resources/public/openapi.json
+++ b/tests/test-javalin-jsonb/src/main/resources/public/openapi.json
@@ -5,6 +5,10 @@
     "description" : "Example Javalin controllers with Java and Maven",
     "version" : ""
   },
+  "tags" : [ {
+    "name" : "tag1",
+    "description" : "this is added to openapi tags"
+  } ],
   "paths" : {
     "/bars" : {
       "get" : {
@@ -678,6 +682,125 @@
         "deprecated" : true
       }
     },
+    "/openapi/get" : {
+      "get" : {
+        "tags" : [ ],
+        "summary" : "Example of Open API Get (up to the first period is the summary)",
+        "description" : "When using Javalin Context only This Javadoc description is added to the generated openapi.json",
+        "responses" : {
+          "200" : {
+            "description" : "funny phrase (this part of the javadoc is added to the response desc)",
+            "content" : {
+              "text/plain" : {
+                "schema" : {
+                  "type" : "string"
+                }
+              }
+            }
+          }
+        }
+      }
+    },
+    "/openapi/post" : {
+      "post" : {
+        "tags" : [ "tag1" ],
+        "summary" : "Standard Post",
+        "description" : "uses tag annotation to add tags to openapi json",
+        "requestBody" : {
+          "description" : "the body (this is used for generated request body desc)",
+          "content" : {
+            "application/json" : {
+              "schema" : {
+                "$ref" : "#/components/schemas/Person"
+              }
+            }
+          },
+          "required" : true
+        },
+        "responses" : {
+          "200" : {
+            "description" : "overrides @return javadoc description",
+            "content" : {
+              "application/json" : {
+                "schema" : {
+                  "$ref" : "#/components/schemas/Person"
+                }
+              }
+            }
+          },
+          "201" : {
+            "description" : "the response body (from javadoc)",
+            "content" : {
+              "application/json" : {
+                "schema" : {
+                  "$ref" : "#/components/schemas/Person"
+                }
+              }
+            }
+          },
+          "400" : {
+            "description" : "User not found (Will not have an associated response schema)"
+          },
+          "500" : {
+            "description" : "Some other Error (Will have this error class as the response class)",
+            "content" : {
+              "application/json" : {
+                "schema" : {
+                  "$ref" : "#/components/schemas/ErrorResponse"
+                }
+              }
+            }
+          }
+        }
+      }
+    },
+    "/openapi/post1" : {
+      "post" : {
+        "tags" : [ ],
+        "summary" : "Standard Post",
+        "description" : "The Deprecated annotation adds \"deprecacted:true\" to the generated json",
+        "requestBody" : {
+          "description" : "the body",
+          "content" : {
+            "application/json" : {
+              "schema" : {
+                "type" : "array",
+                "items" : {
+                  "$ref" : "#/components/schemas/Person"
+                }
+              }
+            }
+          },
+          "required" : true
+        },
+        "responses" : {
+          "400" : {
+            "description" : "User not found"
+          },
+          "500" : {
+            "description" : "Some other Error",
+            "content" : {
+              "application/json" : {
+                "schema" : {
+                  "$ref" : "#/components/schemas/ErrorResponse"
+                }
+              }
+            }
+          },
+          "201" : {
+            "description" : "the response body (from javadoc)",
+            "content" : {
+              "application/json" : {
+                "schema" : {
+                  "$ref" : "#/components/schemas/Person"
+                }
+              }
+            }
+          }
+        },
+        "deprecated" : true
+      }
+    },
     "/req-scoped" : {
       "get" : {
         "tags" : [ ],
@@ -946,7 +1069,7 @@
               "schema" : {
                 "type" : "array",
                 "items" : {
-                  "$ref" : "#/components/schemas/E"
+                  "$ref" : "#/components/schemas/Person"
                 }
               }
             }
@@ -1116,8 +1239,16 @@
           }
         }
       },
-      "E" : {
-        "type" : "object"
+      "ErrorResponse" : {
+        "type" : "object",
+        "properties" : {
+          "id" : {
+            "type" : "string"
+          },
+          "text" : {
+            "type" : "string"
+          }
+        }
       },
       "GetBeanForm" : {
         "type" : "object",

From fc44373d1402762aa759d3ce797183e1f8bb6a7d Mon Sep 17 00:00:00 2001
From: Rob Bygrave 
Date: Fri, 6 Jan 2023 13:34:10 +1300
Subject: [PATCH 0455/1323] Extract JsonBUtil.detectJsonb() into common core

---
 .../http/generator/client/ClientProcessor.java     | 10 ++--------
 .../io/avaje/http/generator/core/JsonBUtil.java    | 12 ++++++++++++
 .../http/generator/javalin/JavalinProcessor.java   | 14 ++------------
 .../http/generator/helidon/nima/NimaProcessor.java | 14 ++------------
 4 files changed, 18 insertions(+), 32 deletions(-)

diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java
index f8d416c3e..49aba1265 100644
--- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java
+++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java
@@ -2,6 +2,7 @@
 
 import io.avaje.http.api.Client;
 import io.avaje.http.generator.core.ControllerReader;
+import io.avaje.http.generator.core.JsonBUtil;
 import io.avaje.http.generator.core.ProcessingContext;
 
 import javax.annotation.processing.AbstractProcessor;
@@ -30,14 +31,7 @@ public class ClientProcessor extends AbstractProcessor {
   private final boolean useJsonB;
 
   public ClientProcessor() {
-    var jsonBOnClassPath = false;
-    try {
-      Class.forName("io.avaje.jsonb.Jsonb");
-      jsonBOnClassPath = true;
-    } catch (final ClassNotFoundException e) {
-      // intentionally ignored
-    }
-    useJsonB = jsonBOnClassPath;
+    useJsonB = JsonBUtil.detectJsonb();
   }
 
   public ClientProcessor(boolean useJsonb) {
diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java
index 2cdf22778..1b007f693 100644
--- a/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java
+++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java
@@ -8,6 +8,18 @@
 public class JsonBUtil {
   private JsonBUtil() {}
 
+  /**
+   * Return true if avaje-jsonb is detected in the classpath.
+   */
+  public static boolean detectJsonb() {
+    try {
+      Class.forName("io.avaje.jsonb.Jsonb");
+      return true;
+    } catch (final ClassNotFoundException e) {
+      return false;
+    }
+  }
+
   public static Map jsonTypes(ControllerReader reader) {
 
     final Map jsonTypes = new LinkedHashMap<>();
diff --git a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinProcessor.java b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinProcessor.java
index ea13ad250..cbe3c0f27 100644
--- a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinProcessor.java
+++ b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinProcessor.java
@@ -1,9 +1,6 @@
 package io.avaje.http.generator.javalin;
 
-import io.avaje.http.generator.core.BaseProcessor;
-import io.avaje.http.generator.core.ControllerReader;
-import io.avaje.http.generator.core.PlatformAdapter;
-import io.avaje.http.generator.core.ProcessingContext;
+import io.avaje.http.generator.core.*;
 
 import java.io.IOException;
 
@@ -12,14 +9,7 @@ public class JavalinProcessor extends BaseProcessor {
   private final boolean useJsonB;
 
   public JavalinProcessor() {
-    var jsonBOnClassPath = false;
-    try {
-      Class.forName("io.avaje.jsonb.Jsonb");
-      jsonBOnClassPath = true;
-    } catch (final ClassNotFoundException e) {
-      // intentionally ignored
-    }
-    useJsonB = jsonBOnClassPath;
+    useJsonB = JsonBUtil.detectJsonb();
   }
 
   public JavalinProcessor(boolean useJsonb) {
diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/NimaProcessor.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/NimaProcessor.java
index 9860a00d2..67461a37e 100644
--- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/NimaProcessor.java
+++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/NimaProcessor.java
@@ -1,9 +1,6 @@
 package io.avaje.http.generator.helidon.nima;
 
-import io.avaje.http.generator.core.BaseProcessor;
-import io.avaje.http.generator.core.ControllerReader;
-import io.avaje.http.generator.core.PlatformAdapter;
-import io.avaje.http.generator.core.ProcessingContext;
+import io.avaje.http.generator.core.*;
 
 import java.io.IOException;
 
@@ -12,14 +9,7 @@ public class NimaProcessor extends BaseProcessor {
   private final boolean jsonB;
 
   public NimaProcessor() {
-    var jsonBOnClassPath = false;
-    try {
-      Class.forName("io.avaje.jsonb.Jsonb");
-      jsonBOnClassPath = true;
-    } catch (final ClassNotFoundException e) {
-      // intentionally ignored
-    }
-    jsonB = jsonBOnClassPath;
+    jsonB = JsonBUtil.detectJsonb();
   }
 
   public NimaProcessor(boolean useJsonb) {

From 813c97d974d8296b576a2ee46bb49c284d80b21f Mon Sep 17 00:00:00 2001
From: Josiah Noel <32279667+SentryMan@users.noreply.github.com>
Date: Thu, 5 Jan 2023 20:00:00 -0500
Subject: [PATCH 0456/1323] use singleton

---
 .../http/generator/core/BaseProcessor.java      | 17 ++++++++++-------
 .../io/avaje/http/generator/core/Constants.java |  2 +-
 .../http/generator/core/ControllerReader.java   |  3 ++-
 .../http/generator/core/ProcessingContext.java  |  6 ++++++
 .../generator/helidon/ControllerWriter.java     |  2 +-
 .../generator/javalin/ControllerWriter.java     |  2 +-
 .../helidon/nima/ControllerWriter.java          |  2 +-
 7 files changed, 22 insertions(+), 12 deletions(-)

diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java
index 228cf923a..03507e519 100644
--- a/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java
+++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java
@@ -1,20 +1,23 @@
 package io.avaje.http.generator.core;
 
-import io.avaje.http.api.Controller;
-import io.swagger.v3.oas.annotations.OpenAPIDefinition;
-import io.swagger.v3.oas.annotations.tags.Tag;
-import io.swagger.v3.oas.annotations.tags.Tags;
+import java.io.IOException;
+import java.util.LinkedHashSet;
+import java.util.Set;
 
 import javax.annotation.processing.AbstractProcessor;
 import javax.annotation.processing.ProcessingEnvironment;
 import javax.annotation.processing.RoundEnvironment;
+import javax.annotation.processing.SupportedOptions;
 import javax.lang.model.SourceVersion;
 import javax.lang.model.element.Element;
 import javax.lang.model.element.TypeElement;
-import java.io.IOException;
-import java.util.LinkedHashSet;
-import java.util.Set;
 
+import io.avaje.http.api.Controller;
+import io.swagger.v3.oas.annotations.OpenAPIDefinition;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import io.swagger.v3.oas.annotations.tags.Tags;
+
+@SupportedOptions({"useJavax"})
 public abstract class BaseProcessor extends AbstractProcessor {
 
   protected ProcessingContext ctx;
diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/Constants.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/Constants.java
index d27afc336..984889080 100644
--- a/http-generator-core/src/main/java/io/avaje/http/generator/core/Constants.java
+++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/Constants.java
@@ -10,7 +10,7 @@ public class Constants {
 
   static final String OPENAPIDEFINITION = "io.swagger.v3.oas.annotations.OpenAPIDefinition";
 
-  static final String COMPONENT = "io.avaje.inject.Component";
+  static final String SINGLETON = "jakarta.inject.Singleton";
 
   static final String IMPORT_PATH_TYPE_CONVERT = "import static io.avaje.http.api.PathTypeConversion.*;";
 
diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java
index 516587209..ee3294ea5 100644
--- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java
+++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java
@@ -67,7 +67,8 @@ protected void addImports(boolean withSingleton) {
       importTypes.add(Constants.VALIDATOR);
     }
     if (withSingleton) {
-      importTypes.add(Constants.COMPONENT);
+      importTypes.add(
+          ctx.useJavax() ? Constants.SINGLETON.replace("jakarta", "javax") : Constants.SINGLETON);
     }
   }
 
diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java
index 9ae147c9c..5c02f0f98 100644
--- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java
+++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java
@@ -26,6 +26,7 @@ public class ProcessingContext {
   private final Types types;
   private final boolean openApiAvailable;
   private final DocContext docContext;
+  private final boolean useJavax;
 
   public ProcessingContext(ProcessingEnvironment env, PlatformAdapter readAdapter) {
     this.readAdapter = readAdapter;
@@ -35,6 +36,7 @@ public ProcessingContext(ProcessingEnvironment env, PlatformAdapter readAdapter)
     this.types = env.getTypeUtils();
     this.openApiAvailable = isTypeAvailable(Constants.OPENAPIDEFINITION);
     this.docContext = new DocContext(env, openApiAvailable);
+    this.useJavax= Boolean.parseBoolean(env.getOptions().get("useJavax"));
   }
 
   private boolean isTypeAvailable(String canonicalName) {
@@ -86,4 +88,8 @@ public TypeMirror asMemberOf(DeclaredType declaredType, Element element) {
   public PlatformAdapter platform() {
     return readAdapter;
   }
+
+  public boolean useJavax() {
+    return useJavax;
+  }
 }
diff --git a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/ControllerWriter.java b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/ControllerWriter.java
index b54b70b56..0b55df326 100644
--- a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/ControllerWriter.java
+++ b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/ControllerWriter.java
@@ -60,7 +60,7 @@ private void writeRoutes(List methods) {
 
   private void writeClassStart() {
     writer.append(AT_GENERATED).eol();
-    writer.append("@Component").eol();
+    writer.append("@Singleton").eol();
     writer.append("public class ").append(shortName).append("$Route implements Service {").eol().eol();
 
     String controllerName = "controller";
diff --git a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java
index 7f19e1ccc..276223421 100644
--- a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java
+++ b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java
@@ -56,7 +56,7 @@ private void writeForMethod(MethodReader method) {
 
   private void writeClassStart() {
     writer.append(AT_GENERATED).eol();
-    writer.append("@Component").eol();
+    writer.append("@Singleton").eol();
     writer
       .append("public class ")
       .append(shortName)
diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java
index 1d78d70ab..822fa642a 100644
--- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java
+++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java
@@ -72,7 +72,7 @@ private void writeRoutes(List methods) {
 
   private void writeClassStart() {
     writer.append(AT_GENERATED).eol();
-    writer.append("@Component").eol();
+    writer.append("@Singleton").eol();
     writer.append("public class %s$Route implements HttpService {", shortName).eol().eol();
 
     var controllerName = "controller";

From d94bf91dc5aa7eadca5f58922ca90a0f3bd682b7 Mon Sep 17 00:00:00 2001
From: Josiah Noel <32279667+SentryMan@users.noreply.github.com>
Date: Thu, 5 Jan 2023 19:06:31 -0600
Subject: [PATCH 0457/1323] Update README.md

---
 README.md | 20 ++++++++++++++++----
 1 file changed, 16 insertions(+), 4 deletions(-)

diff --git a/README.md b/README.md
index 60334e3a2..c5d1d21b0 100644
--- a/README.md
+++ b/README.md
@@ -98,7 +98,19 @@ public class WidgetController {
   record Widget(int id, String name){};
 }
 ```
-
+## @Singleton
+By default the generated classes will use jakarta.inject.Singleton for wiring. To use Javax Inject, use the compiler arg `-AuseJavax=true` 
+```
+  
+		 org.apache.maven.plugins
+			maven-compiler-plugin
+			
+				
+					-AuseJavax=true
+				
+			
+	 
+```
 ## Usage
 The annotation processor will generate controller adapters that can register routes to Javalin/Helidon. The natural way to use the generated adapters is to get a DI library to find and wire them. This is what the below examples do and they use [Avaje-Inject](https://avaje.io/inject/) to do this.
 
@@ -156,7 +168,7 @@ WebServer.builder()
 
 ```java
 @Generated("avaje-javalin-generator")
-@Component
+@Singleton
 public class WidgetController$Route implements WebRoutes {
 
   private final WidgetController controller;
@@ -188,7 +200,7 @@ public class WidgetController$Route implements WebRoutes {
 
 ### (Helidon SE) The generated WidgetController$Route.java is:
 ```java
-@Generated("io.dinject.helidon-generator")
+@Generated("avaje-helidon-generator")
 @Singleton
 public class WidgetController$Route implements Service {
 
@@ -221,7 +233,7 @@ public class WidgetController$Route implements Service {
 
 ```java
 @Generated("avaje-helidon-nima-generator")
-@Component
+@Singleton
 public class WidgetController$Route implements HttpService {
 
   private final WidgetController controller;

From 59997c439fd6a704671e04daff76c8a4eafbe14d Mon Sep 17 00:00:00 2001
From: Josiah Noel <32279667+SentryMan@users.noreply.github.com>
Date: Thu, 5 Jan 2023 19:07:41 -0600
Subject: [PATCH 0458/1323] Update README.md

---
 README.md | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/README.md b/README.md
index c5d1d21b0..6530dc74e 100644
--- a/README.md
+++ b/README.md
@@ -101,15 +101,15 @@ public class WidgetController {
 ## @Singleton
 By default the generated classes will use jakarta.inject.Singleton for wiring. To use Javax Inject, use the compiler arg `-AuseJavax=true` 
 ```
-  
-		 org.apache.maven.plugins
-			maven-compiler-plugin
-			
-				
-					-AuseJavax=true
-				
-			
-	 
+			
+				org.apache.maven.plugins
+				maven-compiler-plugin
+				
+					
+						-AuseJavax=true
+					
+				
+			 
 ```
 ## Usage
 The annotation processor will generate controller adapters that can register routes to Javalin/Helidon. The natural way to use the generated adapters is to get a DI library to find and wire them. This is what the below examples do and they use [Avaje-Inject](https://avaje.io/inject/) to do this.

From 819e63fcf7ca06a381c672d717a1fa143f998a7d Mon Sep 17 00:00:00 2001
From: Josiah Noel <32279667+SentryMan@users.noreply.github.com>
Date: Thu, 5 Jan 2023 20:11:40 -0500
Subject: [PATCH 0459/1323] forgot jex was a thing

---
 .../main/java/io/avaje/http/generator/jex/ControllerWriter.java | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerWriter.java b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerWriter.java
index cd5fc108d..4961604bc 100644
--- a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerWriter.java
+++ b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerWriter.java
@@ -47,7 +47,7 @@ private void writeForMethod(MethodReader method) {
 
   private void writeClassStart() {
     writer.append(AT_GENERATED).eol();
-    writer.append("@Component").eol();
+    writer.append("@Singleton").eol();
     writer.append("public class ").append(shortName).append("$Route implements Routing.Service {").eol().eol();
 
     String controllerName = "controller";

From d59586ad9849d9f464444e4d4dc329ed90c2d8fc Mon Sep 17 00:00:00 2001
From: Josiah Noel <32279667+SentryMan@users.noreply.github.com>
Date: Thu, 5 Jan 2023 22:49:05 -0500
Subject: [PATCH 0460/1323] detect avaje

---
 .../avaje/http/generator/core/Constants.java  |  1 +
 .../http/generator/core/ControllerReader.java |  8 +++++--
 .../generator/core/ProcessingContext.java     | 23 +++++++++++++++----
 .../generator/helidon/ControllerWriter.java   |  2 +-
 .../generator/javalin/ControllerWriter.java   |  2 +-
 .../http/generator/jex/ControllerWriter.java  |  2 +-
 .../helidon/nima/ControllerWriter.java        |  2 +-
 7 files changed, 29 insertions(+), 11 deletions(-)

diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/Constants.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/Constants.java
index 984889080..1babcbcf2 100644
--- a/http-generator-core/src/main/java/io/avaje/http/generator/core/Constants.java
+++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/Constants.java
@@ -9,6 +9,7 @@ public class Constants {
   public static final String FACTORY_SUFFIX = "$Factory";
 
   static final String OPENAPIDEFINITION = "io.swagger.v3.oas.annotations.OpenAPIDefinition";
+  static final String COMPONENT = "io.avaje.inject.Component";
 
   static final String SINGLETON = "jakarta.inject.Singleton";
 
diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java
index ee3294ea5..f950fbf85 100644
--- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java
+++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java
@@ -67,8 +67,12 @@ protected void addImports(boolean withSingleton) {
       importTypes.add(Constants.VALIDATOR);
     }
     if (withSingleton) {
-      importTypes.add(
-          ctx.useJavax() ? Constants.SINGLETON.replace("jakarta", "javax") : Constants.SINGLETON);
+      if (ctx.isAvajeAvailable()) {
+        importTypes.add(Constants.COMPONENT);
+      } else {
+        importTypes.add(
+            ctx.useJavax() ? Constants.SINGLETON.replace("jakarta", "javax") : Constants.SINGLETON);
+      }
     }
   }
 
diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java
index 5c02f0f98..4dc595a31 100644
--- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java
+++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java
@@ -1,6 +1,6 @@
 package io.avaje.http.generator.core;
 
-import io.avaje.http.generator.core.openapi.DocContext;
+import java.io.IOException;
 
 import javax.annotation.processing.Filer;
 import javax.annotation.processing.Messager;
@@ -15,7 +15,8 @@
 import javax.tools.FileObject;
 import javax.tools.JavaFileObject;
 import javax.tools.StandardLocation;
-import java.io.IOException;
+
+import io.avaje.http.generator.core.openapi.DocContext;
 
 public class ProcessingContext {
 
@@ -26,7 +27,9 @@ public class ProcessingContext {
   private final Types types;
   private final boolean openApiAvailable;
   private final DocContext docContext;
+  private final boolean avajeAvailable;
   private final boolean useJavax;
+  private final String diAnnotation;
 
   public ProcessingContext(ProcessingEnvironment env, PlatformAdapter readAdapter) {
     this.readAdapter = readAdapter;
@@ -35,8 +38,10 @@ public ProcessingContext(ProcessingEnvironment env, PlatformAdapter readAdapter)
     this.elements = env.getElementUtils();
     this.types = env.getTypeUtils();
     this.openApiAvailable = isTypeAvailable(Constants.OPENAPIDEFINITION);
+    this.avajeAvailable = isTypeAvailable(Constants.COMPONENT);
     this.docContext = new DocContext(env, openApiAvailable);
-    this.useJavax= Boolean.parseBoolean(env.getOptions().get("useJavax"));
+    this.useJavax = Boolean.parseBoolean(env.getOptions().get("useJavax"));
+    this.diAnnotation = avajeAvailable ? "@Component" : "@Singleton";
   }
 
   private boolean isTypeAvailable(String canonicalName) {
@@ -51,6 +56,14 @@ public boolean isOpenApiAvailable() {
     return openApiAvailable;
   }
 
+  public boolean useJavax() {
+    return useJavax;
+  }
+
+  public boolean isAvajeAvailable() {
+    return avajeAvailable;
+  }
+
   public void logError(Element e, String msg, Object... args) {
     messager.printMessage(Diagnostic.Kind.ERROR, String.format(msg, args), e);
   }
@@ -89,7 +102,7 @@ public PlatformAdapter platform() {
     return readAdapter;
   }
 
-  public boolean useJavax() {
-    return useJavax;
+  public String getDiAnnotation() {
+    return diAnnotation;
   }
 }
diff --git a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/ControllerWriter.java b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/ControllerWriter.java
index 0b55df326..1092caf0a 100644
--- a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/ControllerWriter.java
+++ b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/ControllerWriter.java
@@ -60,7 +60,7 @@ private void writeRoutes(List methods) {
 
   private void writeClassStart() {
     writer.append(AT_GENERATED).eol();
-    writer.append("@Singleton").eol();
+    writer.append(ctx.getDiAnnotation()).eol();
     writer.append("public class ").append(shortName).append("$Route implements Service {").eol().eol();
 
     String controllerName = "controller";
diff --git a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java
index da0161d15..b3b2d4b90 100644
--- a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java
+++ b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java
@@ -67,7 +67,7 @@ private void writeForMethod(MethodReader method) {
 
   private void writeClassStart() {
     writer.append(AT_GENERATED).eol();
-    writer.append("@Singleton").eol();
+    writer.append(ctx.getDiAnnotation()).eol();
     writer
       .append("public class ")
       .append(shortName)
diff --git a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerWriter.java b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerWriter.java
index 4961604bc..65f711158 100644
--- a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerWriter.java
+++ b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerWriter.java
@@ -47,7 +47,7 @@ private void writeForMethod(MethodReader method) {
 
   private void writeClassStart() {
     writer.append(AT_GENERATED).eol();
-    writer.append("@Singleton").eol();
+    writer.append(ctx.getDiAnnotation()).eol();
     writer.append("public class ").append(shortName).append("$Route implements Routing.Service {").eol().eol();
 
     String controllerName = "controller";
diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java
index 3bc138510..f648c8d91 100644
--- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java
+++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java
@@ -77,7 +77,7 @@ private void writeRoutes(List methods) {
 
   private void writeClassStart() {
     writer.append(AT_GENERATED).eol();
-    writer.append("@Singleton").eol();
+    writer.append(ctx.getDiAnnotation()).eol();
     writer.append("public class %s$Route implements HttpService {", shortName).eol().eol();
 
     var controllerName = "controller";

From d37a20afb51a72199c48907b0211c5d04d9b4b38 Mon Sep 17 00:00:00 2001
From: Josiah Noel <32279667+SentryMan@users.noreply.github.com>
Date: Thu, 5 Jan 2023 21:58:19 -0600
Subject: [PATCH 0461/1323] Update README.md

---
 README.md | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/README.md b/README.md
index 6530dc74e..e7aa03a05 100644
--- a/README.md
+++ b/README.md
@@ -98,8 +98,12 @@ public class WidgetController {
   record Widget(int id, String name){};
 }
 ```
-## @Singleton
-By default the generated classes will use jakarta.inject.Singleton for wiring. To use Javax Inject, use the compiler arg `-AuseJavax=true` 
+## DI Usage
+The annotation processor will generate controller adapters that can register routes to Javalin/Helidon. The natural way to use the generated adapters is to get a DI library to find and wire them. This is what the below examples do and they use [Avaje-Inject](https://avaje.io/inject/) to do this. The AP will automatically detect the presence of avaje-inject and generate the class to use avaje-inject's `@Component` as the DI annotation.
+
+There isn't a hard requirement to use Avaje for dependency injection. In the absence of avaje-inject the generated class will default to use `@jakarta.inject.Singleton`. Any DI library that can find and wire the generated @Singleton beans can be used. You can even use Dagger2 or Guice to wire the controllers if you so desire. 
+
+To have the AP generate using `@javax.inject.Singleton`, use the compiler arg `-AuseJavax=true` 
 ```
 			
 				org.apache.maven.plugins
@@ -111,10 +115,6 @@ By default the generated classes will use jakarta.inject.Singleton for wiring. T
 				
 			 
 ```
-## Usage
-The annotation processor will generate controller adapters that can register routes to Javalin/Helidon. The natural way to use the generated adapters is to get a DI library to find and wire them. This is what the below examples do and they use [Avaje-Inject](https://avaje.io/inject/) to do this.
-
-Note that there isn't a requirement to use Avaje for dependency injection. Any DI library that can find and wire the generated @Singleton beans can be used. You can even use Dagger2 or Guice to wire the controllers if you so desire.
 
 ### Usage with Javalin
 

From ac7cc60489121e5f20d66334e2ab7ef42d3b5f47 Mon Sep 17 00:00:00 2001
From: Josiah Noel <32279667+SentryMan@users.noreply.github.com>
Date: Thu, 5 Jan 2023 23:12:23 -0500
Subject: [PATCH 0462/1323] only default if both

---
 .../http/generator/core/ProcessingContext.java     | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java
index 4dc595a31..11c264a52 100644
--- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java
+++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java
@@ -39,9 +39,19 @@ public ProcessingContext(ProcessingEnvironment env, PlatformAdapter readAdapter)
     this.types = env.getTypeUtils();
     this.openApiAvailable = isTypeAvailable(Constants.OPENAPIDEFINITION);
     this.avajeAvailable = isTypeAvailable(Constants.COMPONENT);
-    this.docContext = new DocContext(env, openApiAvailable);
-    this.useJavax = Boolean.parseBoolean(env.getOptions().get("useJavax"));
     this.diAnnotation = avajeAvailable ? "@Component" : "@Singleton";
+
+    this.docContext = new DocContext(env, openApiAvailable);
+
+    final var javax = isTypeAvailable(Constants.SINGLETON.replace("jakarta", "javax"));
+    final var jakarta = isTypeAvailable(Constants.SINGLETON);
+    if (javax && jakarta) {
+      this.useJavax = Boolean.parseBoolean(env.getOptions().get("useJavax"));
+    } else if (jakarta) {
+      this.useJavax = false;
+    } else {
+      useJavax = true;
+    }
   }
 
   private boolean isTypeAvailable(String canonicalName) {

From 1d85a65d4b811c46d625176d6272c96834dbcc05 Mon Sep 17 00:00:00 2001
From: Josiah Noel <32279667+SentryMan@users.noreply.github.com>
Date: Thu, 5 Jan 2023 23:14:57 -0500
Subject: [PATCH 0463/1323] Update ProcessingContext.java

---
 .../io/avaje/http/generator/core/ProcessingContext.java     | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java
index 11c264a52..02be705d1 100644
--- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java
+++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java
@@ -47,10 +47,10 @@ public ProcessingContext(ProcessingEnvironment env, PlatformAdapter readAdapter)
     final var jakarta = isTypeAvailable(Constants.SINGLETON);
     if (javax && jakarta) {
       this.useJavax = Boolean.parseBoolean(env.getOptions().get("useJavax"));
-    } else if (jakarta) {
-      this.useJavax = false;
+    } else if (javax) {
+      this.useJavax = true;
     } else {
-      useJavax = true;
+      useJavax = false;
     }
   }
 

From 635b6e640b50a4dcbb1de57bc6682e3c2e164925 Mon Sep 17 00:00:00 2001
From: Josiah Noel <32279667+SentryMan@users.noreply.github.com>
Date: Thu, 5 Jan 2023 23:18:08 -0500
Subject: [PATCH 0464/1323] Update ProcessingContext.java

---
 .../io/avaje/http/generator/core/ProcessingContext.java     | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java
index 02be705d1..a7295786b 100644
--- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java
+++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java
@@ -45,7 +45,11 @@ public ProcessingContext(ProcessingEnvironment env, PlatformAdapter readAdapter)
 
     final var javax = isTypeAvailable(Constants.SINGLETON.replace("jakarta", "javax"));
     final var jakarta = isTypeAvailable(Constants.SINGLETON);
-    if (javax && jakarta) {
+    final var override = Boolean.getBoolean(env.getOptions().get("useJavax"));
+
+    if (override) {
+      this.useJavax = override;
+    } else if (javax && jakarta) {
       this.useJavax = Boolean.parseBoolean(env.getOptions().get("useJavax"));
     } else if (javax) {
       this.useJavax = true;

From 62d8d1470df9ccc97bb210a44df51170048d146d Mon Sep 17 00:00:00 2001
From: Josiah Noel <32279667+SentryMan@users.noreply.github.com>
Date: Thu, 5 Jan 2023 22:20:32 -0600
Subject: [PATCH 0465/1323] Update README.md

---
 README.md | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/README.md b/README.md
index e7aa03a05..573ceb650 100644
--- a/README.md
+++ b/README.md
@@ -101,9 +101,9 @@ public class WidgetController {
 ## DI Usage
 The annotation processor will generate controller adapters that can register routes to Javalin/Helidon. The natural way to use the generated adapters is to get a DI library to find and wire them. This is what the below examples do and they use [Avaje-Inject](https://avaje.io/inject/) to do this. The AP will automatically detect the presence of avaje-inject and generate the class to use avaje-inject's `@Component` as the DI annotation.
 
-There isn't a hard requirement to use Avaje for dependency injection. In the absence of avaje-inject the generated class will default to use `@jakarta.inject.Singleton`. Any DI library that can find and wire the generated @Singleton beans can be used. You can even use Dagger2 or Guice to wire the controllers if you so desire. 
+There isn't a hard requirement to use Avaje for dependency injection. In the absence of avaje-inject the generated class will use `@jakarta.inject.Singleton` or `@javax.inject.Singleton` depending on what's on the classpath. Any DI library that can find and wire the generated @Singleton beans can be used. You can even use Dagger2 or Guice to wire the controllers if you so desire. 
 
-To have the AP generate using `@javax.inject.Singleton`, use the compiler arg `-AuseJavax=true` 
+To force the AP to generate with `@javax.inject.Singleton`(in the case where you have both jakarta and javax on the classpath), use the compiler arg `-AuseJavax=true` 
 ```
 			
 				org.apache.maven.plugins

From 1b0b07f7323c5280010da28f0973c0ea9b5af21c Mon Sep 17 00:00:00 2001
From: Josiah Noel <32279667+SentryMan@users.noreply.github.com>
Date: Thu, 5 Jan 2023 23:22:03 -0500
Subject: [PATCH 0466/1323] Update ProcessingContext.java

---
 .../java/io/avaje/http/generator/core/ProcessingContext.java  | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java
index a7295786b..263899d6f 100644
--- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java
+++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java
@@ -47,10 +47,8 @@ public ProcessingContext(ProcessingEnvironment env, PlatformAdapter readAdapter)
     final var jakarta = isTypeAvailable(Constants.SINGLETON);
     final var override = Boolean.getBoolean(env.getOptions().get("useJavax"));
 
-    if (override) {
+    if (override || (javax && jakarta)) {
       this.useJavax = override;
-    } else if (javax && jakarta) {
-      this.useJavax = Boolean.parseBoolean(env.getOptions().get("useJavax"));
     } else if (javax) {
       this.useJavax = true;
     } else {

From 72cfe80b5fe15c019f485c7fec22e85275af17a6 Mon Sep 17 00:00:00 2001
From: Josiah Noel <32279667+SentryMan@users.noreply.github.com>
Date: Thu, 5 Jan 2023 22:30:41 -0600
Subject: [PATCH 0467/1323] Update README.md

---
 README.md | 1 +
 1 file changed, 1 insertion(+)

diff --git a/README.md b/README.md
index 573ceb650..5ea96044a 100644
--- a/README.md
+++ b/README.md
@@ -68,6 +68,7 @@ If there are other annotation processors and they are specified via maven-com
   
 
 ```
+
 ## Define a Controller (These APT processors work with both Java and Kotlin.)
 ```java
 package org.example.hello;

From 35e54fd18acb74f4b2ed063b57664b22751bb4b0 Mon Sep 17 00:00:00 2001
From: Josiah Noel <32279667+SentryMan@users.noreply.github.com>
Date: Fri, 6 Jan 2023 15:01:45 -0500
Subject: [PATCH 0468/1323] Create MatrixParam

---
 .../java/io/avaje/http/api/MatrixParam.java   | 23 +++++++++++++++++++
 .../http/generator/core/ElementReader.java    | 20 +++++++++++++---
 .../http/generator/core/PathSegments.java     | 13 ++++++++---
 .../myapp/web/test/TestController.java        | 13 +++++++++++
 4 files changed, 63 insertions(+), 6 deletions(-)
 create mode 100644 http-api/src/main/java/io/avaje/http/api/MatrixParam.java

diff --git a/http-api/src/main/java/io/avaje/http/api/MatrixParam.java b/http-api/src/main/java/io/avaje/http/api/MatrixParam.java
new file mode 100644
index 000000000..71d0ad500
--- /dev/null
+++ b/http-api/src/main/java/io/avaje/http/api/MatrixParam.java
@@ -0,0 +1,23 @@
+package io.avaje.http.api;
+
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+/** Marks a method parameter to be a matrix parameter. */
+@Target(value = {PARAMETER})
+@Retention(value = RUNTIME)
+public @interface MatrixParam {
+
+  /**
+   * The name of the matrix parameter.
+   *
+   * 

If left blank the method parameter name is used. + * + *

We typically use this when the matrix parameter uses snake-case or similar that does not map + * to a valid java/kotlin parameter name. + */ + String value() default ""; +} diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java index 09dd97d76..d09e1d2b8 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java @@ -26,6 +26,7 @@ public class ElementReader { private String paramName; private ParamType paramType; + private String matrixParam; private boolean impliedParamType; private String paramDefault; @@ -110,6 +111,15 @@ private void readAnnotations(Element element, ParamType defaultType) { this.paramDefault = null; return; } + + MatrixParam matrixParam = element.getAnnotation(MatrixParam.class); + if (matrixParam != null) { + this.matrixParam = nameFrom(matrixParam.value(), varName); + this.paramType = defaultType; + this.impliedParamType = true; + return; + } + if (paramType == null) { this.impliedParamType = true; if (typeHandler != null) { @@ -235,15 +245,19 @@ private boolean setValue(Append writer, PathSegments segments, String shortType) return false; } if (impliedParamType) { - PathSegments.Segment segment = segments.segment(varName); + var name = matrixParam != null ? matrixParam : varName; + PathSegments.Segment segment = segments.segment(name); if (segment != null) { // path or matrix parameter boolean requiredParam = segment.isRequired(varName); - String asMethod = (typeHandler == null) ? null : (requiredParam) ? typeHandler.asMethod() : typeHandler.toMethod(); + String asMethod = + (typeHandler == null) + ? null + : (requiredParam) ? typeHandler.asMethod() : typeHandler.toMethod(); if (asMethod != null) { writer.append(asMethod); } - segment.writeGetVal(writer, varName, ctx.platform()); + segment.writeGetVal(writer, name, ctx.platform()); if (asMethod != null) { writer.append(")"); } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/PathSegments.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/PathSegments.java index 6145fcd69..33fb33630 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/PathSegments.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/PathSegments.java @@ -7,6 +7,7 @@ import java.util.LinkedHashSet; import java.util.List; import java.util.Set; +import java.util.regex.Pattern; public class PathSegments { @@ -132,7 +133,9 @@ public boolean isEmpty() { public static class Segment { - private final String name; + private static final Pattern PATTERN = Pattern.compile("[^a-zA-Z0-9_]|\\s"); + private final String name; + private final String sanitizedName; private final String literalSection; /** @@ -150,6 +153,7 @@ public static class Segment { */ Segment(String name) { this.name = name; + this.sanitizedName = PATTERN.matcher(name).replaceAll("_"); this.literalSection = null; this.matrixKeys = null; this.matrixVarNames = null; @@ -160,6 +164,7 @@ public static class Segment { */ Segment(String name, Set matrixKeys) { this.name = name; + this.sanitizedName = PATTERN.matcher(name).replaceAll("_"); this.literalSection = null; this.matrixKeys = matrixKeys; this.matrixVarNames = new HashSet<>(); @@ -172,8 +177,10 @@ public static class Segment { * Create a literal path segment. */ public Segment(String section, boolean literalDummy) { + this.literalSection = section; this.name = null; + this.sanitizedName = null; this.matrixKeys = null; this.matrixVarNames = null; } @@ -219,7 +226,7 @@ void writeGetVal(Append writer, String varName, PlatformAdapter platform) { if (!hasMatrixParams()) { platform.writeReadParameter(writer, ParamType.PATHPARAM, name); } else { - writer.append("%s_segment.", name); + writer.append("%s_segment.", sanitizedName); if (name.equals(varName)) { writer.append("val()"); } else { @@ -238,7 +245,7 @@ private String matrixKey(String varName) { public void writeCreateSegment(Append writer, PlatformAdapter platform) { writer.append(platform.indent()); - writer.append(" PathSegment %s_segment = PathSegment.of(", name); + writer.append(" PathSegment %s_segment = PathSegment.of(", sanitizedName); platform.writeReadParameter(writer, ParamType.PATHPARAM, name + "_segment"); writer.append(");").eol(); } diff --git a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController.java index 9e2b64468..eec28ffcc 100644 --- a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController.java +++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController.java @@ -13,7 +13,9 @@ import io.avaje.http.api.Post; import io.avaje.http.api.Produces; import io.avaje.http.api.Put; +import io.avaje.http.api.MatrixParam; import io.javalin.http.Context; + @Path("test/") @Controller public class TestController { @@ -105,4 +107,15 @@ String testForm(String name, String email, String url) { String testFormBean(MyForm form) { return form.name + "|" + form.email + "|" + form.url; } + + @Get("/withMatrixParam/{type-1;category;vendor-34}/{range;style}") + void neo( + @MatrixParam("type-1") String type, + String category, + @MatrixParam("vendor-34") String vendor, + String range, + String style) { + + System.out.println("Ever have that feeling where you're not sure if you're awake or dreaming?"); + } } From 1f7df4d7ee53dc6729758e45f003b733f01af9c9 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Fri, 6 Jan 2023 15:17:28 -0500 Subject: [PATCH 0469/1323] Update ElementReader.java --- .../java/io/avaje/http/generator/core/ElementReader.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java index d09e1d2b8..c9e68a774 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java @@ -26,7 +26,7 @@ public class ElementReader { private String paramName; private ParamType paramType; - private String matrixParam; + private String matrixParamName; private boolean impliedParamType; private String paramDefault; @@ -114,7 +114,7 @@ private void readAnnotations(Element element, ParamType defaultType) { MatrixParam matrixParam = element.getAnnotation(MatrixParam.class); if (matrixParam != null) { - this.matrixParam = nameFrom(matrixParam.value(), varName); + this.matrixParamName = nameFrom(matrixParam.value(), varName); this.paramType = defaultType; this.impliedParamType = true; return; @@ -245,7 +245,7 @@ private boolean setValue(Append writer, PathSegments segments, String shortType) return false; } if (impliedParamType) { - var name = matrixParam != null ? matrixParam : varName; + var name = matrixParamName != null ? matrixParamName : varName; PathSegments.Segment segment = segments.segment(name); if (segment != null) { // path or matrix parameter From 8d85eca4b20495de988a9d3a3a158f8f53ae3232 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Fri, 6 Jan 2023 17:14:30 -0500 Subject: [PATCH 0470/1323] Update PathSegments.java --- .../java/io/avaje/http/generator/core/PathSegments.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/PathSegments.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/PathSegments.java index 33fb33630..cd2a70fb7 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/PathSegments.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/PathSegments.java @@ -133,9 +133,9 @@ public boolean isEmpty() { public static class Segment { - private static final Pattern PATTERN = Pattern.compile("[^a-zA-Z0-9_]|\\s"); - private final String name; - private final String sanitizedName; + private static final Pattern PATTERN = Pattern.compile("[^a-zA-Z0-9_]|\\s"); + private final String name; + private final String sanitizedName; private final String literalSection; /** From 9da2811ea3503224ba73ec1b6ba08a3f4b450316 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sat, 7 Jan 2023 00:46:45 -0500 Subject: [PATCH 0471/1323] javax constant --- .../src/main/java/io/avaje/http/generator/core/Constants.java | 3 ++- .../java/io/avaje/http/generator/core/ControllerReader.java | 3 +-- .../java/io/avaje/http/generator/core/ProcessingContext.java | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/Constants.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/Constants.java index 1babcbcf2..ebe5d7ec2 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/Constants.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/Constants.java @@ -11,7 +11,8 @@ public class Constants { static final String OPENAPIDEFINITION = "io.swagger.v3.oas.annotations.OpenAPIDefinition"; static final String COMPONENT = "io.avaje.inject.Component"; - static final String SINGLETON = "jakarta.inject.Singleton"; + static final String SINGLETON_JAKARTA = "jakarta.inject.Singleton"; + static final String SINGLETON_JAVAX = "javax.inject.Singleton"; static final String IMPORT_PATH_TYPE_CONVERT = "import static io.avaje.http.api.PathTypeConversion.*;"; diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java index f950fbf85..bf5cb8af5 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java @@ -70,8 +70,7 @@ protected void addImports(boolean withSingleton) { if (ctx.isAvajeAvailable()) { importTypes.add(Constants.COMPONENT); } else { - importTypes.add( - ctx.useJavax() ? Constants.SINGLETON.replace("jakarta", "javax") : Constants.SINGLETON); + importTypes.add(ctx.useJavax() ? Constants.SINGLETON_JAVAX : Constants.SINGLETON_JAKARTA); } } } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java index 263899d6f..f73e89133 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java @@ -43,8 +43,8 @@ public ProcessingContext(ProcessingEnvironment env, PlatformAdapter readAdapter) this.docContext = new DocContext(env, openApiAvailable); - final var javax = isTypeAvailable(Constants.SINGLETON.replace("jakarta", "javax")); - final var jakarta = isTypeAvailable(Constants.SINGLETON); + final var javax = isTypeAvailable(Constants.SINGLETON_JAVAX); + final var jakarta = isTypeAvailable(Constants.SINGLETON_JAKARTA); final var override = Boolean.getBoolean(env.getOptions().get("useJavax")); if (override || (javax && jakarta)) { From 8d07f20114d464e6ac0e405b6e9375bdce8a7984 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sat, 7 Jan 2023 00:52:53 -0500 Subject: [PATCH 0472/1323] rename --- .../http/generator/core/ControllerReader.java | 2 +- .../generator/core/ProcessingContext.java | 19 +++++++++---------- .../generator/helidon/ControllerWriter.java | 2 +- .../generator/javalin/ControllerWriter.java | 2 +- .../helidon/nima/ControllerWriter.java | 2 +- 5 files changed, 13 insertions(+), 14 deletions(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java index bf5cb8af5..1e711199c 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java @@ -67,7 +67,7 @@ protected void addImports(boolean withSingleton) { importTypes.add(Constants.VALIDATOR); } if (withSingleton) { - if (ctx.isAvajeAvailable()) { + if (ctx.useComponent()) { importTypes.add(Constants.COMPONENT); } else { importTypes.add(ctx.useJavax() ? Constants.SINGLETON_JAVAX : Constants.SINGLETON_JAKARTA); diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java index f73e89133..00d5c9caa 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java @@ -27,9 +27,9 @@ public class ProcessingContext { private final Types types; private final boolean openApiAvailable; private final DocContext docContext; - private final boolean avajeAvailable; + private final boolean useComponent; private final boolean useJavax; - private final String diAnnotation; + private final String annotationDI; public ProcessingContext(ProcessingEnvironment env, PlatformAdapter readAdapter) { this.readAdapter = readAdapter; @@ -38,11 +38,10 @@ public ProcessingContext(ProcessingEnvironment env, PlatformAdapter readAdapter) this.elements = env.getElementUtils(); this.types = env.getTypeUtils(); this.openApiAvailable = isTypeAvailable(Constants.OPENAPIDEFINITION); - this.avajeAvailable = isTypeAvailable(Constants.COMPONENT); - this.diAnnotation = avajeAvailable ? "@Component" : "@Singleton"; - this.docContext = new DocContext(env, openApiAvailable); - + this.useComponent = isTypeAvailable(Constants.COMPONENT); + this.annotationDI = useComponent ? "@Component" : "@Singleton"; + final var javax = isTypeAvailable(Constants.SINGLETON_JAVAX); final var jakarta = isTypeAvailable(Constants.SINGLETON_JAKARTA); final var override = Boolean.getBoolean(env.getOptions().get("useJavax")); @@ -72,8 +71,8 @@ public boolean useJavax() { return useJavax; } - public boolean isAvajeAvailable() { - return avajeAvailable; + public boolean useComponent() { + return useComponent; } public void logError(Element e, String msg, Object... args) { @@ -114,7 +113,7 @@ public PlatformAdapter platform() { return readAdapter; } - public String getDiAnnotation() { - return diAnnotation; + public String getDIAnnotation() { + return annotationDI; } } diff --git a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/ControllerWriter.java b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/ControllerWriter.java index 1092caf0a..bfce8a73a 100644 --- a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/ControllerWriter.java +++ b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/ControllerWriter.java @@ -60,7 +60,7 @@ private void writeRoutes(List methods) { private void writeClassStart() { writer.append(AT_GENERATED).eol(); - writer.append(ctx.getDiAnnotation()).eol(); + writer.append(ctx.getDIAnnotation()).eol(); writer.append("public class ").append(shortName).append("$Route implements Service {").eol().eol(); String controllerName = "controller"; diff --git a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java index b3b2d4b90..69781c567 100644 --- a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java +++ b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java @@ -67,7 +67,7 @@ private void writeForMethod(MethodReader method) { private void writeClassStart() { writer.append(AT_GENERATED).eol(); - writer.append(ctx.getDiAnnotation()).eol(); + writer.append(ctx.getDIAnnotation()).eol(); writer .append("public class ") .append(shortName) diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java index f648c8d91..664ad5e3c 100644 --- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java +++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java @@ -77,7 +77,7 @@ private void writeRoutes(List methods) { private void writeClassStart() { writer.append(AT_GENERATED).eol(); - writer.append(ctx.getDiAnnotation()).eol(); + writer.append(ctx.getDIAnnotation()).eol(); writer.append("public class %s$Route implements HttpService {", shortName).eol().eol(); var controllerName = "controller"; From da648b78dc8adab18d4f73d84e8fa351e7e1ce08 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sat, 7 Jan 2023 00:55:15 -0500 Subject: [PATCH 0473/1323] Update ControllerWriter.java --- .../main/java/io/avaje/http/generator/jex/ControllerWriter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerWriter.java b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerWriter.java index 65f711158..92dd4d55a 100644 --- a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerWriter.java +++ b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerWriter.java @@ -47,7 +47,7 @@ private void writeForMethod(MethodReader method) { private void writeClassStart() { writer.append(AT_GENERATED).eol(); - writer.append(ctx.getDiAnnotation()).eol(); + writer.append(ctx.getDIAnnotation()).eol(); writer.append("public class ").append(shortName).append("$Route implements Routing.Service {").eol().eol(); String controllerName = "controller"; From 22a0781bedd62bad87865b59f679e6bdb774ff07 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sat, 7 Jan 2023 00:56:15 -0500 Subject: [PATCH 0474/1323] Update ProcessingContext.java --- .../io/avaje/http/generator/core/ProcessingContext.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java index 00d5c9caa..fece9b0ea 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java @@ -29,7 +29,7 @@ public class ProcessingContext { private final DocContext docContext; private final boolean useComponent; private final boolean useJavax; - private final String annotationDI; + private final String diAnnotation; public ProcessingContext(ProcessingEnvironment env, PlatformAdapter readAdapter) { this.readAdapter = readAdapter; @@ -40,7 +40,7 @@ public ProcessingContext(ProcessingEnvironment env, PlatformAdapter readAdapter) this.openApiAvailable = isTypeAvailable(Constants.OPENAPIDEFINITION); this.docContext = new DocContext(env, openApiAvailable); this.useComponent = isTypeAvailable(Constants.COMPONENT); - this.annotationDI = useComponent ? "@Component" : "@Singleton"; + this.diAnnotation = useComponent ? "@Component" : "@Singleton"; final var javax = isTypeAvailable(Constants.SINGLETON_JAVAX); final var jakarta = isTypeAvailable(Constants.SINGLETON_JAKARTA); @@ -114,6 +114,6 @@ public PlatformAdapter platform() { } public String getDIAnnotation() { - return annotationDI; + return diAnnotation; } } From a67b1c8a579d2dd8e56853049d305607cfddeae4 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sun, 8 Jan 2023 01:04:20 -0500 Subject: [PATCH 0475/1323] custom serialize openapi --- http-generator-core/pom.xml | 7 - .../generator/core/openapi/DocContext.java | 25 +-- .../generator/core/openapi/JsonFormatter.java | 61 ++++++ .../core/openapi/OpenAPISerializer.java | 176 ++++++++++++++++++ .../src/main/java/module-info.java | 2 - 5 files changed, 243 insertions(+), 28 deletions(-) create mode 100644 http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/JsonFormatter.java create mode 100644 http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/OpenAPISerializer.java diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index e59d3110d..7a3d30157 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -13,7 +13,6 @@ 2.0.8 - 2.13.4.1 @@ -36,12 +35,6 @@ 1.21-SNAPSHOT - - com.fasterxml.jackson.core - jackson-databind - ${jackson.version} - - io.swagger.core.v3 swagger-models diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/DocContext.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/DocContext.java index 118a57ebc..0ba24b9c8 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/DocContext.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/DocContext.java @@ -1,9 +1,5 @@ package io.avaje.http.generator.core.openapi; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.SerializationFeature; import io.swagger.v3.oas.annotations.OpenAPIDefinition; import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tags; @@ -177,28 +173,19 @@ public void readApiDefinition(Element element) { } public void writeApi() { - try (Writer metaWriter = createMetaWriter()) { - OpenAPI openAPI = getApiForWriting(); - ObjectMapper mapper = createObjectMapper(); - mapper.writeValue(metaWriter, openAPI); + final var openAPI = getApiForWriting(); + try (var metaWriter = createMetaWriter()) { - } catch (IOException e) { + final var json = OpenAPISerializer.serialize(openAPI); + JsonFormatter.prettyPrintJson(metaWriter, json); + + } catch (final Exception e) { logError(null, "Error writing openapi file" + e.getMessage()); e.printStackTrace(); } } - private ObjectMapper createObjectMapper() { - - ObjectMapper mapper = new ObjectMapper(); - mapper.setDefaultPropertyInclusion(JsonInclude.Include.NON_NULL) - .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) - .enable(SerializationFeature.INDENT_OUTPUT); - - return mapper; - } - private Writer createMetaWriter() throws IOException { FileObject writer = filer.createResource(StandardLocation.CLASS_OUTPUT, "meta", "openapi.json"); return writer.openWriter(); diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/JsonFormatter.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/JsonFormatter.java new file mode 100644 index 000000000..b89e775f5 --- /dev/null +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/JsonFormatter.java @@ -0,0 +1,61 @@ +package io.avaje.http.generator.core.openapi; + +import java.io.IOException; +import java.io.Writer; + +final class JsonFormatter { + + private JsonFormatter() {} + + public static String prettyPrintJson(Writer writer, String json) throws IOException { + final var jsonChars = json.toCharArray(); + + var indentLevel = 0; + var inString = false; + + for (var i = 0; i < jsonChars.length; i++) { + final var current = jsonChars[i]; + + if (current == '"' && jsonChars[i - 1] != '\\') { + inString = !inString; + writer.append(current); + } else if (inString) { + writer.append(current); + } else { + switch (current) { + case '{': + case '[': + writer.append(current).append("\n"); + indentLevel++; + addIndents(writer, indentLevel); + break; + case '}': + case ']': + writer.append("\n"); + indentLevel--; + addIndents(writer, indentLevel); + writer.append(current); + break; + case ',': + writer.append(current).append("\n"); + addIndents(writer, indentLevel); + break; + case ':': + writer.append(" :"); + break; + default: + writer.append(current); + break; + } + } + } + + return writer.toString(); + } + + private static void addIndents(Writer writer, int level) throws IOException { + for (var i = 0; i < level; i++) { + writer.append("\t"); + } + } +} diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/OpenAPISerializer.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/OpenAPISerializer.java new file mode 100644 index 000000000..66879e45c --- /dev/null +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/OpenAPISerializer.java @@ -0,0 +1,176 @@ +package io.avaje.http.generator.core.openapi; + +import java.lang.reflect.Field; +import java.util.Collection; +import java.util.Map; + +final class OpenAPISerializer { + + private OpenAPISerializer() {} + + /** + * Converts the given object into a serialized string. + * + * @param obj the object to serialize + * @return the serialized string + * @throws IllegalAccessException if the fields of the object cannot be accessed + */ + static String serialize(Object obj) throws IllegalAccessException { + + final Class cls = obj.getClass(); + + final var sb = new StringBuilder(); + var firstElement = true; + // handle collections and maps differently to avoid module errors + if (obj instanceof Collection) { + sb.append("["); + final var collection = (Collection) obj; + for (final Object element : collection) { + + if (!firstElement) { + sb.append(","); + } + + write(sb, element); + firstElement = false; + } + + sb.append("]"); + + } else { + + if (obj instanceof Map) { + + sb.append("{"); + final Map map = (Map) obj; + for (final Map.Entry entry : map.entrySet()) { + + if (!firstElement) { + sb.append(","); + } + sb.append("\""); + sb.append(entry.getKey()); + sb.append("\": "); + + write(sb, entry.getValue()); + firstElement = false; + } + } else { + + sb.append("{"); + if (obj instanceof String) { + System.out.println(); + } + + final var fields = getAllFields(cls); + + var firstField = true; + for (final Field field : fields) { + field.setAccessible(true); + final var value = field.get(obj); + if (value != null) { + + if (!firstField) { + sb.append(","); + } + sb.append("\""); + sb.append(field.getName()); + sb.append("\": "); + write(sb, value); + firstField = false; + } + } + } + sb.append("}"); + } + return sb.toString(); + } + + /** + * Gets all the fields of the given class and its superclass. Will skip fields of java lang + * classes + * + * @param clazz the class to get the fields for + * @return an array of fields + */ + static Field[] getAllFields(Class clazz) { + final var fields = clazz.getDeclaredFields(); + Class superclass = clazz.getSuperclass(); + if (superclass.getCanonicalName().startsWith("java.")) { + superclass = null; + } + if (superclass != null) { + final var superFields = getAllFields(superclass); + final var allFields = new Field[fields.length + superFields.length]; + System.arraycopy(fields, 0, allFields, 0, fields.length); + System.arraycopy(superFields, 0, allFields, fields.length, superFields.length); + return allFields; + } else { + return fields; + } + } + + static boolean isPrimitiveWrapperType(Object value) { + + return value instanceof Boolean + || value instanceof Character + || value instanceof Byte + || value instanceof Short + || value instanceof Integer + || value instanceof Long + || value instanceof Float + || value instanceof Double; + } + + /** + * Extracts the primitive value from the given object if it is a wrapper for a primitive type. + * + * @param object the object to extract the value from + * @return the primitive value if the object is a wrapper, the object itself otherwise + */ + static Object extractPrimitiveValue(Object object) { + if (object instanceof Boolean) { + return (boolean) object; + } else if (object instanceof Character) { + return (char) object; + } else if (object instanceof Byte) { + return (byte) object; + } else if (object instanceof Short) { + return (short) object; + } else if (object instanceof Integer) { + return (int) object; + } else if (object instanceof Long) { + return (long) object; + } else if (object instanceof Float) { + return (float) object; + } else if (object instanceof Double) { + return (double) object; + } else { + return object; + } + } + + /** + * Appends the given value to the string builder. + * + * @param sb the string builder to append to + * @param value the value to append + * @throws IllegalAccessException if the fields of the value object cannot be accessed + */ + static void write(StringBuilder sb, Object value) throws IllegalAccessException { + final var isprimitiveWrapper = isPrimitiveWrapperType(value); + // Append primitive or string value as is + if (value.getClass().isPrimitive() || value instanceof String || isprimitiveWrapper) { + if (isprimitiveWrapper) { + sb.append(extractPrimitiveValue(value)); + } else { + sb.append("\""); + sb.append(value.toString().replace("\"", "\\\"")); + sb.append("\""); + } + } else { + // Recursively handle other object types + sb.append(serialize(value)); + } + } +} diff --git a/http-generator-core/src/main/java/module-info.java b/http-generator-core/src/main/java/module-info.java index bb321ee51..327dfaf65 100644 --- a/http-generator-core/src/main/java/module-info.java +++ b/http-generator-core/src/main/java/module-info.java @@ -9,8 +9,6 @@ requires transitive io.avaje.http.api; requires transitive io.swagger.v3.oas.models; requires transitive io.swagger.v3.oas.annotations; - requires transitive com.fasterxml.jackson.core; - requires transitive com.fasterxml.jackson.databind; requires transitive com.fasterxml.jackson.annotation; requires transitive java.validation; } From a2cb03dc62b7eb7a767e4c18b42b7d4fc02e2b71 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Mon, 9 Jan 2023 08:18:46 +1300 Subject: [PATCH 0476/1323] No functional change - tidy internal method names --- .../http/generator/core/MethodReader.java | 3 +- .../http/generator/core/PathSegments.java | 5 - .../generator/core/ProcessingContext.java | 6 +- .../generator/helidon/ControllerWriter.java | 2 +- .../generator/javalin/ControllerWriter.java | 2 +- .../http/generator/jex/ControllerWriter.java | 2 +- .../helidon/nima/ControllerWriter.java | 3 +- .../src/main/resources/public/openapi.json | 2878 +++++++++-------- .../src/main/resources/public/openapi.json | 1672 +++++----- .../src/main/resources/public/openapi.json | 447 +-- 10 files changed, 2653 insertions(+), 2367 deletions(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java index 64512d6fc..0d4a9b491 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java @@ -27,7 +27,6 @@ import io.avaje.http.api.Put; import io.avaje.http.generator.core.javadoc.Javadoc; import io.avaje.http.generator.core.openapi.MethodDocBuilder; -import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tags; @@ -74,7 +73,7 @@ public class MethodReader { this.actualParams = (actualExecutable == null) ? null : actualExecutable.getParameterTypes(); this.isVoid = element.getReturnType().getKind() == TypeKind.VOID; this.methodRoles = Util.findRoles(element); - this.javadoc = Javadoc.parse(ctx.getDocComment(element)); + this.javadoc = Javadoc.parse(ctx.docComment(element)); this.produces = produces(bean); this.apiResponses = getApiResponses(); initWebMethodViaAnnotation(); diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/PathSegments.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/PathSegments.java index cd2a70fb7..4e945a310 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/PathSegments.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/PathSegments.java @@ -14,7 +14,6 @@ public class PathSegments { static final PathSegments EMPTY = new PathSegments(new Chunks(), Collections.emptySet()); static PathSegments parse(String fullPath) { - Set segments = new LinkedHashSet<>(); Chunks chunks = new Chunks(); @@ -67,11 +66,8 @@ private static Segment createSegment(String val) { } private final Chunks chunks; - private final Set segments; - private final List withMatrixs = new ArrayList<>(); - private final Set allNames = new HashSet<>(); private PathSegments(Chunks chunks, Set segments) { @@ -177,7 +173,6 @@ public static class Segment { * Create a literal path segment. */ public Segment(String section, boolean literalDummy) { - this.literalSection = section; this.name = null; this.sanitizedName = null; diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java index fece9b0ea..51d0447a7 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java @@ -41,7 +41,7 @@ public ProcessingContext(ProcessingEnvironment env, PlatformAdapter readAdapter) this.docContext = new DocContext(env, openApiAvailable); this.useComponent = isTypeAvailable(Constants.COMPONENT); this.diAnnotation = useComponent ? "@Component" : "@Singleton"; - + final var javax = isTypeAvailable(Constants.SINGLETON_JAVAX); final var jakarta = isTypeAvailable(Constants.SINGLETON_JAKARTA); final var override = Boolean.getBoolean(env.getOptions().get("useJavax")); @@ -93,7 +93,7 @@ public FileObject createMetaInfWriter(String target) throws IOException { return filer.createResource(StandardLocation.CLASS_OUTPUT, "", target); } - public String getDocComment(Element param) { + public String docComment(Element param) { return elements.getDocComment(param); } @@ -113,7 +113,7 @@ public PlatformAdapter platform() { return readAdapter; } - public String getDIAnnotation() { + public String diAnnotation() { return diAnnotation; } } diff --git a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/ControllerWriter.java b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/ControllerWriter.java index bfce8a73a..0a19d4847 100644 --- a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/ControllerWriter.java +++ b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/ControllerWriter.java @@ -60,7 +60,7 @@ private void writeRoutes(List methods) { private void writeClassStart() { writer.append(AT_GENERATED).eol(); - writer.append(ctx.getDIAnnotation()).eol(); + writer.append(ctx.diAnnotation()).eol(); writer.append("public class ").append(shortName).append("$Route implements Service {").eol().eol(); String controllerName = "controller"; diff --git a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java index 69781c567..09448fc74 100644 --- a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java +++ b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java @@ -67,7 +67,7 @@ private void writeForMethod(MethodReader method) { private void writeClassStart() { writer.append(AT_GENERATED).eol(); - writer.append(ctx.getDIAnnotation()).eol(); + writer.append(ctx.diAnnotation()).eol(); writer .append("public class ") .append(shortName) diff --git a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerWriter.java b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerWriter.java index 92dd4d55a..6ce5dcc91 100644 --- a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerWriter.java +++ b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerWriter.java @@ -47,7 +47,7 @@ private void writeForMethod(MethodReader method) { private void writeClassStart() { writer.append(AT_GENERATED).eol(); - writer.append(ctx.getDIAnnotation()).eol(); + writer.append(ctx.diAnnotation()).eol(); writer.append("public class ").append(shortName).append("$Route implements Routing.Service {").eol().eol(); String controllerName = "controller"; diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java index 664ad5e3c..754fa5828 100644 --- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java +++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java @@ -5,7 +5,6 @@ import java.io.IOException; import java.util.List; import java.util.Map; -import java.util.Set; /** * Write Helidon specific web route adapter (a Helidon Service). @@ -77,7 +76,7 @@ private void writeRoutes(List methods) { private void writeClassStart() { writer.append(AT_GENERATED).eol(); - writer.append(ctx.getDIAnnotation()).eol(); + writer.append(ctx.diAnnotation()).eol(); writer.append("public class %s$Route implements HttpService {", shortName).eol().eol(); var controllerName = "controller"; diff --git a/tests/test-javalin-jsonb/src/main/resources/public/openapi.json b/tests/test-javalin-jsonb/src/main/resources/public/openapi.json index f4ce7754e..65e54b00f 100644 --- a/tests/test-javalin-jsonb/src/main/resources/public/openapi.json +++ b/tests/test-javalin-jsonb/src/main/resources/public/openapi.json @@ -1,1348 +1,1534 @@ { - "openapi" : "3.0.1", - "info" : { - "title" : "Example service", - "description" : "Example Javalin controllers with Java and Maven", - "version" : "" - }, - "tags" : [ { - "name" : "tag1", - "description" : "this is added to openapi tags" - } ], - "paths" : { - "/bars" : { - "get" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "responses" : { - "200" : { - "description" : "", - "content" : { - "text/plain" : { - "schema" : { - "type" : "string" - } - } - } - } - } - } - }, - "/bars/find/{code}" : { - "get" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "parameters" : [ { - "name" : "code", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "responses" : { - "200" : { - "description" : "", - "content" : { - "application/json" : { - "schema" : { - "type" : "array", - "items" : { - "$ref" : "#/components/schemas/Bar" - } - } - } - } - } - } - } - }, - "/bars/{id}" : { - "get" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "parameters" : [ { - "name" : "id", - "in" : "path", - "required" : true, - "schema" : { - "type" : "integer", - "format" : "int64", - "nullable" : false - } - } ], - "responses" : { - "200" : { - "description" : "", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/Bar" - } - } - } - } - } - } - }, - "/baz" : { - "get" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "responses" : { - "200" : { - "description" : "", - "content" : { - "application/json" : { - "schema" : { - "type" : "array", - "items" : { - "$ref" : "#/components/schemas/Baz" - } - } - } - } - } - } - }, - "post" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "requestBody" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/Baz" - } - } - }, - "required" : true - }, - "responses" : { - "201" : { - "description" : "", - "content" : { - "application/json" : { - "schema" : { - "type" : "integer", - "format" : "int64" - } - } - } - } - } - } - }, - "/baz/checkparams/{id}" : { - "get" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "parameters" : [ { - "name" : "id", - "in" : "path", - "required" : true, - "schema" : { - "type" : "integer", - "format" : "int32", - "nullable" : false - } - }, { - "name" : "p1", - "in" : "query", - "schema" : { - "type" : "string" - } - }, { - "name" : "p2", - "in" : "query", - "schema" : { - "type" : "number" - } - }, { - "name" : "p3", - "in" : "query", - "schema" : { - "type" : "integer", - "format" : "int32" - } - }, { - "name" : "p4", - "in" : "query", - "schema" : { - "type" : "number" - } - }, { - "name" : "body", - "in" : "query", - "schema" : { - "type" : "string" - } - } ], - "responses" : { - "200" : { - "description" : "", - "content" : { - "application/json" : { - "schema" : { - "type" : "string" - } - } - } - } - } - } - }, - "/baz/findbyname/{name}" : { - "get" : { - "tags" : [ ], - "summary" : "Find the baz by name", - "description" : "This is some more comments about this method.", - "parameters" : [ { - "name" : "name", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "responses" : { - "200" : { - "description" : "The list of baz", - "content" : { - "application/json" : { - "schema" : { - "type" : "array", - "items" : { - "$ref" : "#/components/schemas/Baz" - } - } - } - } - } - } - } - }, - "/baz/{id}" : { - "get" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "parameters" : [ { - "name" : "id", - "in" : "path", - "required" : true, - "schema" : { - "type" : "integer", - "format" : "int64" - } - } ], - "responses" : { - "200" : { - "description" : "", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/Baz" - } - } - } - } - } - } - }, - "/hello" : { - "post" : { - "tags" : [ ], - "summary" : "Simple example post with JSON body response", - "description" : "", - "requestBody" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/HelloDto" - } - } - }, - "required" : true - }, - "responses" : { - "201" : { - "description" : "", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/HelloDto" - } - } - } - } - } - } - }, - "/hello/findbyname/{name}" : { - "get" : { - "tags" : [ ], - "summary" : "Find Hellos by name", - "description" : "", - "parameters" : [ { - "name" : "name", - "in" : "path", - "description" : "The name to search for", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "myParam", - "in" : "query", - "schema" : { - "type" : "string" - } - } ], - "responses" : { - "200" : { - "description" : "The Hellos that we found.", - "content" : { - "application/json" : { - "schema" : { - "type" : "array", - "items" : { - "$ref" : "#/components/schemas/HelloDto" - } - } - } - } - } - } - } - }, - "/hello/message" : { - "get" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "responses" : { - "200" : { - "description" : "", - "content" : { - "text/plain" : { - "schema" : { - "type" : "string" - } - } - } - } - } - } - }, - "/hello/mySave" : { - "post" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "requestBody" : { - "content" : { - "application/x-www-form-urlencoded" : { - "schema" : { - "type" : "object", - "properties" : { - "name" : { - "type" : "string" - }, - "email" : { - "type" : "string" - }, - "url" : { - "type" : "string" - } - } - } - } - }, - "required" : true - }, - "responses" : { - "201" : { - "description" : "No content" - } - } - } - }, - "/hello/savebean/{foo}" : { - "post" : { - "tags" : [ ], - "summary" : "Save the hello using json body", - "description" : "", - "parameters" : [ { - "name" : "foo", - "in" : "path", - "description" : "The hello doo id", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "requestBody" : { - "description" : "The hello body as json", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/HelloDto" - } - } - }, - "required" : true - }, - "responses" : { - "201" : { - "description" : "No content" - } - } - } - }, - "/hello/saveform" : { - "post" : { - "tags" : [ ], - "summary" : "Create the new Hello using a form", - "description" : "", - "requestBody" : { - "content" : { - "application/x-www-form-urlencoded" : { - "schema" : { - "$ref" : "#/components/schemas/HelloForm" - } - } - }, - "required" : true - }, - "responses" : { - "201" : { - "description" : "No content" - } - } - } - }, - "/hello/saveform2" : { - "post" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "requestBody" : { - "content" : { - "application/x-www-form-urlencoded" : { - "schema" : { - "type" : "object", - "properties" : { - "name" : { - "type" : "string" - }, - "email" : { - "type" : "string" - }, - "url" : { - "type" : "string" - } - } - } - } - }, - "required" : true - }, - "responses" : { - "201" : { - "description" : "No content" - } - } - } - }, - "/hello/saveform3" : { - "post" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "requestBody" : { - "content" : { - "application/x-www-form-urlencoded" : { - "schema" : { - "$ref" : "#/components/schemas/HelloForm" - } - } - }, - "required" : true - }, - "responses" : { - "201" : { - "description" : "", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/HelloDto" - } - } - } - } - } - } - }, - "/hello/slash/{name}//other/" : { - "get" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "parameters" : [ { - "name" : "name", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "nam0", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "nam1", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "responses" : { - "200" : { - "description" : "", - "content" : { - "text/plain" : { - "schema" : { - "type" : "string" - } - } - } - } - } - } - }, - "/hello/withMatrix/{year_segment}/{other}" : { - "get" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "parameters" : [ { - "name" : "year", - "in" : "path", - "required" : true, - "schema" : { - "type" : "integer", - "format" : "int32", - "nullable" : false - } - }, { - "name" : "author", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "country", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "other", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "extra", - "in" : "query", - "schema" : { - "type" : "string" - } - } ], - "responses" : { - "200" : { - "description" : "", - "content" : { - "text/plain" : { - "schema" : { - "type" : "string" - } - } - } - } - } - } - }, - "/hello/withValidBean" : { - "get" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "parameters" : [ { - "name" : "bean", - "in" : "bean", - "schema" : { - "$ref" : "#/components/schemas/GetBeanForm" - } - } ], - "responses" : { - "200" : { - "description" : "", - "content" : { - "text/plain" : { - "schema" : { - "type" : "string" - } - } - } - } - } - } - }, - "/hello/{id}" : { - "delete" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "parameters" : [ { - "name" : "id", - "in" : "path", - "required" : true, - "schema" : { - "type" : "integer", - "format" : "int32", - "nullable" : false - } - } ], - "responses" : { - "204" : { - "description" : "No content" - } - } - } - }, - "/hello/{id}/{date}" : { - "get" : { - "tags" : [ ], - "summary" : "Return the Hello DTO", - "description" : "", - "parameters" : [ { - "name" : "id", - "in" : "path", - "description" : "The hello Id.", - "required" : true, - "schema" : { - "type" : "integer", - "format" : "int32", - "nullable" : false - } - }, { - "name" : "date", - "in" : "path", - "description" : "The name of the hello", - "required" : true, - "schema" : { - "type" : "string", - "format" : "date" - } - }, { - "name" : "otherParam", - "in" : "query", - "description" : "Optional other parameter", - "schema" : { - "type" : "string" - } - } ], - "responses" : { - "200" : { - "description" : "The Hello DTO given the id and name.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/HelloDto" - } - } - } - } - }, - "deprecated" : true - } - }, - "/openapi/get" : { - "get" : { - "tags" : [ ], - "summary" : "Example of Open API Get (up to the first period is the summary)", - "description" : "When using Javalin Context only This Javadoc description is added to the generated openapi.json", - "responses" : { - "200" : { - "description" : "funny phrase (this part of the javadoc is added to the response desc)", - "content" : { - "text/plain" : { - "schema" : { - "type" : "string" - } - } - } - } - } - } - }, - "/openapi/post" : { - "post" : { - "tags" : [ "tag1" ], - "summary" : "Standard Post", - "description" : "uses tag annotation to add tags to openapi json", - "requestBody" : { - "description" : "the body (this is used for generated request body desc)", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/Person" - } - } - }, - "required" : true - }, - "responses" : { - "200" : { - "description" : "overrides @return javadoc description", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/Person" - } - } - } - }, - "201" : { - "description" : "the response body (from javadoc)", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/Person" - } - } - } - }, - "400" : { - "description" : "User not found (Will not have an associated response schema)" - }, - "500" : { - "description" : "Some other Error (Will have this error class as the response class)", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ErrorResponse" - } - } - } - } - } - } - }, - "/openapi/post1" : { - "post" : { - "tags" : [ ], - "summary" : "Standard Post", - "description" : "The Deprecated annotation adds \"deprecacted:true\" to the generated json", - "requestBody" : { - "description" : "the body", - "content" : { - "application/json" : { - "schema" : { - "type" : "array", - "items" : { - "$ref" : "#/components/schemas/Person" - } - } - } - }, - "required" : true - }, - "responses" : { - "400" : { - "description" : "User not found" - }, - "500" : { - "description" : "Some other Error", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ErrorResponse" - } - } - } - }, - "201" : { - "description" : "the response body (from javadoc)", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/Person" - } - } - } - } - }, - "deprecated" : true - } - }, - "/req-scoped" : { - "get" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "responses" : { - "200" : { - "description" : "", - "content" : { - "text/plain" : { - "schema" : { - "type" : "string" - } - } - } - } - } - } - }, - "/test" : { - "get" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "responses" : { - "200" : { - "description" : "", - "content" : { - "text/plain" : { - "schema" : { - "type" : "string" - } - } - } - } - } - } - }, - "/test/byte" : { - "get" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "responses" : { - "200" : { - "description" : "", - "content" : { - "image/png" : { - "schema" : { - "type" : "array", - "items" : { - "$ref" : "#/components/schemas/byte" - } - } - } - } - } - } - } - }, - "/test/ctx" : { - "get" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "responses" : { - "200" : { - "description" : "No content" - } - } - } - }, - "/test/form" : { - "post" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "requestBody" : { - "content" : { - "application/x-www-form-urlencoded" : { - "schema" : { - "type" : "object", - "properties" : { - "name" : { - "type" : "string" - }, - "email" : { - "type" : "string" - }, - "url" : { - "type" : "string" - } - } - } - } - }, - "required" : true - }, - "responses" : { - "201" : { - "description" : "", - "content" : { - "application/json" : { - "schema" : { - "type" : "string" - } - } - } - } - } - } - }, - "/test/formBean" : { - "post" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "requestBody" : { - "content" : { - "application/x-www-form-urlencoded" : { - "schema" : { - "$ref" : "#/components/schemas/MyForm" - } - } - }, - "required" : true - }, - "responses" : { - "201" : { - "description" : "", - "content" : { - "application/json" : { - "schema" : { - "type" : "string" - } - } - } - } - } - } - }, - "/test/header" : { - "get" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "parameters" : [ { - "name" : "head", - "in" : "header", - "schema" : { - "type" : "string" - } - } ], - "responses" : { - "200" : { - "description" : "", - "content" : { - "application/json" : { - "schema" : { - "type" : "string" - } - } - } - } - } - } - }, - "/test/hey" : { - "get" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "responses" : { - "200" : { - "description" : "", - "content" : { - "text/plain" : { - "schema" : { - "type" : "string" - } - } - } - } - } - } - }, - "/test/int" : { - "put" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "responses" : { - "200" : { - "description" : "", - "content" : { - "application/json" : { - "schema" : { - "type" : "integer", - "format" : "int32", - "nullable" : false - } - } - } - } - } - } - }, - "/test/long" : { - "put" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "responses" : { - "200" : { - "description" : "", - "content" : { - "application/json" : { - "schema" : { - "type" : "integer", - "format" : "int64", - "nullable" : false - } - } - } - } - } - } - }, - "/test/person" : { - "post" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "requestBody" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/Person" - } - } - }, - "required" : true - }, - "responses" : { - "201" : { - "description" : "", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/Person" - } - } - } - } - } - } - }, - "/test/person/update" : { - "put" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "requestBody" : { - "content" : { - "application/json" : { - "schema" : { - "type" : "array", - "items" : { - "$ref" : "#/components/schemas/Person" - } - } - } - }, - "required" : true - }, - "responses" : { - "200" : { - "description" : "", - "content" : { - "application/json" : { - "schema" : { - "type" : "string" - } - } - } - } - } - } - }, - "/test/person/{name}" : { - "get" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "parameters" : [ { - "name" : "name", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "responses" : { - "200" : { - "description" : "", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/Person" - } - } - } - } - } - } - }, - "/test/person/{sortBy}/list" : { - "get" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "parameters" : [ { - "name" : "sortBy", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "responses" : { - "200" : { - "description" : "", - "content" : { - "application/json" : { - "schema" : { - "type" : "array", - "items" : { - "$ref" : "#/components/schemas/Person" - } - } - } - } - } - } - } - }, - "/test/person/{sortBy}/map" : { - "get" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "parameters" : [ { - "name" : "sortBy", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "responses" : { - "200" : { - "description" : "", - "content" : { - "application/json" : { - "schema" : { - "type" : "object", - "additionalProperties" : { - "$ref" : "#/components/schemas/Person" - } - } - } - } - } - } - } - }, - "/test/person/{sortBy}/set" : { - "get" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "parameters" : [ { - "name" : "sortBy", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "responses" : { - "200" : { - "description" : "", - "content" : { - "application/json" : { - "schema" : { - "type" : "array", - "items" : { - "$ref" : "#/components/schemas/Person" - } - } - } - } - } - } - } - } - }, - "components" : { - "schemas" : { - "Bar" : { - "type" : "object", - "properties" : { - "id" : { - "type" : "integer", - "format" : "int64", - "nullable" : false - }, - "name" : { - "type" : "string" - } - } - }, - "Baz" : { - "type" : "object", - "properties" : { - "id" : { - "type" : "integer", - "format" : "int64" - }, - "name" : { - "type" : "string" - }, - "startDate" : { - "type" : "string", - "format" : "date" - } - } - }, - "ErrorResponse" : { - "type" : "object", - "properties" : { - "id" : { - "type" : "string" - }, - "text" : { - "type" : "string" - } - } - }, - "GetBeanForm" : { - "type" : "object", - "properties" : { - "name" : { - "maxLength" : 150, - "minLength" : 2, - "type" : "string", - "nullable" : false - }, - "email" : { - "maxLength" : 100, - "type" : "string", - "format" : "email" - } - } - }, - "HelloDto" : { - "type" : "object", - "properties" : { - "id" : { - "type" : "integer", - "format" : "int32", - "nullable" : false - }, - "name" : { - "type" : "string" - }, - "otherParam" : { - "type" : "string" - }, - "gid" : { - "type" : "string", - "format" : "uuid" - }, - "whenAction" : { - "type" : "string", - "format" : "date-time" - } - } - }, - "HelloForm" : { - "type" : "object", - "properties" : { - "name" : { - "maxLength" : 150, - "minLength" : 2, - "type" : "string", - "nullable" : false - }, - "email" : { - "maxLength" : 100, - "type" : "string", - "format" : "email" - }, - "url" : { - "type" : "string" - }, - "startDate" : { - "type" : "string", - "format" : "date" - } - } - }, - "MyForm" : { - "type" : "object", - "properties" : { - "name" : { - "type" : "string" - }, - "email" : { - "type" : "string" - }, - "url" : { - "type" : "string" - } - } - }, - "Person" : { - "type" : "object", - "properties" : { - "id" : { - "type" : "integer", - "format" : "int64", - "nullable" : false - }, - "name" : { - "type" : "string" - } - } - }, - "byte" : { - "type" : "object" - } - } - } + "openapi" : "3.0.1", + "info" : { + "title" : "Example service", + "description" : "Example Javalin controllers with Java and Maven", + "version" : "" + }, + "tags" : [ + { + "name" : "tag1", + "description" : "this is added to openapi tags" + } + ], + "paths" : { + "/bars" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/bars/find/{code}" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "parameters" : [ + { + "name" : "code", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "items" : { + "$ref" : "#/components/schemas/Bar" + }, + "type" : "array" + } + } + } + } + } + } + }, + "/bars/{id}" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "parameters" : [ + { + "name" : "id", + "in" : "path", + "required" : true, + "schema" : { + "type" : "integer", + "format" : "int64", + "nullable" : false + } + } + ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Bar" + } + } + } + } + } + } + }, + "/baz" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "items" : { + "$ref" : "#/components/schemas/Baz" + }, + "type" : "array" + } + } + } + } + } + }, + "post" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Baz" + } + } + }, + "required" : true + }, + "responses" : { + "201" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "integer", + "format" : "int64" + } + } + } + } + } + } + }, + "/baz/checkparams/{id}" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "parameters" : [ + { + "name" : "id", + "in" : "path", + "required" : true, + "schema" : { + "type" : "integer", + "format" : "int32", + "nullable" : false + } + }, + { + "name" : "p1", + "in" : "query", + "schema" : { + "type" : "string" + } + }, + { + "name" : "p2", + "in" : "query", + "schema" : { + "type" : "number" + } + }, + { + "name" : "p3", + "in" : "query", + "schema" : { + "type" : "integer", + "format" : "int32" + } + }, + { + "name" : "p4", + "in" : "query", + "schema" : { + "type" : "number" + } + }, + { + "name" : "body", + "in" : "query", + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/baz/findbyname/{name}" : { + "get" : { + "tags" : [ + + ], + "summary" : "Find the baz by name", + "description" : "This is some more comments about this method.", + "parameters" : [ + { + "name" : "name", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "description" : "The list of baz", + "content" : { + "application/json" : { + "schema" : { + "items" : { + "$ref" : "#/components/schemas/Baz" + }, + "type" : "array" + } + } + } + } + } + } + }, + "/baz/{id}" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "parameters" : [ + { + "name" : "id", + "in" : "path", + "required" : true, + "schema" : { + "type" : "integer", + "format" : "int64" + } + } + ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Baz" + } + } + } + } + } + } + }, + "/hello" : { + "post" : { + "tags" : [ + + ], + "summary" : "Simple example post with JSON body response", + "description" : "", + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/HelloDto" + } + } + }, + "required" : true + }, + "responses" : { + "201" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/HelloDto" + } + } + } + } + } + } + }, + "/hello/findbyname/{name}" : { + "get" : { + "tags" : [ + + ], + "summary" : "Find Hellos by name", + "description" : "", + "parameters" : [ + { + "name" : "name", + "in" : "path", + "description" : "The name to search for", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "name" : "myParam", + "in" : "query", + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "description" : "The Hellos that we found.", + "content" : { + "application/json" : { + "schema" : { + "items" : { + "$ref" : "#/components/schemas/HelloDto" + }, + "type" : "array" + } + } + } + } + } + } + }, + "/hello/message" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/hello/mySave" : { + "post" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "requestBody" : { + "content" : { + "application/x-www-form-urlencoded" : { + "schema" : { + "type" : "object", + "properties" : { + "name" : { + "type" : "string" + }, + "email" : { + "type" : "string" + }, + "url" : { + "type" : "string" + } + } + } + } + }, + "required" : true + }, + "responses" : { + "201" : { + "description" : "No content" + } + } + } + }, + "/hello/savebean/{foo}" : { + "post" : { + "tags" : [ + + ], + "summary" : "Save the hello using json body", + "description" : "", + "parameters" : [ + { + "name" : "foo", + "in" : "path", + "description" : "The hello doo id", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "requestBody" : { + "description" : "The hello body as json", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/HelloDto" + } + } + }, + "required" : true + }, + "responses" : { + "201" : { + "description" : "No content" + } + } + } + }, + "/hello/saveform" : { + "post" : { + "tags" : [ + + ], + "summary" : "Create the new Hello using a form", + "description" : "", + "requestBody" : { + "content" : { + "application/x-www-form-urlencoded" : { + "schema" : { + "$ref" : "#/components/schemas/HelloForm" + } + } + }, + "required" : true + }, + "responses" : { + "201" : { + "description" : "No content" + } + } + } + }, + "/hello/saveform2" : { + "post" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "requestBody" : { + "content" : { + "application/x-www-form-urlencoded" : { + "schema" : { + "type" : "object", + "properties" : { + "name" : { + "type" : "string" + }, + "email" : { + "type" : "string" + }, + "url" : { + "type" : "string" + } + } + } + } + }, + "required" : true + }, + "responses" : { + "201" : { + "description" : "No content" + } + } + } + }, + "/hello/saveform3" : { + "post" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "requestBody" : { + "content" : { + "application/x-www-form-urlencoded" : { + "schema" : { + "$ref" : "#/components/schemas/HelloForm" + } + } + }, + "required" : true + }, + "responses" : { + "201" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/HelloDto" + } + } + } + } + } + } + }, + "/hello/slash/{name}//other/" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "parameters" : [ + { + "name" : "name", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "name" : "nam0", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "name" : "nam1", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/hello/withMatrix/{year_segment}/{other}" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "parameters" : [ + { + "name" : "year", + "in" : "path", + "required" : true, + "schema" : { + "type" : "integer", + "format" : "int32", + "nullable" : false + } + }, + { + "name" : "author", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "name" : "country", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "name" : "other", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "name" : "extra", + "in" : "query", + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/hello/withValidBean" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "parameters" : [ + { + "name" : "bean", + "in" : "bean", + "schema" : { + "$ref" : "#/components/schemas/GetBeanForm" + } + } + ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/hello/{id}" : { + "delete" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "parameters" : [ + { + "name" : "id", + "in" : "path", + "required" : true, + "schema" : { + "type" : "integer", + "format" : "int32", + "nullable" : false + } + } + ], + "responses" : { + "204" : { + "description" : "No content" + } + } + } + }, + "/hello/{id}/{date}" : { + "get" : { + "tags" : [ + + ], + "summary" : "Return the Hello DTO", + "description" : "", + "parameters" : [ + { + "name" : "id", + "in" : "path", + "description" : "The hello Id.", + "required" : true, + "schema" : { + "type" : "integer", + "format" : "int32", + "nullable" : false + } + }, + { + "name" : "date", + "in" : "path", + "description" : "The name of the hello", + "required" : true, + "schema" : { + "type" : "string", + "format" : "date" + } + }, + { + "name" : "otherParam", + "in" : "query", + "description" : "Optional other parameter", + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "description" : "The Hello DTO given the id and name.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/HelloDto" + } + } + } + } + }, + "deprecated" : true + } + }, + "/openapi/get" : { + "get" : { + "tags" : [ + + ], + "summary" : "Example of Open API Get (up to the first period is the summary)", + "description" : "When using Javalin Context only This Javadoc description is added to the generated openapi.json", + "responses" : { + "200" : { + "description" : "funny phrase (this part of the javadoc is added to the response desc)", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/openapi/post" : { + "post" : { + "tags" : [ + "tag1" + ], + "summary" : "Standard Post", + "description" : "uses tag annotation to add tags to openapi json", + "requestBody" : { + "description" : "the body (this is used for generated request body desc)", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Person" + } + } + }, + "required" : true + }, + "responses" : { + "200" : { + "description" : "overrides @return javadoc description", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Person" + } + } + } + }, + "201" : { + "description" : "the response body (from javadoc)", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Person" + } + } + } + }, + "400" : { + "description" : "User not found (Will not have an associated response schema)" + }, + "500" : { + "description" : "Some other Error (Will have this error class as the response class)", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ErrorResponse" + } + } + } + } + } + } + }, + "/openapi/post1" : { + "post" : { + "tags" : [ + + ], + "summary" : "Standard Post", + "description" : "The Deprecated annotation adds \"deprecacted:true\" to the generated json", + "requestBody" : { + "description" : "the body", + "content" : { + "application/json" : { + "schema" : { + "items" : { + "$ref" : "#/components/schemas/Person" + }, + "type" : "array" + } + } + }, + "required" : true + }, + "responses" : { + "400" : { + "description" : "User not found" + }, + "500" : { + "description" : "Some other Error", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ErrorResponse" + } + } + } + }, + "201" : { + "description" : "the response body (from javadoc)", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Person" + } + } + } + } + }, + "deprecated" : true + } + }, + "/req-scoped" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/test" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/test/byte" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "", + "content" : { + "image/png" : { + "schema" : { + "items" : { + "$ref" : "#/components/schemas/byte" + }, + "type" : "array" + } + } + } + } + } + } + }, + "/test/ctx" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "No content" + } + } + } + }, + "/test/form" : { + "post" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "requestBody" : { + "content" : { + "application/x-www-form-urlencoded" : { + "schema" : { + "type" : "object", + "properties" : { + "name" : { + "type" : "string" + }, + "email" : { + "type" : "string" + }, + "url" : { + "type" : "string" + } + } + } + } + }, + "required" : true + }, + "responses" : { + "201" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/test/formBean" : { + "post" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "requestBody" : { + "content" : { + "application/x-www-form-urlencoded" : { + "schema" : { + "$ref" : "#/components/schemas/MyForm" + } + } + }, + "required" : true + }, + "responses" : { + "201" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/test/header" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "parameters" : [ + { + "name" : "head", + "in" : "header", + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/test/hey" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/test/int" : { + "put" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "integer", + "format" : "int32", + "nullable" : false + } + } + } + } + } + } + }, + "/test/long" : { + "put" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "integer", + "format" : "int64", + "nullable" : false + } + } + } + } + } + } + }, + "/test/person" : { + "post" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Person" + } + } + }, + "required" : true + }, + "responses" : { + "201" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Person" + } + } + } + } + } + } + }, + "/test/person/update" : { + "put" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "items" : { + "$ref" : "#/components/schemas/Person" + }, + "type" : "array" + } + } + }, + "required" : true + }, + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/test/person/{name}" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "parameters" : [ + { + "name" : "name", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Person" + } + } + } + } + } + } + }, + "/test/person/{sortBy}/list" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "parameters" : [ + { + "name" : "sortBy", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "items" : { + "$ref" : "#/components/schemas/Person" + }, + "type" : "array" + } + } + } + } + } + } + }, + "/test/person/{sortBy}/map" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "parameters" : [ + { + "name" : "sortBy", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "object", + "additionalProperties" : { + "$ref" : "#/components/schemas/Person" + } + } + } + } + } + } + } + }, + "/test/person/{sortBy}/set" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "parameters" : [ + { + "name" : "sortBy", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "items" : { + "$ref" : "#/components/schemas/Person" + }, + "type" : "array" + } + } + } + } + } + } + }, + "/test/withMatrixParam/{type-1_segment}/{range_segment}" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "parameters" : [ + { + "name" : "type", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "name" : "category", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "name" : "vendor", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "name" : "range", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "name" : "style", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "description" : "No content" + } + } + } + } + }, + "components" : { + "schemas" : { + "Bar" : { + "type" : "object", + "properties" : { + "id" : { + "type" : "integer", + "format" : "int64", + "nullable" : false + }, + "name" : { + "type" : "string" + } + } + }, + "Baz" : { + "type" : "object", + "properties" : { + "id" : { + "type" : "integer", + "format" : "int64" + }, + "name" : { + "type" : "string" + }, + "startDate" : { + "type" : "string", + "format" : "date" + } + } + }, + "ErrorResponse" : { + "type" : "object", + "properties" : { + "id" : { + "type" : "string" + }, + "text" : { + "type" : "string" + } + } + }, + "GetBeanForm" : { + "type" : "object", + "properties" : { + "name" : { + "maxLength" : 150, + "minLength" : 2, + "type" : "string", + "nullable" : false + }, + "email" : { + "maxLength" : 100, + "type" : "string", + "format" : "email" + } + } + }, + "HelloDto" : { + "type" : "object", + "properties" : { + "id" : { + "type" : "integer", + "format" : "int32", + "nullable" : false + }, + "name" : { + "type" : "string" + }, + "otherParam" : { + "type" : "string" + }, + "gid" : { + "type" : "string", + "format" : "uuid" + }, + "whenAction" : { + "type" : "string", + "format" : "date-time" + } + } + }, + "HelloForm" : { + "type" : "object", + "properties" : { + "name" : { + "maxLength" : 150, + "minLength" : 2, + "type" : "string", + "nullable" : false + }, + "email" : { + "maxLength" : 100, + "type" : "string", + "format" : "email" + }, + "url" : { + "type" : "string" + }, + "startDate" : { + "type" : "string", + "format" : "date" + } + } + }, + "MyForm" : { + "type" : "object", + "properties" : { + "name" : { + "type" : "string" + }, + "email" : { + "type" : "string" + }, + "url" : { + "type" : "string" + } + } + }, + "Person" : { + "type" : "object", + "properties" : { + "id" : { + "type" : "integer", + "format" : "int64", + "nullable" : false + }, + "name" : { + "type" : "string" + } + } + }, + "byte" : { + "type" : "object" + } + } + } } \ No newline at end of file diff --git a/tests/test-javalin/src/main/resources/public/openapi.json b/tests/test-javalin/src/main/resources/public/openapi.json index fe92fc8f0..56cea1bbc 100644 --- a/tests/test-javalin/src/main/resources/public/openapi.json +++ b/tests/test-javalin/src/main/resources/public/openapi.json @@ -1,797 +1,879 @@ { - "openapi" : "3.0.1", - "info" : { - "title" : "Example service", - "description" : "Example Javalin controllers with Java and Maven", - "version" : "" - }, - "paths" : { - "/bars" : { - "get" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "responses" : { - "200" : { - "description" : "", - "content" : { - "text/plain" : { - "schema" : { - "type" : "string" - } - } - } - } - } - } - }, - "/bars/find/{code}" : { - "get" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "parameters" : [ { - "name" : "code", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "responses" : { - "200" : { - "description" : "", - "content" : { - "application/json" : { - "schema" : { - "type" : "array", - "items" : { - "$ref" : "#/components/schemas/Bar" - } - } - } - } - } - } - } - }, - "/bars/{id}" : { - "get" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "parameters" : [ { - "name" : "id", - "in" : "path", - "required" : true, - "schema" : { - "type" : "integer", - "format" : "int64", - "nullable" : false - } - } ], - "responses" : { - "200" : { - "description" : "", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/Bar" - } - } - } - } - } - } - }, - "/baz" : { - "get" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "responses" : { - "200" : { - "description" : "", - "content" : { - "application/json" : { - "schema" : { - "type" : "array", - "items" : { - "$ref" : "#/components/schemas/Baz" - } - } - } - } - } - } - }, - "post" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "requestBody" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/Baz" - } - } - }, - "required" : true - }, - "responses" : { - "201" : { - "description" : "", - "content" : { - "application/json" : { - "schema" : { - "type" : "integer", - "format" : "int64" - } - } - } - } - } - } - }, - "/baz/checkparams/{id}" : { - "get" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "parameters" : [ { - "name" : "id", - "in" : "path", - "required" : true, - "schema" : { - "type" : "integer", - "format" : "int32", - "nullable" : false - } - }, { - "name" : "p1", - "in" : "query", - "schema" : { - "type" : "string" - } - }, { - "name" : "p2", - "in" : "query", - "schema" : { - "type" : "number" - } - }, { - "name" : "p3", - "in" : "query", - "schema" : { - "type" : "integer", - "format" : "int32" - } - }, { - "name" : "p4", - "in" : "query", - "schema" : { - "type" : "number" - } - }, { - "name" : "body", - "in" : "query", - "schema" : { - "type" : "string" - } - } ], - "responses" : { - "200" : { - "description" : "", - "content" : { - "application/json" : { - "schema" : { - "type" : "string" - } - } - } - } - } - } - }, - "/baz/findbyname/{name}" : { - "get" : { - "tags" : [ ], - "summary" : "Find the baz by name", - "description" : "This is some more comments about this method.", - "parameters" : [ { - "name" : "name", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "responses" : { - "200" : { - "description" : "The list of baz", - "content" : { - "application/json" : { - "schema" : { - "type" : "array", - "items" : { - "$ref" : "#/components/schemas/Baz" - } - } - } - } - } - } - } - }, - "/baz/{id}" : { - "get" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "parameters" : [ { - "name" : "id", - "in" : "path", - "required" : true, - "schema" : { - "type" : "integer", - "format" : "int64" - } - } ], - "responses" : { - "200" : { - "description" : "", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/Baz" - } - } - } - } - } - } - }, - "/hello" : { - "post" : { - "tags" : [ ], - "summary" : "Simple example post with JSON body response", - "description" : "", - "requestBody" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/HelloDto" - } - } - }, - "required" : true - }, - "responses" : { - "201" : { - "description" : "", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/HelloDto" - } - } - } - } - } - } - }, - "/hello/findbyname/{name}" : { - "get" : { - "tags" : [ ], - "summary" : "Find Hellos by name", - "description" : "", - "parameters" : [ { - "name" : "name", - "in" : "path", - "description" : "The name to search for", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "myParam", - "in" : "query", - "schema" : { - "type" : "string" - } - } ], - "responses" : { - "200" : { - "description" : "The Hellos that we found.", - "content" : { - "application/json" : { - "schema" : { - "type" : "array", - "items" : { - "$ref" : "#/components/schemas/HelloDto" - } - } - } - } - } - } - } - }, - "/hello/message" : { - "get" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "responses" : { - "200" : { - "description" : "", - "content" : { - "text/plain" : { - "schema" : { - "type" : "string" - } - } - } - } - } - } - }, - "/hello/mySave" : { - "post" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "requestBody" : { - "content" : { - "application/x-www-form-urlencoded" : { - "schema" : { - "type" : "object", - "properties" : { - "name" : { - "type" : "string" - }, - "email" : { - "type" : "string" - }, - "url" : { - "type" : "string" - } - } - } - } - }, - "required" : true - }, - "responses" : { - "201" : { - "description" : "No content" - } - } - } - }, - "/hello/savebean/{foo}" : { - "post" : { - "tags" : [ ], - "summary" : "Save the hello using json body", - "description" : "", - "parameters" : [ { - "name" : "foo", - "in" : "path", - "description" : "The hello doo id", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "requestBody" : { - "description" : "The hello body as json", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/HelloDto" - } - } - }, - "required" : true - }, - "responses" : { - "201" : { - "description" : "No content" - } - } - } - }, - "/hello/saveform" : { - "post" : { - "tags" : [ ], - "summary" : "Create the new Hello using a form", - "description" : "", - "requestBody" : { - "content" : { - "application/x-www-form-urlencoded" : { - "schema" : { - "$ref" : "#/components/schemas/HelloForm" - } - } - }, - "required" : true - }, - "responses" : { - "201" : { - "description" : "No content" - } - } - } - }, - "/hello/saveform2" : { - "post" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "requestBody" : { - "content" : { - "application/x-www-form-urlencoded" : { - "schema" : { - "type" : "object", - "properties" : { - "name" : { - "type" : "string" - }, - "email" : { - "type" : "string" - }, - "url" : { - "type" : "string" - } - } - } - } - }, - "required" : true - }, - "responses" : { - "201" : { - "description" : "No content" - } - } - } - }, - "/hello/saveform3" : { - "post" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "requestBody" : { - "content" : { - "application/x-www-form-urlencoded" : { - "schema" : { - "$ref" : "#/components/schemas/HelloForm" - } - } - }, - "required" : true - }, - "responses" : { - "201" : { - "description" : "", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/HelloDto" - } - } - } - } - } - } - }, - "/hello/slash/{name}//other/" : { - "get" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "parameters" : [ { - "name" : "name", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "nam0", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "nam1", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "responses" : { - "200" : { - "description" : "", - "content" : { - "text/plain" : { - "schema" : { - "type" : "string" - } - } - } - } - } - } - }, - "/hello/withMatrix/{year_segment}/{other}" : { - "get" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "parameters" : [ { - "name" : "year", - "in" : "path", - "required" : true, - "schema" : { - "type" : "integer", - "format" : "int32", - "nullable" : false - } - }, { - "name" : "author", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "country", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "other", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "extra", - "in" : "query", - "schema" : { - "type" : "string" - } - } ], - "responses" : { - "200" : { - "description" : "", - "content" : { - "text/plain" : { - "schema" : { - "type" : "string" - } - } - } - } - } - } - }, - "/hello/withValidBean" : { - "get" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "parameters" : [ { - "name" : "bean", - "in" : "bean", - "schema" : { - "$ref" : "#/components/schemas/GetBeanForm" - } - } ], - "responses" : { - "200" : { - "description" : "", - "content" : { - "text/plain" : { - "schema" : { - "type" : "string" - } - } - } - } - } - } - }, - "/hello/{id}" : { - "delete" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "parameters" : [ { - "name" : "id", - "in" : "path", - "required" : true, - "schema" : { - "type" : "integer", - "format" : "int32", - "nullable" : false - } - } ], - "responses" : { - "204" : { - "description" : "No content" - } - } - } - }, - "/hello/{id}/{date}" : { - "get" : { - "tags" : [ ], - "summary" : "Return the Hello DTO", - "description" : "", - "parameters" : [ { - "name" : "id", - "in" : "path", - "description" : "The hello Id.", - "required" : true, - "schema" : { - "type" : "integer", - "format" : "int32", - "nullable" : false - } - }, { - "name" : "date", - "in" : "path", - "description" : "The name of the hello", - "required" : true, - "schema" : { - "type" : "string", - "format" : "date" - } - }, { - "name" : "otherParam", - "in" : "query", - "description" : "Optional other parameter", - "schema" : { - "type" : "string" - } - } ], - "responses" : { - "200" : { - "description" : "The Hello DTO given the id and name.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/HelloDto" - } - } - } - } - }, - "deprecated" : true - } - }, - "/req-scoped" : { - "get" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "responses" : { - "200" : { - "description" : "", - "content" : { - "text/plain" : { - "schema" : { - "type" : "string" - } - } - } - } - } - } - } - }, - "components" : { - "schemas" : { - "Bar" : { - "type" : "object", - "properties" : { - "id" : { - "type" : "integer", - "format" : "int64", - "nullable" : false - }, - "name" : { - "type" : "string" - } - } - }, - "Baz" : { - "type" : "object", - "properties" : { - "id" : { - "type" : "integer", - "format" : "int64" - }, - "name" : { - "type" : "string" - }, - "startDate" : { - "type" : "string", - "format" : "date" - } - } - }, - "GetBeanForm" : { - "type" : "object", - "properties" : { - "name" : { - "maxLength" : 150, - "minLength" : 2, - "type" : "string", - "nullable" : false - }, - "email" : { - "maxLength" : 100, - "type" : "string", - "format" : "email" - } - } - }, - "HelloDto" : { - "type" : "object", - "properties" : { - "id" : { - "type" : "integer", - "format" : "int32", - "nullable" : false - }, - "name" : { - "type" : "string" - }, - "otherParam" : { - "type" : "string" - }, - "gid" : { - "type" : "string", - "format" : "uuid" - }, - "whenAction" : { - "type" : "string", - "format" : "date-time" - } - } - }, - "HelloForm" : { - "type" : "object", - "properties" : { - "name" : { - "maxLength" : 150, - "minLength" : 2, - "type" : "string", - "nullable" : false - }, - "email" : { - "maxLength" : 100, - "type" : "string", - "format" : "email" - }, - "url" : { - "type" : "string" - }, - "startDate" : { - "type" : "string", - "format" : "date" - } - } - } - } - } + "openapi" : "3.0.1", + "info" : { + "title" : "Example service", + "description" : "Example Javalin controllers with Java and Maven", + "version" : "" + }, + "paths" : { + "/bars" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/bars/find/{code}" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "parameters" : [ + { + "name" : "code", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "items" : { + "$ref" : "#/components/schemas/Bar" + }, + "type" : "array" + } + } + } + } + } + } + }, + "/bars/{id}" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "parameters" : [ + { + "name" : "id", + "in" : "path", + "required" : true, + "schema" : { + "type" : "integer", + "format" : "int64", + "nullable" : false + } + } + ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Bar" + } + } + } + } + } + } + }, + "/baz" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "items" : { + "$ref" : "#/components/schemas/Baz" + }, + "type" : "array" + } + } + } + } + } + }, + "post" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Baz" + } + } + }, + "required" : true + }, + "responses" : { + "201" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "integer", + "format" : "int64" + } + } + } + } + } + } + }, + "/baz/checkparams/{id}" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "parameters" : [ + { + "name" : "id", + "in" : "path", + "required" : true, + "schema" : { + "type" : "integer", + "format" : "int32", + "nullable" : false + } + }, + { + "name" : "p1", + "in" : "query", + "schema" : { + "type" : "string" + } + }, + { + "name" : "p2", + "in" : "query", + "schema" : { + "type" : "number" + } + }, + { + "name" : "p3", + "in" : "query", + "schema" : { + "type" : "integer", + "format" : "int32" + } + }, + { + "name" : "p4", + "in" : "query", + "schema" : { + "type" : "number" + } + }, + { + "name" : "body", + "in" : "query", + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/baz/findbyname/{name}" : { + "get" : { + "tags" : [ + + ], + "summary" : "Find the baz by name", + "description" : "This is some more comments about this method.", + "parameters" : [ + { + "name" : "name", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "description" : "The list of baz", + "content" : { + "application/json" : { + "schema" : { + "items" : { + "$ref" : "#/components/schemas/Baz" + }, + "type" : "array" + } + } + } + } + } + } + }, + "/baz/{id}" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "parameters" : [ + { + "name" : "id", + "in" : "path", + "required" : true, + "schema" : { + "type" : "integer", + "format" : "int64" + } + } + ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Baz" + } + } + } + } + } + } + }, + "/hello" : { + "post" : { + "tags" : [ + + ], + "summary" : "Simple example post with JSON body response", + "description" : "", + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/HelloDto" + } + } + }, + "required" : true + }, + "responses" : { + "201" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/HelloDto" + } + } + } + } + } + } + }, + "/hello/findbyname/{name}" : { + "get" : { + "tags" : [ + + ], + "summary" : "Find Hellos by name", + "description" : "", + "parameters" : [ + { + "name" : "name", + "in" : "path", + "description" : "The name to search for", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "name" : "myParam", + "in" : "query", + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "description" : "The Hellos that we found.", + "content" : { + "application/json" : { + "schema" : { + "items" : { + "$ref" : "#/components/schemas/HelloDto" + }, + "type" : "array" + } + } + } + } + } + } + }, + "/hello/message" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/hello/mySave" : { + "post" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "requestBody" : { + "content" : { + "application/x-www-form-urlencoded" : { + "schema" : { + "type" : "object", + "properties" : { + "name" : { + "type" : "string" + }, + "email" : { + "type" : "string" + }, + "url" : { + "type" : "string" + } + } + } + } + }, + "required" : true + }, + "responses" : { + "201" : { + "description" : "No content" + } + } + } + }, + "/hello/savebean/{foo}" : { + "post" : { + "tags" : [ + + ], + "summary" : "Save the hello using json body", + "description" : "", + "parameters" : [ + { + "name" : "foo", + "in" : "path", + "description" : "The hello doo id", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "requestBody" : { + "description" : "The hello body as json", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/HelloDto" + } + } + }, + "required" : true + }, + "responses" : { + "201" : { + "description" : "No content" + } + } + } + }, + "/hello/saveform" : { + "post" : { + "tags" : [ + + ], + "summary" : "Create the new Hello using a form", + "description" : "", + "requestBody" : { + "content" : { + "application/x-www-form-urlencoded" : { + "schema" : { + "$ref" : "#/components/schemas/HelloForm" + } + } + }, + "required" : true + }, + "responses" : { + "201" : { + "description" : "No content" + } + } + } + }, + "/hello/saveform2" : { + "post" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "requestBody" : { + "content" : { + "application/x-www-form-urlencoded" : { + "schema" : { + "type" : "object", + "properties" : { + "name" : { + "type" : "string" + }, + "email" : { + "type" : "string" + }, + "url" : { + "type" : "string" + } + } + } + } + }, + "required" : true + }, + "responses" : { + "201" : { + "description" : "No content" + } + } + } + }, + "/hello/saveform3" : { + "post" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "requestBody" : { + "content" : { + "application/x-www-form-urlencoded" : { + "schema" : { + "$ref" : "#/components/schemas/HelloForm" + } + } + }, + "required" : true + }, + "responses" : { + "201" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/HelloDto" + } + } + } + } + } + } + }, + "/hello/slash/{name}//other/" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "parameters" : [ + { + "name" : "name", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "name" : "nam0", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "name" : "nam1", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/hello/withMatrix/{year_segment}/{other}" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "parameters" : [ + { + "name" : "year", + "in" : "path", + "required" : true, + "schema" : { + "type" : "integer", + "format" : "int32", + "nullable" : false + } + }, + { + "name" : "author", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "name" : "country", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "name" : "other", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "name" : "extra", + "in" : "query", + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/hello/withValidBean" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "parameters" : [ + { + "name" : "bean", + "in" : "bean", + "schema" : { + "$ref" : "#/components/schemas/GetBeanForm" + } + } + ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/hello/{id}" : { + "delete" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "parameters" : [ + { + "name" : "id", + "in" : "path", + "required" : true, + "schema" : { + "type" : "integer", + "format" : "int32", + "nullable" : false + } + } + ], + "responses" : { + "204" : { + "description" : "No content" + } + } + } + }, + "/hello/{id}/{date}" : { + "get" : { + "tags" : [ + + ], + "summary" : "Return the Hello DTO", + "description" : "", + "parameters" : [ + { + "name" : "id", + "in" : "path", + "description" : "The hello Id.", + "required" : true, + "schema" : { + "type" : "integer", + "format" : "int32", + "nullable" : false + } + }, + { + "name" : "date", + "in" : "path", + "description" : "The name of the hello", + "required" : true, + "schema" : { + "type" : "string", + "format" : "date" + } + }, + { + "name" : "otherParam", + "in" : "query", + "description" : "Optional other parameter", + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "description" : "The Hello DTO given the id and name.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/HelloDto" + } + } + } + } + }, + "deprecated" : true + } + }, + "/req-scoped" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + } + }, + "components" : { + "schemas" : { + "Bar" : { + "type" : "object", + "properties" : { + "id" : { + "type" : "integer", + "format" : "int64", + "nullable" : false + }, + "name" : { + "type" : "string" + } + } + }, + "Baz" : { + "type" : "object", + "properties" : { + "id" : { + "type" : "integer", + "format" : "int64" + }, + "name" : { + "type" : "string" + }, + "startDate" : { + "type" : "string", + "format" : "date" + } + } + }, + "GetBeanForm" : { + "type" : "object", + "properties" : { + "name" : { + "maxLength" : 150, + "minLength" : 2, + "type" : "string", + "nullable" : false + }, + "email" : { + "maxLength" : 100, + "type" : "string", + "format" : "email" + } + } + }, + "HelloDto" : { + "type" : "object", + "properties" : { + "id" : { + "type" : "integer", + "format" : "int32", + "nullable" : false + }, + "name" : { + "type" : "string" + }, + "otherParam" : { + "type" : "string" + }, + "gid" : { + "type" : "string", + "format" : "uuid" + }, + "whenAction" : { + "type" : "string", + "format" : "date-time" + } + } + }, + "HelloForm" : { + "type" : "object", + "properties" : { + "name" : { + "maxLength" : 150, + "minLength" : 2, + "type" : "string", + "nullable" : false + }, + "email" : { + "maxLength" : 100, + "type" : "string", + "format" : "email" + }, + "url" : { + "type" : "string" + }, + "startDate" : { + "type" : "string", + "format" : "date" + } + } + } + } + } } \ No newline at end of file diff --git a/tests/test-jex/src/main/resources/public/openapi.json b/tests/test-jex/src/main/resources/public/openapi.json index aa864f845..fb4378388 100644 --- a/tests/test-jex/src/main/resources/public/openapi.json +++ b/tests/test-jex/src/main/resources/public/openapi.json @@ -1,213 +1,238 @@ { - "openapi" : "3.0.1", - "info" : { - "title" : "", - "version" : "" - }, - "paths" : { - "/" : { - "get" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "responses" : { - "200" : { - "description" : "", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/HelloDto" - } - } - } - } - } - }, - "put" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "requestBody" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/HelloDto" - } - } - }, - "required" : true - }, - "responses" : { - "204" : { - "description" : "No content" - } - } - } - }, - "/other/{name}" : { - "get" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "parameters" : [ { - "name" : "name", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "responses" : { - "200" : { - "description" : "", - "content" : { - "text/plain" : { - "schema" : { - "type" : "string" - } - } - } - } - } - } - }, - "/plain" : { - "get" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "responses" : { - "200" : { - "description" : "", - "content" : { - "text/plain" : { - "schema" : { - "type" : "string" - } - } - } - } - } - } - }, - "/splat/{name}//other/" : { - "get" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "parameters" : [ { - "name" : "name", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "responses" : { - "200" : { - "description" : "", - "content" : { - "text/plain" : { - "schema" : { - "type" : "string" - } - } - } - } - } - } - }, - "/splat2/{name}//other/" : { - "get" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "parameters" : [ { - "name" : "name", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "nam0", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "nam1", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } ], - "responses" : { - "200" : { - "description" : "", - "content" : { - "text/plain" : { - "schema" : { - "type" : "string" - } - } - } - } - } - } - }, - "/withDefault/{name}" : { - "get" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "parameters" : [ { - "name" : "name", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, { - "name" : "limit", - "in" : "query", - "schema" : { - "type" : "string" - } - } ], - "responses" : { - "200" : { - "description" : "", - "content" : { - "text/plain" : { - "schema" : { - "type" : "string" - } - } - } - } - } - } - } - }, - "components" : { - "schemas" : { - "HelloDto" : { - "type" : "object", - "properties" : { - "id" : { - "type" : "integer", - "format" : "int32", - "nullable" : false - }, - "name" : { - "type" : "string", - "nullable" : false - } - } - } - } - } + "openapi" : "3.0.1", + "info" : { + "title" : "", + "version" : "" + }, + "paths" : { + "/" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/HelloDto" + } + } + } + } + } + }, + "put" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/HelloDto" + } + } + }, + "required" : true + }, + "responses" : { + "204" : { + "description" : "No content" + } + } + } + }, + "/other/{name}" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "parameters" : [ + { + "name" : "name", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/plain" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/splat/{name}//other/" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "parameters" : [ + { + "name" : "name", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/splat2/{name}//other/" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "parameters" : [ + { + "name" : "name", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "name" : "nam0", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "name" : "nam1", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/withDefault/{name}" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "parameters" : [ + { + "name" : "name", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "name" : "limit", + "in" : "query", + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + } + }, + "components" : { + "schemas" : { + "HelloDto" : { + "type" : "object", + "properties" : { + "id" : { + "type" : "integer", + "format" : "int32", + "nullable" : false + }, + "name" : { + "type" : "string", + "nullable" : false + } + } + } + } + } } \ No newline at end of file From 22b4775e225eb3cc798c5b438929e760cf3b5060 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Mon, 9 Jan 2023 08:19:42 +1300 Subject: [PATCH 0477/1323] [maven-release-plugin] prepare release avaje-http-generator-parent-1.21 --- http-api/pom.xml | 4 ++-- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 4 ++-- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-generator-nima/pom.xml | 2 +- pom.xml | 4 ++-- 8 files changed, 11 insertions(+), 11 deletions(-) diff --git a/http-api/pom.xml b/http-api/pom.xml index 99072f048..39f003a18 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-generator-parent - 1.21-SNAPSHOT + 1.21 .. @@ -12,7 +12,7 @@ scm:git:git@github.com:avaje/avaje-http.git - avaje-http-generator-parent-1.19 + avaje-http-generator-parent-1.21 diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index 158015e4a..dc2a439ba 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -5,7 +5,7 @@ io.avaje avaje-http-generator-parent - 1.21-SNAPSHOT + 1.21 .. diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 7a3d30157..a233f2e2d 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-generator-parent - 1.21-SNAPSHOT + 1.21 .. @@ -32,7 +32,7 @@ io.avaje avaje-http-api - 1.21-SNAPSHOT + 1.21 diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index ab9bab52b..52972028d 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-generator-parent - 1.21-SNAPSHOT + 1.21 .. diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index 1fa74eca8..f7618072b 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-generator-parent - 1.21-SNAPSHOT + 1.21 .. diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index 9809fa5b4..415b8689a 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-generator-parent - 1.21-SNAPSHOT + 1.21 .. diff --git a/http-generator-nima/pom.xml b/http-generator-nima/pom.xml index 18c11c5d6..2ea00953e 100644 --- a/http-generator-nima/pom.xml +++ b/http-generator-nima/pom.xml @@ -3,7 +3,7 @@ avaje-http-generator-parent io.avaje - 1.21-SNAPSHOT + 1.21 4.0.0 diff --git a/pom.xml b/pom.xml index a9a53c9c9..08fd5d90d 100644 --- a/pom.xml +++ b/pom.xml @@ -9,12 +9,12 @@ io.avaje avaje-http-generator-parent - 1.21-SNAPSHOT + 1.21 pom scm:git:git@github.com:avaje/avaje-http.git - avaje-http-generator-parent-1.19 + avaje-http-generator-parent-1.21 From 6d03a24f09b5eec79b53cb3fedd94b32b673b37d Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Mon, 9 Jan 2023 08:19:49 +1300 Subject: [PATCH 0478/1323] [maven-release-plugin] prepare for next development iteration --- http-api/pom.xml | 4 ++-- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 4 ++-- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-generator-nima/pom.xml | 2 +- pom.xml | 4 ++-- 8 files changed, 11 insertions(+), 11 deletions(-) diff --git a/http-api/pom.xml b/http-api/pom.xml index 39f003a18..7f4c98d55 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-generator-parent - 1.21 + 1.22-SNAPSHOT .. @@ -12,7 +12,7 @@ scm:git:git@github.com:avaje/avaje-http.git - avaje-http-generator-parent-1.21 + avaje-http-generator-parent-1.19 diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index dc2a439ba..04abc512c 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -5,7 +5,7 @@ io.avaje avaje-http-generator-parent - 1.21 + 1.22-SNAPSHOT .. diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index a233f2e2d..08c136896 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-generator-parent - 1.21 + 1.22-SNAPSHOT .. @@ -32,7 +32,7 @@ io.avaje avaje-http-api - 1.21 + 1.22-SNAPSHOT diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index 52972028d..9ec65d0d9 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-generator-parent - 1.21 + 1.22-SNAPSHOT .. diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index f7618072b..c33f2bcde 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-generator-parent - 1.21 + 1.22-SNAPSHOT .. diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index 415b8689a..0df048264 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-generator-parent - 1.21 + 1.22-SNAPSHOT .. diff --git a/http-generator-nima/pom.xml b/http-generator-nima/pom.xml index 2ea00953e..552ff5018 100644 --- a/http-generator-nima/pom.xml +++ b/http-generator-nima/pom.xml @@ -3,7 +3,7 @@ avaje-http-generator-parent io.avaje - 1.21 + 1.22-SNAPSHOT 4.0.0 diff --git a/pom.xml b/pom.xml index 08fd5d90d..db43bc2b1 100644 --- a/pom.xml +++ b/pom.xml @@ -9,12 +9,12 @@ io.avaje avaje-http-generator-parent - 1.21 + 1.22-SNAPSHOT pom scm:git:git@github.com:avaje/avaje-http.git - avaje-http-generator-parent-1.21 + avaje-http-generator-parent-1.19 From c9f04dd9667e88104679fc679310d6f3d9e42a24 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Mon, 9 Jan 2023 08:24:21 +1300 Subject: [PATCH 0479/1323] Bump versions in test modules after release --- tests/test-client/pom.xml | 6 +++--- tests/test-helidon/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-jsonb/.factorypath | 2 +- tests/test-nima-jsonb/pom.xml | 8 ++++---- tests/test-nima/pom.xml | 6 +++--- 8 files changed, 15 insertions(+), 15 deletions(-) diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index 9babe4139..4d68ede87 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -36,7 +36,7 @@ io.avaje avaje-http-api - 1.21-SNAPSHOT + 1.22-SNAPSHOT @@ -108,12 +108,12 @@ io.avaje avaje-http-client-generator - 1.21-SNAPSHOT + 1.22-SNAPSHOT io.avaje avaje-http-jex-generator - 1.21-SNAPSHOT + 1.22-SNAPSHOT io.avaje diff --git a/tests/test-helidon/pom.xml b/tests/test-helidon/pom.xml index 4d1607e4d..f8b08421c 100644 --- a/tests/test-helidon/pom.xml +++ b/tests/test-helidon/pom.xml @@ -17,7 +17,7 @@ true org.example.Main 2.3.0 - 1.21-SNAPSHOT + 1.22-SNAPSHOT diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index a68527ba7..80c3520db 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -21,7 +21,7 @@ 2.0.8 1.3.71 2.13.4.1 - 1.21-SNAPSHOT + 1.22-SNAPSHOT diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index d562c30d8..72715d4db 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -20,7 +20,7 @@ 2.0.8 1.3.71 2.13.4.1 - 1.21-SNAPSHOT + 1.22-SNAPSHOT diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index ea44c178d..2e26ae5fe 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -20,7 +20,7 @@ 2.0.8 2.13.4.1 8.9 - 1.21-SNAPSHOT + 1.22-SNAPSHOT diff --git a/tests/test-nima-jsonb/.factorypath b/tests/test-nima-jsonb/.factorypath index 9b0ba4d09..28dee16ed 100644 --- a/tests/test-nima-jsonb/.factorypath +++ b/tests/test-nima-jsonb/.factorypath @@ -1,7 +1,7 @@ - + diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index c7cf695a3..5805ca7bc 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -4,7 +4,7 @@ avaje-http-generator-parent io.avaje - 1.21-SNAPSHOT + 1.22-SNAPSHOT ../../pom.xml @@ -28,7 +28,7 @@ io.avaje avaje-http-api - 1.21-SNAPSHOT + 1.22-SNAPSHOT io.avaje @@ -48,7 +48,7 @@ io.avaje avaje-http-nima-generator - 1.21-SNAPSHOT + 1.22-SNAPSHOT test @@ -75,7 +75,7 @@ io.avaje avaje-http-nima-generator - 1.21-SNAPSHOT + 1.22-SNAPSHOT io.avaje diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index f6c42b1b2..52e954a3a 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -6,7 +6,7 @@ avaje-http-generator-parent io.avaje - 1.21-SNAPSHOT + 1.22-SNAPSHOT ../../pom.xml @@ -30,7 +30,7 @@ io.avaje avaje-http-api - 1.21-SNAPSHOT + 1.22-SNAPSHOT io.helidon.nima.webserver @@ -67,7 +67,7 @@ io.avaje avaje-http-nima-generator - 1.21-SNAPSHOT + 1.22-SNAPSHOT io.avaje From f51b1dfaf492406f0ca5446d1ba143a8813ba88a Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Mon, 9 Jan 2023 18:32:50 -0500 Subject: [PATCH 0480/1323] fix flag --- .../http/generator/core/BaseProcessor.java | 2 +- .../generator/core/ProcessingContext.java | 24 +++++--- .../generator/core/openapi/JsonFormatter.java | 3 - .../core/openapi/OpenAPISerializer.java | 4 +- .../http/generator/JavalinProcessorTest.java | 60 ++++++++++++++++++- 5 files changed, 78 insertions(+), 15 deletions(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java index 03507e519..4a01b96a6 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java @@ -17,7 +17,7 @@ import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tags; -@SupportedOptions({"useJavax"}) +@SupportedOptions({"useJavax","useSingleton"}) public abstract class BaseProcessor extends AbstractProcessor { protected ProcessingContext ctx; diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java index 51d0447a7..4ca1bc2e0 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java @@ -32,24 +32,34 @@ public class ProcessingContext { private final String diAnnotation; public ProcessingContext(ProcessingEnvironment env, PlatformAdapter readAdapter) { - this.readAdapter = readAdapter; + + this.readAdapter = readAdapter; this.messager = env.getMessager(); this.filer = env.getFiler(); this.elements = env.getElementUtils(); this.types = env.getTypeUtils(); this.openApiAvailable = isTypeAvailable(Constants.OPENAPIDEFINITION); this.docContext = new DocContext(env, openApiAvailable); - this.useComponent = isTypeAvailable(Constants.COMPONENT); + + final var options = env.getOptions(); + final var singletonOverride = options.get("useSingleton"); + + if (singletonOverride != null) { + this.useComponent = !Boolean.parseBoolean(singletonOverride); + } else { + this.useComponent = isTypeAvailable(Constants.COMPONENT); + } + this.diAnnotation = useComponent ? "@Component" : "@Singleton"; final var javax = isTypeAvailable(Constants.SINGLETON_JAVAX); final var jakarta = isTypeAvailable(Constants.SINGLETON_JAKARTA); - final var override = Boolean.getBoolean(env.getOptions().get("useJavax")); + final var override = env.getOptions().get("useJavax"); - if (override || (javax && jakarta)) { - this.useJavax = override; - } else if (javax) { - this.useJavax = true; + if (override != null || (javax && jakarta)) { + this.useJavax = Boolean.parseBoolean(override); + } else if (javax && !jakarta) { + useJavax = javax; } else { useJavax = false; } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/JsonFormatter.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/JsonFormatter.java index b89e775f5..cebed7bd1 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/JsonFormatter.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/JsonFormatter.java @@ -40,9 +40,6 @@ public static String prettyPrintJson(Writer writer, String json) throws IOExcept writer.append(current).append("\n"); addIndents(writer, indentLevel); break; - case ':': - writer.append(" :"); - break; default: writer.append(current); break; diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/OpenAPISerializer.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/OpenAPISerializer.java index 66879e45c..0f69ada46 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/OpenAPISerializer.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/OpenAPISerializer.java @@ -50,7 +50,7 @@ static String serialize(Object obj) throws IllegalAccessException { } sb.append("\""); sb.append(entry.getKey()); - sb.append("\": "); + sb.append("\" : "); write(sb, entry.getValue()); firstElement = false; @@ -75,7 +75,7 @@ static String serialize(Object obj) throws IllegalAccessException { } sb.append("\""); sb.append(field.getName()); - sb.append("\": "); + sb.append("\" : "); write(sb, value); firstField = false; } diff --git a/tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/JavalinProcessorTest.java b/tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/JavalinProcessorTest.java index 617676246..555cdc7b7 100644 --- a/tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/JavalinProcessorTest.java +++ b/tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/JavalinProcessorTest.java @@ -41,7 +41,7 @@ void deleteGeneratedFiles() throws IOException { } @Test - public void runAnnoationProcessor() throws Exception { + public void runAnnotationProcessor() throws Exception { final var source = Paths.get("src").toAbsolutePath().toString(); final var files = getSourceFiles(source); @@ -54,10 +54,13 @@ public void runAnnoationProcessor() throws Exception { task.setProcessors(List.of(new JavalinProcessor())); assertThat(task.call()).isTrue(); + assert Files.readString( + Paths.get("org/example/myapp/web/BarController$Route.java").toAbsolutePath()) + .contains("io.avaje.inject.Component"); } @Test - public void runAnnoationProcessorJsonB() throws Exception { + public void runAnnotationProcessorJsonB() throws Exception { final var source = Paths.get("src").toAbsolutePath().toString(); final var files = getSourceFiles(source); @@ -67,9 +70,62 @@ public void runAnnoationProcessorJsonB() throws Exception { final var task = compiler.getTask( new PrintWriter(System.out), null, null, List.of("--release=11"), null, files); + task.setProcessors(List.of(new JavalinProcessor(true), new Processor())); + + assertThat(task.call()).isTrue(); + assert Files.readString( + Paths.get("org/example/myapp/web/BarController$Route.java").toAbsolutePath()) + .contains("io.avaje.jsonb.Jsonb"); + } + + @Test + public void runAnnotationProcessorJavax() throws Exception { + final var source = Paths.get("src").toAbsolutePath().toString(); + + final var files = getSourceFiles(source); + + final var compiler = ToolProvider.getSystemJavaCompiler(); + + final var task = + compiler.getTask( + new PrintWriter(System.out), + null, + null, + List.of("--release=11", "-AuseJavax=true", "-AuseSingleton=true"), + null, + files); + task.setProcessors(List.of(new JavalinProcessor(false), new Processor())); + // we don't have javax on the cp + assertThat(task.call()).isFalse(); + + assert Files.readString( + Paths.get("org/example/myapp/web/BarController$Route.java").toAbsolutePath()) + .contains("javax.inject.Singleton"); + } + + @Test + public void runAnnotationProcessorJakarta() throws Exception { + final var source = Paths.get("src").toAbsolutePath().toString(); + + final var files = getSourceFiles(source); + + final var compiler = ToolProvider.getSystemJavaCompiler(); + + final var task = + compiler.getTask( + new PrintWriter(System.out), + null, + null, + List.of("--release=11", "-AuseJavax=false", "-AuseSingleton=true"), + null, + files); task.setProcessors(List.of(new JavalinProcessor(false), new Processor())); assertThat(task.call()).isTrue(); + + assert Files.readString( + Paths.get("org/example/myapp/web/BarController$Route.java").toAbsolutePath()) + .contains("jakarta.inject.Singleton"); } @Test From 1ef641973407f1c4a4e43c7a7b89dcf249e291a9 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Mon, 9 Jan 2023 18:35:00 -0500 Subject: [PATCH 0481/1323] Update ProcessingContext.java --- .../java/io/avaje/http/generator/core/ProcessingContext.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java index 4ca1bc2e0..143ee84a7 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java @@ -33,7 +33,7 @@ public class ProcessingContext { public ProcessingContext(ProcessingEnvironment env, PlatformAdapter readAdapter) { - this.readAdapter = readAdapter; + this.readAdapter = readAdapter; this.messager = env.getMessager(); this.filer = env.getFiler(); this.elements = env.getElementUtils(); From 85586fd0ea21c1811da40570c17c4a758c18c60a Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 10 Jan 2023 22:43:07 +1300 Subject: [PATCH 0482/1323] No effective change - tidy ProcessingContext only --- .../java/io/avaje/http/generator/core/ProcessingContext.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java index 143ee84a7..fcb51fc09 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java @@ -32,7 +32,6 @@ public class ProcessingContext { private final String diAnnotation; public ProcessingContext(ProcessingEnvironment env, PlatformAdapter readAdapter) { - this.readAdapter = readAdapter; this.messager = env.getMessager(); this.filer = env.getFiler(); @@ -43,19 +42,16 @@ public ProcessingContext(ProcessingEnvironment env, PlatformAdapter readAdapter) final var options = env.getOptions(); final var singletonOverride = options.get("useSingleton"); - if (singletonOverride != null) { this.useComponent = !Boolean.parseBoolean(singletonOverride); } else { this.useComponent = isTypeAvailable(Constants.COMPONENT); } - this.diAnnotation = useComponent ? "@Component" : "@Singleton"; final var javax = isTypeAvailable(Constants.SINGLETON_JAVAX); final var jakarta = isTypeAvailable(Constants.SINGLETON_JAKARTA); final var override = env.getOptions().get("useJavax"); - if (override != null || (javax && jakarta)) { this.useJavax = Boolean.parseBoolean(override); } else if (javax && !jakarta) { From c73eb050b771780dd67a89d5db8ef8529dc0826d Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 10 Jan 2023 22:43:36 +1300 Subject: [PATCH 0483/1323] bump test-nima-jsonb test dependencies --- tests/test-nima-jsonb/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 5805ca7bc..6f56c22c9 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -23,7 +23,7 @@ io.avaje avaje-inject - 8.10 + 8.11 io.avaje @@ -33,7 +33,7 @@ io.avaje avaje-jsonb - 1.1-RC2 + 1.1 io.helidon.nima.webserver From 0930af9ca12d1ddf000382ef72298607d1b5e109 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 10 Jan 2023 23:01:48 +1300 Subject: [PATCH 0484/1323] [maven-release-plugin] prepare release avaje-http-generator-parent-1.22 --- http-api/pom.xml | 4 ++-- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 4 ++-- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-generator-nima/pom.xml | 2 +- pom.xml | 4 ++-- 8 files changed, 11 insertions(+), 11 deletions(-) diff --git a/http-api/pom.xml b/http-api/pom.xml index 7f4c98d55..104cfda27 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-generator-parent - 1.22-SNAPSHOT + 1.22 .. @@ -12,7 +12,7 @@ scm:git:git@github.com:avaje/avaje-http.git - avaje-http-generator-parent-1.19 + avaje-http-generator-parent-1.22 diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index 04abc512c..73712aede 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -5,7 +5,7 @@ io.avaje avaje-http-generator-parent - 1.22-SNAPSHOT + 1.22 .. diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 08c136896..52db4f362 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-generator-parent - 1.22-SNAPSHOT + 1.22 .. @@ -32,7 +32,7 @@ io.avaje avaje-http-api - 1.22-SNAPSHOT + 1.22 diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index 9ec65d0d9..12c592b68 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-generator-parent - 1.22-SNAPSHOT + 1.22 .. diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index c33f2bcde..7f253cd8a 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-generator-parent - 1.22-SNAPSHOT + 1.22 .. diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index 0df048264..8094ef43e 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-generator-parent - 1.22-SNAPSHOT + 1.22 .. diff --git a/http-generator-nima/pom.xml b/http-generator-nima/pom.xml index 552ff5018..3cc9084c1 100644 --- a/http-generator-nima/pom.xml +++ b/http-generator-nima/pom.xml @@ -3,7 +3,7 @@ avaje-http-generator-parent io.avaje - 1.22-SNAPSHOT + 1.22 4.0.0 diff --git a/pom.xml b/pom.xml index db43bc2b1..e33244103 100644 --- a/pom.xml +++ b/pom.xml @@ -9,12 +9,12 @@ io.avaje avaje-http-generator-parent - 1.22-SNAPSHOT + 1.22 pom scm:git:git@github.com:avaje/avaje-http.git - avaje-http-generator-parent-1.19 + avaje-http-generator-parent-1.22 From f6371a7b25d65c402370375d68c6b1535e8d56b3 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 10 Jan 2023 23:02:20 +1300 Subject: [PATCH 0485/1323] [maven-release-plugin] prepare for next development iteration --- http-api/pom.xml | 4 ++-- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 4 ++-- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-generator-nima/pom.xml | 2 +- pom.xml | 4 ++-- 8 files changed, 11 insertions(+), 11 deletions(-) diff --git a/http-api/pom.xml b/http-api/pom.xml index 104cfda27..ad9d130fa 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-generator-parent - 1.22 + 1.23-SNAPSHOT .. @@ -12,7 +12,7 @@ scm:git:git@github.com:avaje/avaje-http.git - avaje-http-generator-parent-1.22 + avaje-http-generator-parent-1.19 diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index 73712aede..140a9aa8a 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -5,7 +5,7 @@ io.avaje avaje-http-generator-parent - 1.22 + 1.23-SNAPSHOT .. diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 52db4f362..d5cfe3c25 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-generator-parent - 1.22 + 1.23-SNAPSHOT .. @@ -32,7 +32,7 @@ io.avaje avaje-http-api - 1.22 + 1.23-SNAPSHOT diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index 12c592b68..d5623fdc4 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-generator-parent - 1.22 + 1.23-SNAPSHOT .. diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index 7f253cd8a..2262c4688 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-generator-parent - 1.22 + 1.23-SNAPSHOT .. diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index 8094ef43e..2ae1b6ceb 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-generator-parent - 1.22 + 1.23-SNAPSHOT .. diff --git a/http-generator-nima/pom.xml b/http-generator-nima/pom.xml index 3cc9084c1..884575f2c 100644 --- a/http-generator-nima/pom.xml +++ b/http-generator-nima/pom.xml @@ -3,7 +3,7 @@ avaje-http-generator-parent io.avaje - 1.22 + 1.23-SNAPSHOT 4.0.0 diff --git a/pom.xml b/pom.xml index e33244103..a12ff39d5 100644 --- a/pom.xml +++ b/pom.xml @@ -9,12 +9,12 @@ io.avaje avaje-http-generator-parent - 1.22 + 1.23-SNAPSHOT pom scm:git:git@github.com:avaje/avaje-http.git - avaje-http-generator-parent-1.22 + avaje-http-generator-parent-1.19 From f5f06c05e9ef577529d2123668702310a9ee6295 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 10 Jan 2023 23:48:08 +1300 Subject: [PATCH 0486/1323] Bump test modules to 1.23-SNAPSHOT after release --- tests/test-client/pom.xml | 6 +++--- tests/test-helidon/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-jsonb/.factorypath | 2 +- tests/test-nima-jsonb/pom.xml | 8 ++++---- tests/test-nima/pom.xml | 6 +++--- 8 files changed, 15 insertions(+), 15 deletions(-) diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index 4d68ede87..5c2dc3978 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -36,7 +36,7 @@ io.avaje avaje-http-api - 1.22-SNAPSHOT + 1.23-SNAPSHOT @@ -108,12 +108,12 @@ io.avaje avaje-http-client-generator - 1.22-SNAPSHOT + 1.23-SNAPSHOT io.avaje avaje-http-jex-generator - 1.22-SNAPSHOT + 1.23-SNAPSHOT io.avaje diff --git a/tests/test-helidon/pom.xml b/tests/test-helidon/pom.xml index f8b08421c..ea03df3ee 100644 --- a/tests/test-helidon/pom.xml +++ b/tests/test-helidon/pom.xml @@ -17,7 +17,7 @@ true org.example.Main 2.3.0 - 1.22-SNAPSHOT + 1.23-SNAPSHOT diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 80c3520db..290e56c0f 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -21,7 +21,7 @@ 2.0.8 1.3.71 2.13.4.1 - 1.22-SNAPSHOT + 1.23-SNAPSHOT diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 72715d4db..5ca6ca25c 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -20,7 +20,7 @@ 2.0.8 1.3.71 2.13.4.1 - 1.22-SNAPSHOT + 1.23-SNAPSHOT diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 2e26ae5fe..59907959a 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -20,7 +20,7 @@ 2.0.8 2.13.4.1 8.9 - 1.22-SNAPSHOT + 1.23-SNAPSHOT diff --git a/tests/test-nima-jsonb/.factorypath b/tests/test-nima-jsonb/.factorypath index 28dee16ed..bf32270c8 100644 --- a/tests/test-nima-jsonb/.factorypath +++ b/tests/test-nima-jsonb/.factorypath @@ -1,7 +1,7 @@ - + diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 6f56c22c9..ea8feacf3 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -4,7 +4,7 @@ avaje-http-generator-parent io.avaje - 1.22-SNAPSHOT + 1.23-SNAPSHOT ../../pom.xml @@ -28,7 +28,7 @@ io.avaje avaje-http-api - 1.22-SNAPSHOT + 1.23-SNAPSHOT io.avaje @@ -48,7 +48,7 @@ io.avaje avaje-http-nima-generator - 1.22-SNAPSHOT + 1.23-SNAPSHOT test @@ -75,7 +75,7 @@ io.avaje avaje-http-nima-generator - 1.22-SNAPSHOT + 1.23-SNAPSHOT io.avaje diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index 52e954a3a..1ec5b8823 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -6,7 +6,7 @@ avaje-http-generator-parent io.avaje - 1.22-SNAPSHOT + 1.23-SNAPSHOT ../../pom.xml @@ -30,7 +30,7 @@ io.avaje avaje-http-api - 1.22-SNAPSHOT + 1.23-SNAPSHOT io.helidon.nima.webserver @@ -67,7 +67,7 @@ io.avaje avaje-http-nima-generator - 1.22-SNAPSHOT + 1.23-SNAPSHOT io.avaje From dc2f003311194f0e08edba0d4fa63d44282b70ac Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sun, 15 Jan 2023 15:13:21 -0500 Subject: [PATCH 0487/1323] now can define path in controller --- .../java/io/avaje/http/api/Controller.java | 23 ++++++------ .../http/generator/core/ControllerReader.java | 35 +++++++++++-------- .../main/java/org/example/FooController.java | 3 +- 3 files changed, 34 insertions(+), 27 deletions(-) diff --git a/http-api/src/main/java/io/avaje/http/api/Controller.java b/http-api/src/main/java/io/avaje/http/api/Controller.java index 0869c16f9..e920e7352 100644 --- a/http-api/src/main/java/io/avaje/http/api/Controller.java +++ b/http-api/src/main/java/io/avaje/http/api/Controller.java @@ -1,25 +1,26 @@ package io.avaje.http.api; -import java.lang.annotation.Retention; -import java.lang.annotation.Target; - import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + /** * Marker annotation for controllers. * *

{@code
- *
- *  @Controller
- *  @Path("/customers")
- *  class CustomerController {
- *    ...
- *  }
+ * @Controller("/customers")
+ * class CustomerController {
+ *   ...
+ * }
  *
  * }
*/ -@Target(value=TYPE) -@Retention(value=RUNTIME) +@Target(TYPE) +@Retention(RUNTIME) public @interface Controller { + + /** Specify the path mapping request to the controller. */ + String value() default ""; } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java index 1e711199c..8dcc5a933 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java @@ -1,8 +1,13 @@ package io.avaje.http.generator.core; -import io.avaje.http.api.Path; -import io.avaje.http.api.Produces; -import io.swagger.v3.oas.annotations.Hidden; +import static java.util.function.Predicate.not; + +import java.lang.annotation.Annotation; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.Set; +import java.util.TreeSet; import javax.lang.model.element.Element; import javax.lang.model.element.ElementKind; @@ -14,11 +19,11 @@ import javax.lang.model.type.TypeMirror; import javax.lang.model.util.ElementFilter; import javax.validation.Valid; -import java.lang.annotation.Annotation; -import java.util.ArrayList; -import java.util.List; -import java.util.Set; -import java.util.TreeSet; + +import io.avaje.http.api.Controller; +import io.avaje.http.api.Path; +import io.avaje.http.api.Produces; +import io.swagger.v3.oas.annotations.Hidden; /** * Reads the type information for the Controller (bean). @@ -79,7 +84,7 @@ private List initInterfaces() { List interfaces = new ArrayList<>(); for (TypeMirror anInterface : beanType.getInterfaces()) { final Element ifaceElement = ctx.asElement(anInterface); - if (ifaceElement.getAnnotation(Path.class) != null) { + if ((ifaceElement.getAnnotation(Path.class) != null) || !ifaceElement.getAnnotation(Controller.class).value().isBlank()) { interfaces.add(ifaceElement); } } @@ -250,11 +255,13 @@ public List methods() { } public String path() { - Path path = findAnnotation(Path.class); - if (path == null) { - return null; - } - return Util.trimPath(path.value()); + + return Optional.ofNullable(findAnnotation(Controller.class)) + .map(Controller::value) + .filter(not(String::isBlank)) + .or(() -> Optional.ofNullable(findAnnotation(Path.class)).map(Path::value)) + .map(Util::trimPath) + .orElse(null); } public void addImportType(String rawType) { diff --git a/tests/test-helidon/src/main/java/org/example/FooController.java b/tests/test-helidon/src/main/java/org/example/FooController.java index 6c3d5e330..b003c667c 100644 --- a/tests/test-helidon/src/main/java/org/example/FooController.java +++ b/tests/test-helidon/src/main/java/org/example/FooController.java @@ -18,8 +18,7 @@ import java.util.ArrayList; import java.util.List; -@Controller -@Path("/foo") +@Controller("/foo") public class FooController { //@Produces("text/plain") From 288b53f79adc55b490ab598798052b9dcd973266 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sun, 15 Jan 2023 15:24:06 -0500 Subject: [PATCH 0488/1323] Update README.md --- README.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/README.md b/README.md index 5ea96044a..e04187713 100644 --- a/README.md +++ b/README.md @@ -75,11 +75,9 @@ package org.example.hello; import io.avaje.http.api.Controller; import io.avaje.http.api.Get; -import io.avaje.http.api.Path; import java.util.List; -@Path("/widgets") -@Controller +@Controller("/widgets") public class WidgetController { private final HelloComponent hello; public WidgetController(HelloComponent hello) { From ff6b27070215127589f898bd8a13e24af25a2aa1 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sun, 15 Jan 2023 15:27:40 -0500 Subject: [PATCH 0489/1323] Update ControllerReader.java --- .../java/io/avaje/http/generator/core/ControllerReader.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java index 8dcc5a933..4b6d0f981 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java @@ -84,7 +84,8 @@ private List initInterfaces() { List interfaces = new ArrayList<>(); for (TypeMirror anInterface : beanType.getInterfaces()) { final Element ifaceElement = ctx.asElement(anInterface); - if ((ifaceElement.getAnnotation(Path.class) != null) || !ifaceElement.getAnnotation(Controller.class).value().isBlank()) { + if (!ifaceElement.getAnnotation(Controller.class).value().isBlank() + || ifaceElement.getAnnotation(Path.class) != null) { interfaces.add(ifaceElement); } } @@ -256,7 +257,7 @@ public List methods() { public String path() { - return Optional.ofNullable(findAnnotation(Controller.class)) + return Optional.of(findAnnotation(Controller.class)) .map(Controller::value) .filter(not(String::isBlank)) .or(() -> Optional.ofNullable(findAnnotation(Path.class)).map(Path::value)) From a9a070546979b0e0d89b827beecef5f99595faee Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sun, 15 Jan 2023 15:33:48 -0500 Subject: [PATCH 0490/1323] handle null --- .../java/io/avaje/http/generator/core/ControllerReader.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java index 4b6d0f981..363e27a13 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java @@ -84,7 +84,8 @@ private List initInterfaces() { List interfaces = new ArrayList<>(); for (TypeMirror anInterface : beanType.getInterfaces()) { final Element ifaceElement = ctx.asElement(anInterface); - if (!ifaceElement.getAnnotation(Controller.class).value().isBlank() + var controller = ifaceElement.getAnnotation(Controller.class); + if (controller != null && !controller.value().isBlank() || ifaceElement.getAnnotation(Path.class) != null) { interfaces.add(ifaceElement); } @@ -257,7 +258,7 @@ public List methods() { public String path() { - return Optional.of(findAnnotation(Controller.class)) + return Optional.ofNullable(findAnnotation(Controller.class)) .map(Controller::value) .filter(not(String::isBlank)) .or(() -> Optional.ofNullable(findAnnotation(Path.class)).map(Path::value)) From 9b9eb7cbbcdecb5fbd3a0efc0005c1133338a0d3 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sun, 15 Jan 2023 21:26:00 -0500 Subject: [PATCH 0491/1323] fix annotations --- .../io/avaje/http/generator/core/Util.java | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/Util.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/Util.java index 09d47dc46..29544e52b 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/Util.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/Util.java @@ -16,11 +16,12 @@ public class Util { * Parse the raw type potentially handling generic parameters. */ public static UType parse(String rawType) { - int pos = rawType.indexOf('<'); + var type = trimAnnotations(rawType); + int pos = type.indexOf('<'); if (pos == -1) { - return new UType.Basic(rawType); + return new UType.Basic(type); } else { - return new UType.Generic(rawType); + return new UType.Generic(type); } } @@ -30,10 +31,19 @@ public static UType parse(String rawType) { public static String typeDef(TypeMirror typeMirror) { if (typeMirror.getKind() == TypeKind.DECLARED) { DeclaredType declaredType = (DeclaredType) typeMirror; + return declaredType.asElement().toString(); } else { - return typeMirror.toString(); + return trimAnnotations(typeMirror.toString()); + } + } + + static String trimAnnotations(String type) { + int pos = type.indexOf("@"); + if (pos == -1) { + return type; } + return type.substring(0, pos) + type.substring(type.lastIndexOf(' ') + 1); } static String trimPath(String value) { From 79e3f7adcebe1f29444829a11f5314418c76eb3f Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Mon, 16 Jan 2023 00:30:59 -0500 Subject: [PATCH 0492/1323] inherit roles --- .../main/java/io/avaje/http/generator/core/MethodReader.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java index 0d4a9b491..c00e52f9f 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java @@ -215,7 +215,8 @@ public void buildApiDocumentation(ProcessingContext ctx) { } public List roles() { - return methodRoles.isEmpty() ? bean.roles() : methodRoles; + methodRoles.addAll(bean.roles()); + return methodRoles; } public boolean isWebMethod() { From d0c19d208bb1cf78ed6e565ca8d67963cd0845f0 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Mon, 16 Jan 2023 21:57:06 +1300 Subject: [PATCH 0493/1323] #125 - Add unit tests for Util.trimAnnotations() --- .../test/java/io/avaje/http/generator/core/UtilTest.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/http-generator-core/src/test/java/io/avaje/http/generator/core/UtilTest.java b/http-generator-core/src/test/java/io/avaje/http/generator/core/UtilTest.java index 25a922705..9ee2b5aff 100644 --- a/http-generator-core/src/test/java/io/avaje/http/generator/core/UtilTest.java +++ b/http-generator-core/src/test/java/io/avaje/http/generator/core/UtilTest.java @@ -186,4 +186,12 @@ void shortName() { assertThat(Util.name("Map")).isEqualTo("mapStringPerson"); } + @Test + void trimAnnotations() { + assertEquals("java.lang.String", Util.trimAnnotations("java.lang.String")); + assertEquals("java.lang.String", Util.trimAnnotations("java.lang.@javax.validation.constraints.Email String")); + assertEquals("java.lang.String", Util.trimAnnotations("java.lang.@javax.validation.constraints.NotNull,@javax.validation.constraints.Size(min=2, max=150) String")); + assertEquals("java.lang.String", Util.trimAnnotations("java.lang.@javax.validation.constraints.Email,@javax.validation.constraints.Size(max=100) String")); + } + } From 4e7135b39530e6f1141a3c42229ab24ff994a5d0 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Mon, 16 Jan 2023 22:18:54 +1300 Subject: [PATCH 0494/1323] Introduce HttpClient.Metrics and HttpClient.Builder.State --- .../client/DHttpClientContextBuilder.java | 2 +- .../java/io/avaje/http/client/HttpClient.java | 100 ++++++++++++++++++ .../avaje/http/client/HttpClientContext.java | 64 +---------- 3 files changed, 104 insertions(+), 62 deletions(-) create mode 100644 http-client/client/src/main/java/io/avaje/http/client/HttpClient.java diff --git a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContextBuilder.java b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContextBuilder.java index 75f068c18..2e1bb1585 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContextBuilder.java +++ b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContextBuilder.java @@ -19,7 +19,7 @@ import static java.util.Objects.requireNonNull; -final class DHttpClientContextBuilder implements HttpClientContext.Builder.State { +final class DHttpClientContextBuilder implements HttpClientContext.Builder, HttpClientContext.Builder.State { private HttpClient client; private String baseUrl; diff --git a/http-client/client/src/main/java/io/avaje/http/client/HttpClient.java b/http-client/client/src/main/java/io/avaje/http/client/HttpClient.java new file mode 100644 index 000000000..643a43cb7 --- /dev/null +++ b/http-client/client/src/main/java/io/avaje/http/client/HttpClient.java @@ -0,0 +1,100 @@ +package io.avaje.http.client; + +import java.time.Duration; + +/** + * The HTTP client context that we use to build and process requests. + * + *
{@code
+ *
+ *   HttpClient client = HttpClient.builder()
+ *       .baseUrl("http://localhost:8080")
+ *       .bodyAdapter(new JacksonBodyAdapter())
+ *       .build();
+ *
+ *  HelloDto dto = client.request()
+ *       .path("hello")
+ *       .queryParam("name", "Rob")
+ *       .queryParam("say", "Whats up")
+ *       .GET()
+ *       .bean(HelloDto.class);
+ *
+ * }
+ */ +public interface HttpClient { + + interface Builder { + + /** + * The state of the builder with methods to read the set state. + */ + interface State { + + /** + * Return the base URL. + */ + String baseUrl(); + + /** + * Return the body adapter. + */ + BodyAdapter bodyAdapter(); + + /** + * Return the HttpClient. + */ + java.net.http.HttpClient client(); + + /** + * Return true if requestLogging is on. + */ + boolean requestLogging(); + + /** + * Return the request timeout. + */ + Duration requestTimeout(); + + /** + * Return the retry handler. + */ + RetryHandler retryHandler(); + } + } + + /** + * Statistic metrics collected to provide an overview of activity of this client. + */ + interface Metrics { + + /** + * Return the total number of responses. + */ + long totalCount(); + + /** + * Return the total number of error responses (status code >= 300). + */ + long errorCount(); + + /** + * Return the total response bytes (excludes streaming responses). + */ + long responseBytes(); + + /** + * Return the total response time in microseconds. + */ + long totalMicros(); + + /** + * Return the max response time in microseconds (since the last reset). + */ + long maxMicros(); + + /** + * Return the average response time in microseconds. + */ + long avgMicros(); + } +} diff --git a/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java b/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java index 3fc7b7394..33ab6f7d9 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java +++ b/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java @@ -346,73 +346,15 @@ interface Builder { /** * The state of the builder with methods to read the set state. */ - interface State extends Builder { - - /** - * Return the base URL. - */ - String baseUrl(); - - /** - * Return the body adapter. - */ - BodyAdapter bodyAdapter(); - - /** - * Return the HttpClient. - */ - HttpClient client(); - - /** - * Return true if requestLogging is on. - */ - boolean requestLogging(); - - /** - * Return the request timeout. - */ - Duration requestTimeout(); - - /** - * Return the retry handler. - */ - RetryHandler retryHandler(); + interface State extends io.avaje.http.client.HttpClient.Builder.State { + } } /** * Statistic metrics collected to provide an overview of activity of this client. */ - interface Metrics { - - /** - * Return the total number of responses. - */ - long totalCount(); - - /** - * Return the total number of error responses (status code >= 300). - */ - long errorCount(); - - /** - * Return the total response bytes (excludes streaming responses). - */ - long responseBytes(); + interface Metrics extends io.avaje.http.client.HttpClient.Metrics { - /** - * Return the total response time in microseconds. - */ - long totalMicros(); - - /** - * Return the max response time in microseconds (since the last reset). - */ - long maxMicros(); - - /** - * Return the average response time in microseconds. - */ - long avgMicros(); } } From 67b5437efb641ec40d07e5f62f3b27093761a1be Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 17 Jan 2023 00:04:17 +1300 Subject: [PATCH 0495/1323] Introduce HttpClient and HttpClient.Builder --- .../io/avaje/http/client/DBaseBuilder.java | 172 +++++++++++ .../avaje/http/client/DHttpClientBuilder.java | 172 +++++++++++ .../avaje/http/client/DHttpClientContext.java | 2 +- .../client/DHttpClientContextBuilder.java | 151 +--------- .../java/io/avaje/http/client/HttpClient.java | 266 ++++++++++++++++++ .../avaje/http/client/HttpClientContext.java | 81 +----- .../io/avaje/http/client/SpiHttpClient.java | 53 ++++ .../http/client/DHttpClientContextTest.java | 26 +- .../http/client/HelloControllerTest.java | 37 ++- .../github/httpclient/Simple$HttpClient.java | 2 +- 10 files changed, 718 insertions(+), 244 deletions(-) create mode 100644 http-client/client/src/main/java/io/avaje/http/client/DBaseBuilder.java create mode 100644 http-client/client/src/main/java/io/avaje/http/client/DHttpClientBuilder.java create mode 100644 http-client/client/src/main/java/io/avaje/http/client/SpiHttpClient.java diff --git a/http-client/client/src/main/java/io/avaje/http/client/DBaseBuilder.java b/http-client/client/src/main/java/io/avaje/http/client/DBaseBuilder.java new file mode 100644 index 000000000..789316bf9 --- /dev/null +++ b/http-client/client/src/main/java/io/avaje/http/client/DBaseBuilder.java @@ -0,0 +1,172 @@ +package io.avaje.http.client; + +import com.fasterxml.jackson.databind.ObjectMapper; +import io.avaje.inject.BeanScope; +import io.avaje.jsonb.Jsonb; + +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLParameters; +import java.net.Authenticator; +import java.net.CookieHandler; +import java.net.CookieManager; +import java.net.ProxySelector; +import java.time.Duration; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.concurrent.Executor; + +import static java.util.Objects.requireNonNull; + +abstract class DBaseBuilder { + + java.net.http.HttpClient client; + String baseUrl; + boolean requestLogging = true; + Duration requestTimeout = Duration.ofSeconds(20); + BodyAdapter bodyAdapter; + RetryHandler retryHandler; + AuthTokenProvider authTokenProvider; + + CookieHandler cookieHandler = new CookieManager(); + java.net.http.HttpClient.Redirect redirect = java.net.http.HttpClient.Redirect.NORMAL; + java.net.http.HttpClient.Version version; + Executor executor; + ProxySelector proxy; + SSLContext sslContext; + SSLParameters sslParameters; + Authenticator authenticator; + int priority; + + final List interceptors = new ArrayList<>(); + final List listeners = new ArrayList<>(); + + void configureFromScope(BeanScope beanScope) { + if (bodyAdapter == null) { + configureBodyAdapter(beanScope); + } + if (retryHandler == null) { + configureRetryHandler(beanScope); + } + } + + private void configureRetryHandler(BeanScope beanScope) { + beanScope.getOptional(RetryHandler.class) + .ifPresent(this::setRetryHandler); + } + + private void setRetryHandler(RetryHandler retryHandler) { + this.retryHandler = retryHandler; + } + + private void configureBodyAdapter(BeanScope beanScope) { + Optional body = beanScope.getOptional(BodyAdapter.class); + if (body.isPresent()) { + bodyAdapter = body.get(); + } else if (beanScope.contains("io.avaje.jsonb.Jsonb")) { + bodyAdapter = new JsonbBodyAdapter(beanScope.get(Jsonb.class)); + } else if (beanScope.contains("com.fasterxml.jackson.databind.ObjectMapper")) { + ObjectMapper objectMapper = beanScope.get(ObjectMapper.class); + bodyAdapter = new JacksonBodyAdapter(objectMapper); + } + } + + private RequestListener buildListener() { + if (listeners.isEmpty()) { + return null; + } else if (listeners.size() == 1) { + return listeners.get(0); + } else { + return new DRequestListeners(listeners); + } + } + + private RequestIntercept buildIntercept() { + if (interceptors.isEmpty()) { + return null; + } else if (interceptors.size() == 1) { + return interceptors.get(0); + } else { + return new DRequestInterceptors(interceptors); + } + } + + private java.net.http.HttpClient defaultClient() { + final java.net.http.HttpClient.Builder builder = java.net.http.HttpClient.newBuilder() + .followRedirects(redirect) + .connectTimeout(Duration.ofSeconds(20)); + if (cookieHandler != null) { + builder.cookieHandler(cookieHandler); + } + if (version != null) { + builder.version(version); + } + if (executor != null) { + builder.executor(executor); + } + if (proxy != null) { + builder.proxy(proxy); + } + if (sslContext != null) { + builder.sslContext(sslContext); + } + if (sslParameters != null) { + builder.sslParameters(sslParameters); + } + if (authenticator != null) { + builder.authenticator(authenticator); + } + if (priority > 0) { + builder.priority(priority); + } + return builder.build(); + } + + /** + * Create a reasonable default BodyAdapter if avaje-jsonb or Jackson are present. + */ + private BodyAdapter defaultBodyAdapter() { + try { + return detectJsonb() ? new JsonbBodyAdapter() + : detectJackson() ? new JacksonBodyAdapter() + : null; + } catch (IllegalAccessError e) { + // not in module path + return null; + } + } + + private boolean detectJsonb() { + return detectTypeExists("io.avaje.jsonb.Jsonb"); + } + + private boolean detectJackson() { + return detectTypeExists("com.fasterxml.jackson.databind.ObjectMapper"); + } + + private boolean detectTypeExists(String className) { + try { + Class.forName(className); + return true; + } catch (ClassNotFoundException e) { + return false; + } + } + + DHttpClientContext buildClient() { + requireNonNull(baseUrl, "baseUrl is not specified"); + requireNonNull(requestTimeout, "requestTimeout is not specified"); + if (client == null) { + client = defaultClient(); + } + if (requestLogging) { + // register the builtin request/response logging + this.listeners.add(new RequestLogger()); + } + if (bodyAdapter == null) { + bodyAdapter = defaultBodyAdapter(); + } + return new DHttpClientContext(client, baseUrl, requestTimeout, bodyAdapter, retryHandler, buildListener(), authTokenProvider, buildIntercept()); + } + +} diff --git a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientBuilder.java b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientBuilder.java new file mode 100644 index 000000000..18b3d1f36 --- /dev/null +++ b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientBuilder.java @@ -0,0 +1,172 @@ +package io.avaje.http.client; + +import io.avaje.inject.BeanScope; + +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLParameters; +import java.net.Authenticator; +import java.net.CookieHandler; +import java.net.ProxySelector; +import java.time.Duration; +import java.util.concurrent.Executor; + +final class DHttpClientBuilder extends DBaseBuilder implements HttpClient.Builder, HttpClient.Builder.State { + + DHttpClientBuilder() { + } + + @Override + public HttpClient.Builder client(java.net.http.HttpClient client) { + this.client = client; + return this; + } + + @Override + public HttpClient.Builder baseUrl(String baseUrl) { + this.baseUrl = baseUrl; + return this; + } + + @Override + public HttpClient.Builder requestTimeout(Duration requestTimeout) { + this.requestTimeout = requestTimeout; + return this; + } + + @Override + public HttpClient.Builder bodyAdapter(BodyAdapter adapter) { + this.bodyAdapter = adapter; + return this; + } + + @Override + public HttpClient.Builder retryHandler(RetryHandler retryHandler) { + this.retryHandler = retryHandler; + return this; + } + + @Override + public HttpClient.Builder requestLogging(boolean requestLogging) { + this.requestLogging = requestLogging; + return this; + } + + @Override + public HttpClient.Builder requestListener(RequestListener requestListener) { + this.listeners.add(requestListener); + return this; + } + + @Override + public HttpClient.Builder requestIntercept(RequestIntercept requestIntercept) { + this.interceptors.add(requestIntercept); + return this; + } + + @Override + public HttpClient.Builder authTokenProvider(AuthTokenProvider authTokenProvider) { + this.authTokenProvider = authTokenProvider; + return this; + } + + @Override + public HttpClient.Builder cookieHandler(CookieHandler cookieHandler) { + this.cookieHandler = cookieHandler; + return this; + } + + @Override + public HttpClient.Builder redirect(java.net.http.HttpClient.Redirect redirect) { + this.redirect = redirect; + return this; + } + + @Override + public HttpClient.Builder version(java.net.http.HttpClient.Version version) { + this.version = version; + return this; + } + + @Override + public HttpClient.Builder executor(Executor executor) { + this.executor = executor; + return this; + } + + @Override + public HttpClient.Builder proxy(ProxySelector proxySelector) { + this.proxy = proxySelector; + return this; + } + + @Override + public HttpClient.Builder sslContext(SSLContext sslContext) { + this.sslContext = sslContext; + return this; + } + + @Override + public HttpClient.Builder sslParameters(SSLParameters sslParameters) { + this.sslParameters = sslParameters; + return this; + } + + @Override + public HttpClient.Builder authenticator(Authenticator authenticator) { + this.authenticator = authenticator; + return this; + } + + @Override + public HttpClient.Builder priority(int priority) { + this.priority = priority; + return this; + } + + @Override + public HttpClient.Builder.State state() { + return this; + } + + @Override + public HttpClient.Builder configureWith(BeanScope beanScope) { + super.configureFromScope(beanScope); + return this; + } + + @Override + public HttpClient build() { + return buildClient(); + } + + @Override + public String baseUrl() { + return baseUrl; + } + + @Override + public BodyAdapter bodyAdapter() { + return bodyAdapter; + } + + @Override + public java.net.http.HttpClient client() { + return client; + } + + @Override + public boolean requestLogging() { + return requestLogging; + } + + @Override + public Duration requestTimeout() { + return requestTimeout; + } + + @Override + public RetryHandler retryHandler() { + return retryHandler; + } + +} diff --git a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContext.java b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContext.java index d2c1064ed..ea880544d 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContext.java +++ b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContext.java @@ -16,7 +16,7 @@ import java.util.concurrent.atomic.LongAccumulator; import java.util.concurrent.atomic.LongAdder; -final class DHttpClientContext implements HttpClientContext { +final class DHttpClientContext implements HttpClientContext, SpiHttpClient { /** * HTTP Authorization header. diff --git a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContextBuilder.java b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContextBuilder.java index 2e1bb1585..08675e4d5 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContextBuilder.java +++ b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContextBuilder.java @@ -1,46 +1,17 @@ package io.avaje.http.client; -import com.fasterxml.jackson.databind.ObjectMapper; import io.avaje.inject.BeanScope; -import io.avaje.jsonb.Jsonb; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLParameters; import java.net.Authenticator; import java.net.CookieHandler; -import java.net.CookieManager; import java.net.ProxySelector; import java.net.http.HttpClient; import java.time.Duration; -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; import java.util.concurrent.Executor; -import static java.util.Objects.requireNonNull; - -final class DHttpClientContextBuilder implements HttpClientContext.Builder, HttpClientContext.Builder.State { - - private HttpClient client; - private String baseUrl; - private boolean requestLogging = true; - private Duration requestTimeout = Duration.ofSeconds(20); - private BodyAdapter bodyAdapter; - private RetryHandler retryHandler; - private AuthTokenProvider authTokenProvider; - - private CookieHandler cookieHandler = new CookieManager(); - private HttpClient.Redirect redirect = HttpClient.Redirect.NORMAL; - private HttpClient.Version version; - private Executor executor; - private ProxySelector proxy; - private SSLContext sslContext; - private SSLParameters sslParameters; - private Authenticator authenticator; - private int priority; - - private final List interceptors = new ArrayList<>(); - private final List listeners = new ArrayList<>(); +final class DHttpClientContextBuilder extends DBaseBuilder implements HttpClientContext.Builder, HttpClientContext.Builder.State { DHttpClientContextBuilder() { } @@ -160,47 +131,13 @@ public State state() { @Override public HttpClientContext.Builder configureWith(BeanScope beanScope) { - if (bodyAdapter == null) { - configureBodyAdapter(beanScope); - } - if (retryHandler == null) { - configureRetryHandler(beanScope); - } + super.configureFromScope(beanScope); return this; } - private void configureRetryHandler(BeanScope beanScope) { - beanScope.getOptional(RetryHandler.class) - .ifPresent(this::retryHandler); - } - - private void configureBodyAdapter(BeanScope beanScope) { - Optional body = beanScope.getOptional(BodyAdapter.class); - if (body.isPresent()) { - bodyAdapter = body.get(); - } else if (beanScope.contains("io.avaje.jsonb.Jsonb")) { - bodyAdapter = new JsonbBodyAdapter(beanScope.get(Jsonb.class)); - } else if (beanScope.contains("com.fasterxml.jackson.databind.ObjectMapper")) { - ObjectMapper objectMapper = beanScope.get(ObjectMapper.class); - bodyAdapter = new JacksonBodyAdapter(objectMapper); - } - } - @Override public HttpClientContext build() { - requireNonNull(baseUrl, "baseUrl is not specified"); - requireNonNull(requestTimeout, "requestTimeout is not specified"); - if (client == null) { - client = defaultClient(); - } - if (requestLogging) { - // register the builtin request/response logging - requestListener(new RequestLogger()); - } - if (bodyAdapter == null) { - bodyAdapter = defaultBodyAdapter(); - } - return new DHttpClientContext(client, baseUrl, requestTimeout, bodyAdapter, retryHandler, buildListener(), authTokenProvider, buildIntercept()); + return super.buildClient(); } @Override @@ -233,86 +170,4 @@ public RetryHandler retryHandler() { return retryHandler; } - private RequestListener buildListener() { - if (listeners.isEmpty()) { - return null; - } else if (listeners.size() == 1) { - return listeners.get(0); - } else { - return new DRequestListeners(listeners); - } - } - - private RequestIntercept buildIntercept() { - if (interceptors.isEmpty()) { - return null; - } else if (interceptors.size() == 1) { - return interceptors.get(0); - } else { - return new DRequestInterceptors(interceptors); - } - } - - private HttpClient defaultClient() { - final HttpClient.Builder builder = HttpClient.newBuilder() - .followRedirects(redirect) - .connectTimeout(Duration.ofSeconds(20)); - if (cookieHandler != null) { - builder.cookieHandler(cookieHandler); - } - if (version != null) { - builder.version(version); - } - if (executor != null) { - builder.executor(executor); - } - if (proxy != null) { - builder.proxy(proxy); - } - if (sslContext != null) { - builder.sslContext(sslContext); - } - if (sslParameters != null) { - builder.sslParameters(sslParameters); - } - if (authenticator != null) { - builder.authenticator(authenticator); - } - if (priority > 0) { - builder.priority(priority); - } - return builder.build(); - } - - /** - * Create a reasonable default BodyAdapter if avaje-jsonb or Jackson are present. - */ - BodyAdapter defaultBodyAdapter() { - try { - return detectJsonb() ? new JsonbBodyAdapter() - : detectJackson() ? new JacksonBodyAdapter() - : null; - } catch (IllegalAccessError e) { - // not in module path - return null; - } - } - - boolean detectJsonb() { - return detectTypeExists("io.avaje.jsonb.Jsonb"); - } - - boolean detectJackson() { - return detectTypeExists("com.fasterxml.jackson.databind.ObjectMapper"); - } - - private boolean detectTypeExists(String className) { - try { - Class.forName(className); - return true; - } catch (ClassNotFoundException e) { - return false; - } - } - } diff --git a/http-client/client/src/main/java/io/avaje/http/client/HttpClient.java b/http-client/client/src/main/java/io/avaje/http/client/HttpClient.java index 643a43cb7..99c5f9af1 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/HttpClient.java +++ b/http-client/client/src/main/java/io/avaje/http/client/HttpClient.java @@ -1,6 +1,14 @@ package io.avaje.http.client; +import io.avaje.inject.BeanScope; + +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLParameters; +import java.net.Authenticator; +import java.net.CookieHandler; +import java.net.ProxySelector; import java.time.Duration; +import java.util.concurrent.Executor; /** * The HTTP client context that we use to build and process requests. @@ -23,8 +31,266 @@ */ public interface HttpClient { + /** + * Return the builder to config and build the client context. + * + *
{@code
+   *
+   *   HttpClient client = HttpClient.builder()
+   *       .baseUrl("http://localhost:8080")
+   *       .bodyAdapter(new JacksonBodyAdapter())
+   *       .build();
+   *
+   *  HttpResponse res = client.request()
+   *       .path("hello")
+   *       .GET().asString();
+   *
+   * }
+ */ + static Builder builder() { + return new DHttpClientBuilder(); + } + + /** + * Return the http client API implementation. + * + * @param clientInterface A @Client interface with annotated API methods. + * @param The service type. + * @return The http client API implementation. + */ + T create(Class clientInterface); + + /** + * Create a new request. + */ + HttpClientRequest request(); + + /** + * Return the body adapter used by the client context. + *

+ * This is the body adapter used to convert request and response + * bodies to java types. For example using Jackson with JSON payloads. + */ + BodyAdapter converters(); + + /** + * Return the current aggregate metrics. + *

+ * These metrics are collected for all requests sent via this context. + */ + HttpClientContext.Metrics metrics(); + + /** + * Return the current metrics with the option of resetting the underlying counters. + *

+ * These metrics are collected for all requests sent via this context. + */ + HttpClientContext.Metrics metrics(boolean reset); + + /** + * Builds the HttpClient. + * + *

{@code
+   *
+   *   HttpClient client = HttpClient.builder()
+   *       .baseUrl("http://localhost:8080")
+   *       .bodyAdapter(new JacksonBodyAdapter())
+   *       .build();
+   *
+   *  HelloDto dto = client.request()
+   *       .path("hello")
+   *       .queryParam("name", "Rob")
+   *       .queryParam("say", "Whats up")
+   *       .GET()
+   *       .bean(HelloDto.class);
+   *
+   * }
+ */ interface Builder { + /** + * Set the base URL to use for requests created from the context. + *

+ * Note that the base url can be replaced via {@link HttpClientRequest#url(String)}. + */ + Builder baseUrl(String baseUrl); + + /** + * Set the default request timeout. + * + * @see java.net.http.HttpRequest.Builder#timeout(Duration) + */ + Builder requestTimeout(Duration requestTimeout); + + /** + * Set the body adapter to use to convert beans to body content + * and response content back to beans. + */ + Builder bodyAdapter(BodyAdapter adapter); + + /** + * Set a RetryHandler to use to retry requests. + */ + Builder retryHandler(RetryHandler retryHandler); + + /** + * Disable or enable built in request and response logging. + *

+ * By default request logging is enabled. Set this to false to stop + * the default {@link RequestLogger} being registered to log request + * and response headers and bodies etc. + *

+ * With logging level set to {@code DEBUG} for + * {@code io.avaje.http.client.RequestLogger} the request and response + * are logged as a summary with response status and time. + *

+ * Set the logging level to {@code TRACE} to include the request + * and response headers and body payloads with truncation for large + * bodies. + * + *

Suppression

+ *

+ * We can also use {@link HttpClientRequest#suppressLogging()} to suppress + * logging on specific requests. + *

+ * Logging of Authorization headers is suppressed. + * {@link AuthTokenProvider} requests are suppressed. + * + * @param requestLogging Disable/enable the registration of the default logger + * @see RequestLogger + */ + Builder requestLogging(boolean requestLogging); + + /** + * Add a request listener. Multiple listeners may be added, when + * do so they will process events in the order they were added. + *

+ * Note that {@link RequestLogger} is an implementation for debug + * logging request/response headers and content which is registered + * by default depending on {@link #requestLogging(boolean)}. + * + * @see RequestLogger + */ + Builder requestListener(RequestListener requestListener); + + /** + * Add a request interceptor. Multiple interceptors may be added. + */ + Builder requestIntercept(RequestIntercept requestIntercept); + + /** + * Add a Authorization token provider. + *

+ * When set all requests are expected to use a Authorization Bearer token + * unless they are marked via {@link HttpClientRequest#skipAuthToken()}. + *

+ * The AuthTokenProvider obtains a new token typically with an expiry. This + * is automatically called as needed and the Authorization Bearer header set + * on all requests (not marked with skipAuthToken()). + */ + Builder authTokenProvider(AuthTokenProvider authTokenProvider); + + /** + * Set the underlying HttpClient to use. + *

+ * Used when we wish to control all options of the HttpClient. + */ + Builder client(java.net.http.HttpClient client); + + /** + * Specify a cookie handler to use on the HttpClient. This would override the default cookie handler. + * + * @see java.net.http.HttpClient.Builder#cookieHandler(CookieHandler) + */ + Builder cookieHandler(CookieHandler cookieHandler); + + /** + * Specify the redirect policy. Defaults to HttpClient.Redirect.NORMAL. + * + * @see java.net.http.HttpClient.Builder#followRedirects(java.net.http.HttpClient.Redirect) + */ + Builder redirect(java.net.http.HttpClient.Redirect redirect); + + /** + * Specify the HTTP version. Defaults to not set. + * + * @see java.net.http.HttpClient.Builder#version(java.net.http.HttpClient.Version) + */ + Builder version(java.net.http.HttpClient.Version version); + + /** + * Specify the Executor to use for asynchronous tasks. + * If not specified a default executor will be used. + * + * @see java.net.http.HttpClient.Builder#executor(Executor) + */ + Builder executor(Executor executor); + + /** + * Set the proxy to the underlying {@link java.net.http.HttpClient}. + * + * @see java.net.http.HttpClient.Builder#proxy(ProxySelector) + */ + Builder proxy(ProxySelector proxySelector); + + /** + * Set the sslContext to the underlying {@link java.net.http.HttpClient}. + * + * @see java.net.http.HttpClient.Builder#sslContext(SSLContext) + */ + Builder sslContext(SSLContext sslContext); + + /** + * Set the sslParameters to the underlying {@link java.net.http.HttpClient}. + * + * @see java.net.http.HttpClient.Builder#sslParameters(SSLParameters) + */ + Builder sslParameters(SSLParameters sslParameters); + + /** + * Set a HttpClient authenticator to the underlying {@link java.net.http.HttpClient}. + * + * @see java.net.http.HttpClient.Builder#authenticator(Authenticator) + */ + Builder authenticator(Authenticator authenticator); + + /** + * Set the priority for HTTP/2 requests to the underlying {@link java.net.http.HttpClient}. + * + * @see java.net.http.HttpClient.Builder#priority(int) + */ + Builder priority(int priority); + + /** + * Configure BodyAdapter and RetryHandler using dependency injection BeanScope. + */ + Builder configureWith(BeanScope beanScope); + + /** + * Return the state of the builder. + */ + Builder.State state(); + + /** + * Build and return the context. + * + *

{@code
+     *
+     *   HttpClient client = HttpClient.builder()
+     *       .baseUrl("http://localhost:8080")
+     *       .bodyAdapter(new JacksonBodyAdapter())
+     *       .build();
+     *
+     *  HelloDto dto = client.request()
+     *       .path("hello")
+     *       .queryParam("say", "Whats up")
+     *       .GET()
+     *       .bean(HelloDto.class);
+     *
+     * }
+ */ + HttpClient build(); + /** * The state of the builder with methods to read the set state. */ diff --git a/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java b/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java index 33ab6f7d9..5b45a0d7b 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java +++ b/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java @@ -8,7 +8,6 @@ import java.net.CookieHandler; import java.net.ProxySelector; import java.net.http.HttpClient; -import java.net.http.HttpResponse; import java.time.Duration; import java.util.concurrent.Executor; @@ -31,7 +30,7 @@ * * }
*/ -public interface HttpClientContext { +public interface HttpClientContext extends io.avaje.http.client.HttpClient { /** * Return the builder to config and build the client context. @@ -61,84 +60,6 @@ static HttpClientContext.Builder newBuilder() { return builder(); } - /** - * Return the http client API implementation. - * - * @param clientInterface A @Client interface with annotated API methods. - * @param The service type. - * @return The http client API implementation. - */ - T create(Class clientInterface); - - /** - * Create a new request. - */ - HttpClientRequest request(); - - /** - * Return a UrlBuilder to use to build an URL taking into - * account the base URL. - */ - UrlBuilder url(); - - /** - * Return the body adapter used by the client context. - *

- * This is the body adapter used to convert request and response - * bodies to java types. For example using Jackson with JSON payloads. - */ - BodyAdapter converters(); - - /** - * Return the underlying http client. - */ - HttpClient httpClient(); - - /** - * Return the current aggregate metrics. - *

- * These metrics are collected for all requests sent via this context. - */ - Metrics metrics(); - - /** - * Return the current metrics with the option of resetting the underlying counters. - *

- * These metrics are collected for all requests sent via this context. - */ - Metrics metrics(boolean reset); - - /** - * Check the response status code and throw HttpException if the status - * code is in the error range. - */ - void checkResponse(HttpResponse response); - - /** - * Return the response content taking into account content encoding. - * - * @param httpResponse The HTTP response to decode the content from - * @return The decoded content - */ - BodyContent readContent(HttpResponse httpResponse); - - /** - * Decode the response content given the Content-Encoding http header. - * - * @param httpResponse The HTTP response - * @return The decoded content - */ - byte[] decodeContent(HttpResponse httpResponse); - - /** - * Decode the body using the given encoding. - * - * @param encoding The encoding used to decode the content - * @param content The raw content being decoded - * @return The decoded content - */ - byte[] decodeContent(String encoding, byte[] content); - /** * Builds the HttpClientContext. * diff --git a/http-client/client/src/main/java/io/avaje/http/client/SpiHttpClient.java b/http-client/client/src/main/java/io/avaje/http/client/SpiHttpClient.java new file mode 100644 index 000000000..b7a1c1fb1 --- /dev/null +++ b/http-client/client/src/main/java/io/avaje/http/client/SpiHttpClient.java @@ -0,0 +1,53 @@ +package io.avaje.http.client; + +import java.net.http.HttpClient; +import java.net.http.HttpResponse; + +/** + * Internal Http Client interface. + */ +interface SpiHttpClient { + + /** + * Return a UrlBuilder to use to build an URL taking into + * account the base URL. + */ + UrlBuilder url(); + + /** + * Return the underlying http client. + */ + HttpClient httpClient(); + + /** + * Return the response content taking into account content encoding. + * + * @param httpResponse The HTTP response to decode the content from + * @return The decoded content + */ + BodyContent readContent(HttpResponse httpResponse); + + /** + * Decode the response content given the Content-Encoding http header. + * + * @param httpResponse The HTTP response + * @return The decoded content + */ + byte[] decodeContent(HttpResponse httpResponse); + + /** + * Decode the body using the given encoding. + * + * @param encoding The encoding used to decode the content + * @param content The raw content being decoded + * @return The decoded content + */ + byte[] decodeContent(String encoding, byte[] content); + + /** + * Check the response status code and throw HttpException if the status + * code is in the error range. + */ + void checkResponse(HttpResponse response); + +} diff --git a/http-client/client/src/test/java/io/avaje/http/client/DHttpClientContextTest.java b/http-client/client/src/test/java/io/avaje/http/client/DHttpClientContextTest.java index 405af5bd5..0811224af 100644 --- a/http-client/client/src/test/java/io/avaje/http/client/DHttpClientContextTest.java +++ b/http-client/client/src/test/java/io/avaje/http/client/DHttpClientContextTest.java @@ -45,15 +45,16 @@ void build_basic() { .baseUrl("http://localhost") .build(); + SpiHttpClient spi = (SpiHttpClient)context; // has default client created - assertThat(context.httpClient()).isNotNull(); - assertThat(context.httpClient().version()).isEqualTo(HttpClient.Version.HTTP_2); - assertThat(context.httpClient().cookieHandler()).isPresent(); + assertThat(spi.httpClient()).isNotNull(); + assertThat(spi.httpClient().version()).isEqualTo(HttpClient.Version.HTTP_2); + assertThat(spi.httpClient().cookieHandler()).isPresent(); // has expected url building - assertThat(context.url().build()).isEqualTo("http://localhost"); - assertThat(context.url().path("hello").build()).isEqualTo("http://localhost/hello"); - assertThat(context.url().queryParam("hello","there").build()).isEqualTo("http://localhost?hello=there"); + assertThat(spi.url().build()).isEqualTo("http://localhost"); + assertThat(spi.url().path("hello").build()).isEqualTo("http://localhost/hello"); + assertThat(spi.url().queryParam("hello","there").build()).isEqualTo("http://localhost?hello=there"); } @Test @@ -66,15 +67,16 @@ void build_noCookieHandler() { .redirect(HttpClient.Redirect.ALWAYS) .build(); + SpiHttpClient spi = (SpiHttpClient)context; // has default client created - assertThat(context.httpClient()).isNotNull(); - assertThat(context.httpClient().version()).isEqualTo(HttpClient.Version.HTTP_2); - assertThat(context.httpClient().cookieHandler()).isEmpty(); + assertThat(spi.httpClient()).isNotNull(); + assertThat(spi.httpClient().version()).isEqualTo(HttpClient.Version.HTTP_2); + assertThat(spi.httpClient().cookieHandler()).isEmpty(); // has expected url building - assertThat(context.url().build()).isEqualTo("http://localhost"); - assertThat(context.url().path("hello").build()).isEqualTo("http://localhost/hello"); - assertThat(context.url().queryParam("hello","there").build()).isEqualTo("http://localhost?hello=there"); + assertThat(spi.url().build()).isEqualTo("http://localhost"); + assertThat(spi.url().path("hello").build()).isEqualTo("http://localhost/hello"); + assertThat(spi.url().queryParam("hello","there").build()).isEqualTo("http://localhost?hello=there"); } @Test diff --git a/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java b/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java index 6b308add2..b77ca72ba 100644 --- a/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java +++ b/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java @@ -1,11 +1,12 @@ package io.avaje.http.client; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; import org.example.webserver.ErrorResponse; import org.example.webserver.HelloDto; import org.junit.jupiter.api.Test; import java.io.*; -import java.net.http.HttpClient; import java.net.http.HttpResponse; import java.nio.charset.StandardCharsets; import java.nio.file.Path; @@ -22,13 +23,45 @@ import java.util.stream.Collectors; import java.util.stream.Stream; +import static java.net.http.HttpClient.Version.*; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.*; class HelloControllerTest extends BaseWebTest { + private static final ObjectMapper objectMapper = new ObjectMapper(); + final HttpClientContext clientContext = client(); + @Test + void newClientTest() { + HttpClient client = HttpClient.builder() + .baseUrl("http://localhost:8887") + .bodyAdapter(new JacksonBodyAdapter()) + .build(); + + client.metrics(true); + Map params = new LinkedHashMap<>(); + params.put("A", "a"); + params.put("B", "b"); + + final HttpResponse hres = client.request() + .path("hello").path("message") + .queryParam(params) + .GET().asString(); + + assertThat(hres.statusCode()).isEqualTo(200); + assertThat(hres.uri().toString()).isEqualTo("http://localhost:8887/hello/message?A=a&B=b"); + + HttpClient.Metrics metrics = client.metrics(); + assertThat(metrics.totalCount()).isEqualTo(1); + assertThat(metrics.errorCount()).isEqualTo(0); + assertThat(metrics.responseBytes()).isGreaterThan(0); + assertThat(metrics.totalMicros()).isGreaterThan(0); + assertThat(metrics.maxMicros()).isEqualTo(metrics.totalMicros()); + assertThat(metrics.avgMicros()).isEqualTo(metrics.totalMicros()); + } + @Test void queryParamMap() { clientContext.metrics(true); @@ -945,7 +978,7 @@ void postForm_asVoid_validResponse() { assertThat(res.request()).isNotNull(); assertThat(res.previousResponse()).isEmpty(); assertThat(res.sslSession()).isEmpty(); - assertThat(res.version()).isEqualTo(HttpClient.Version.HTTP_1_1); + assertThat(res.version()).isEqualTo(HTTP_1_1); assertThat(res.uri().toString()).isEqualTo("http://localhost:8887/hello/saveform"); } diff --git a/http-client/client/src/test/java/org/example/github/httpclient/Simple$HttpClient.java b/http-client/client/src/test/java/org/example/github/httpclient/Simple$HttpClient.java index 797d0cb3c..73a16d0d1 100644 --- a/http-client/client/src/test/java/org/example/github/httpclient/Simple$HttpClient.java +++ b/http-client/client/src/test/java/org/example/github/httpclient/Simple$HttpClient.java @@ -58,7 +58,7 @@ public InputStream getById2(String id, InputStream is) { .body(() -> is) .GET().handler(HttpResponse.BodyHandlers.ofInputStream()); - context.checkResponse(response); + //context.checkResponse(response); return response.body(); } From 7a16f668318395486243af1b46110e19387c4131 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 17 Jan 2023 00:15:03 +1300 Subject: [PATCH 0496/1323] Flip HttpClient.Metrics to extend HttpClientContext.Metrics instead of the other way around --- .../avaje/http/client/DHttpClientContext.java | 13 ++++--- .../java/io/avaje/http/client/HttpClient.java | 35 ++----------------- .../avaje/http/client/HttpClientContext.java | 30 +++++++++++++++- .../http/client/HelloControllerTest.java | 3 +- 4 files changed, 39 insertions(+), 42 deletions(-) diff --git a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContext.java b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContext.java index ea880544d..56eabbd71 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContext.java +++ b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContext.java @@ -3,7 +3,6 @@ import java.io.IOException; import java.lang.reflect.Constructor; import java.lang.reflect.ParameterizedType; -import java.net.http.HttpClient; import java.net.http.HttpHeaders; import java.net.http.HttpRequest; import java.net.http.HttpResponse; @@ -24,7 +23,7 @@ final class DHttpClientContext implements HttpClientContext, SpiHttpClient { static final String AUTHORIZATION = "Authorization"; private static final String BEARER = "Bearer "; - private final HttpClient httpClient; + private final java.net.http.HttpClient httpClient; private final String baseUrl; private final Duration requestTimeout; private final BodyAdapter bodyAdapter; @@ -41,7 +40,7 @@ final class DHttpClientContext implements HttpClientContext, SpiHttpClient { private final LongAdder metricResMicros = new LongAdder(); private final LongAccumulator metricResMaxMicros = new LongAccumulator(Math::max, 0); - DHttpClientContext(HttpClient httpClient, String baseUrl, Duration requestTimeout, BodyAdapter bodyAdapter, RetryHandler retryHandler, RequestListener requestListener, AuthTokenProvider authTokenProvider, RequestIntercept intercept) { + DHttpClientContext(java.net.http.HttpClient httpClient, String baseUrl, Duration requestTimeout, BodyAdapter bodyAdapter, RetryHandler retryHandler, RequestListener requestListener, AuthTokenProvider authTokenProvider, RequestIntercept intercept) { this.httpClient = httpClient; this.baseUrl = baseUrl; this.requestTimeout = requestTimeout; @@ -106,17 +105,17 @@ public UrlBuilder url() { } @Override - public HttpClient httpClient() { + public java.net.http.HttpClient httpClient() { return httpClient; } @Override - public Metrics metrics() { + public HttpClient.Metrics metrics() { return metrics(false); } @Override - public Metrics metrics(boolean reset) { + public HttpClient.Metrics metrics(boolean reset) { if (reset) { return new DMetrics(metricResTotal.sumThenReset(), metricResError.sumThenReset(), metricResBytes.sumThenReset(), metricResMicros.sumThenReset(), metricResMaxMicros.getThenReset()); } else { @@ -128,7 +127,7 @@ void metricsString(int stringBody) { metricResBytes.add(stringBody); } - static final class DMetrics implements Metrics { + static final class DMetrics implements HttpClient.Metrics { private final long totalCount; private final long errorCount; diff --git a/http-client/client/src/main/java/io/avaje/http/client/HttpClient.java b/http-client/client/src/main/java/io/avaje/http/client/HttpClient.java index 99c5f9af1..cb4298e68 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/HttpClient.java +++ b/http-client/client/src/main/java/io/avaje/http/client/HttpClient.java @@ -78,14 +78,14 @@ static Builder builder() { *

* These metrics are collected for all requests sent via this context. */ - HttpClientContext.Metrics metrics(); + HttpClient.Metrics metrics(); /** * Return the current metrics with the option of resetting the underlying counters. *

* These metrics are collected for all requests sent via this context. */ - HttpClientContext.Metrics metrics(boolean reset); + HttpClient.Metrics metrics(boolean reset); /** * Builds the HttpClient. @@ -331,36 +331,7 @@ interface State { /** * Statistic metrics collected to provide an overview of activity of this client. */ - interface Metrics { + interface Metrics extends HttpClientContext.Metrics { - /** - * Return the total number of responses. - */ - long totalCount(); - - /** - * Return the total number of error responses (status code >= 300). - */ - long errorCount(); - - /** - * Return the total response bytes (excludes streaming responses). - */ - long responseBytes(); - - /** - * Return the total response time in microseconds. - */ - long totalMicros(); - - /** - * Return the max response time in microseconds (since the last reset). - */ - long maxMicros(); - - /** - * Return the average response time in microseconds. - */ - long avgMicros(); } } diff --git a/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java b/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java index 5b45a0d7b..c62894807 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java +++ b/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java @@ -275,7 +275,35 @@ interface State extends io.avaje.http.client.HttpClient.Builder.State { /** * Statistic metrics collected to provide an overview of activity of this client. */ - interface Metrics extends io.avaje.http.client.HttpClient.Metrics { + interface Metrics { + /** + * Return the total number of responses. + */ + long totalCount(); + + /** + * Return the total number of error responses (status code >= 300). + */ + long errorCount(); + + /** + * Return the total response bytes (excludes streaming responses). + */ + long responseBytes(); + /** + * Return the total response time in microseconds. + */ + long totalMicros(); + + /** + * Return the max response time in microseconds (since the last reset). + */ + long maxMicros(); + + /** + * Return the average response time in microseconds. + */ + long avgMicros(); } } diff --git a/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java b/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java index b77ca72ba..c81792bfc 100644 --- a/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java +++ b/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java @@ -1,6 +1,5 @@ package io.avaje.http.client; -import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import org.example.webserver.ErrorResponse; import org.example.webserver.HelloDto; @@ -23,7 +22,7 @@ import java.util.stream.Collectors; import java.util.stream.Stream; -import static java.net.http.HttpClient.Version.*; +import static java.net.http.HttpClient.Version.HTTP_1_1; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.*; From c6584fc34a5a17c462bd62fafbe6793b66324719 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 17 Jan 2023 00:18:35 +1300 Subject: [PATCH 0497/1323] Refactor rename HttpClient.converters() to HttpClient.bodyAdapter() with deprecation --- .../io/avaje/http/client/DHttpClientContext.java | 2 +- .../main/java/io/avaje/http/client/HttpClient.java | 12 +++++++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContext.java b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContext.java index 56eabbd71..cd44ab73b 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContext.java +++ b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContext.java @@ -95,7 +95,7 @@ public HttpClientRequest request() { } @Override - public BodyAdapter converters() { + public BodyAdapter bodyAdapter() { return bodyAdapter; } diff --git a/http-client/client/src/main/java/io/avaje/http/client/HttpClient.java b/http-client/client/src/main/java/io/avaje/http/client/HttpClient.java index cb4298e68..d351c7674 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/HttpClient.java +++ b/http-client/client/src/main/java/io/avaje/http/client/HttpClient.java @@ -66,12 +66,22 @@ static Builder builder() { HttpClientRequest request(); /** + * Deprecated - migrate to {@link #bodyAdapter()}. + *

* Return the body adapter used by the client context. *

* This is the body adapter used to convert request and response * bodies to java types. For example using Jackson with JSON payloads. */ - BodyAdapter converters(); + @Deprecated + default BodyAdapter converters() { + return bodyAdapter(); + } + + /** + * Return the BodyAdapter that this client is using. + */ + BodyAdapter bodyAdapter(); /** * Return the current aggregate metrics. From 5232599fce199b98bdeb154e4e85a62d81583847 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 17 Jan 2023 00:21:50 +1300 Subject: [PATCH 0498/1323] Mark HttpClientContext.builder() as deprecated, migrate to HttpClient.builder() --- .../src/main/java/io/avaje/http/client/HttpClientContext.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java b/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java index c62894807..23d750654 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java +++ b/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java @@ -33,6 +33,8 @@ public interface HttpClientContext extends io.avaje.http.client.HttpClient { /** + * Deprecated - migrate to {@link io.avaje.http.client.HttpClient#builder()}. + *

* Return the builder to config and build the client context. * *

{@code
@@ -48,6 +50,7 @@ public interface HttpClientContext extends io.avaje.http.client.HttpClient {
    *
    * }
*/ + @Deprecated static HttpClientContext.Builder builder() { return new DHttpClientContextBuilder(); } From fa8df2cfa5897613c57015f9c2138b80e0ffb59b Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 17 Jan 2023 00:31:41 +1300 Subject: [PATCH 0499/1323] Additionally add deprecation to HttpClientContext --- .../src/main/java/io/avaje/http/client/HttpClientContext.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java b/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java index 23d750654..0e2289b57 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java +++ b/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java @@ -12,6 +12,9 @@ import java.util.concurrent.Executor; /** + * Deprecated in favor of {@link io.avaje.http.client.HttpClient}. + * Migrate to using {@link io.avaje.http.client.HttpClient#builder()}. + *

* The HTTP client context that we use to build and process requests. * *

{@code
@@ -30,6 +33,7 @@
  *
  * }
*/ +@Deprecated public interface HttpClientContext extends io.avaje.http.client.HttpClient { /** From 2b92473c69be0c3cc473e75a5468b3f3d22a9c22 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Mon, 16 Jan 2023 11:42:59 -0500 Subject: [PATCH 0500/1323] can validate request body --- .../avaje/http/generator/core/ControllerReader.java | 12 +++++++++++- .../io/avaje/http/generator/core/ElementReader.java | 5 ++++- .../io/avaje/http/generator/core/MethodReader.java | 13 ++++++++++++- 3 files changed, 27 insertions(+), 3 deletions(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java index 363e27a13..8b00eaea5 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java @@ -141,7 +141,17 @@ private boolean initDocHidden() { } private boolean initHasValid() { - return findAnnotation(Valid.class) != null; + Annotation jakarta = null; + try { + var anno = + (Class) + Class.forName(Valid.class.getCanonicalName().replace("javax", "jakarta")); + jakarta = findAnnotation(anno); + } catch (final ClassNotFoundException e) { + + } + + return findAnnotation(Valid.class) != null || jakarta != null; } String produces() { diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java index c9e68a774..9a583dd82 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java @@ -63,7 +63,10 @@ private boolean useValidation() { return false; } TypeElement elementType = ctx.typeElement(rawType); - return elementType != null && elementType.getAnnotation(Valid.class) != null; + var elementRawType = element.asType().toString(); + return elementType != null + && (elementType.getAnnotation(Valid.class) != null + || (elementRawType.contains("@") && elementRawType.contains("validation"))); } private void readAnnotations(Element element, ParamType defaultType) { diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java index c00e52f9f..2d549432a 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java @@ -78,7 +78,18 @@ public class MethodReader { this.apiResponses = getApiResponses(); initWebMethodViaAnnotation(); if (isWebMethod()) { - this.hasValid = findAnnotation(Valid.class) != null; + + Annotation jakarta = null; + try { + final var anno = + (Class) + Class.forName(Valid.class.getCanonicalName().replace("javax", "jakarta")); + jakarta = findAnnotation(anno); + } catch (final ClassNotFoundException e) { + + } + + this.hasValid = findAnnotation(Valid.class) != null || jakarta != null; this.pathSegments = PathSegments.parse(Util.combinePath(bean.path(), webMethodPath)); } else { this.hasValid = false; From 2e107ea40e03c466b458973704342efde16f8813 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 17 Jan 2023 07:41:30 +1300 Subject: [PATCH 0501/1323] #59 - Add support for setting connection timeout on the Builder --- .../src/main/java/io/avaje/http/client/DBaseBuilder.java | 5 +++-- .../main/java/io/avaje/http/client/DHttpClientBuilder.java | 6 ++++++ .../io/avaje/http/client/DHttpClientContextBuilder.java | 6 ++++++ .../src/main/java/io/avaje/http/client/HttpClient.java | 7 +++++++ .../main/java/io/avaje/http/client/HttpClientContext.java | 7 +++++++ .../src/test/java/io/avaje/http/client/BaseWebTest.java | 4 ++++ .../java/io/avaje/http/client/HelloControllerTest.java | 1 + 7 files changed, 34 insertions(+), 2 deletions(-) diff --git a/http-client/client/src/main/java/io/avaje/http/client/DBaseBuilder.java b/http-client/client/src/main/java/io/avaje/http/client/DBaseBuilder.java index 789316bf9..57cb5a725 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/DBaseBuilder.java +++ b/http-client/client/src/main/java/io/avaje/http/client/DBaseBuilder.java @@ -23,6 +23,7 @@ abstract class DBaseBuilder { java.net.http.HttpClient client; String baseUrl; boolean requestLogging = true; + Duration connectionTimeout = Duration.ofSeconds(20); Duration requestTimeout = Duration.ofSeconds(20); BodyAdapter bodyAdapter; RetryHandler retryHandler; @@ -92,9 +93,9 @@ private RequestIntercept buildIntercept() { } private java.net.http.HttpClient defaultClient() { - final java.net.http.HttpClient.Builder builder = java.net.http.HttpClient.newBuilder() + final var builder = java.net.http.HttpClient.newBuilder() .followRedirects(redirect) - .connectTimeout(Duration.ofSeconds(20)); + .connectTimeout(connectionTimeout); if (cookieHandler != null) { builder.cookieHandler(cookieHandler); } diff --git a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientBuilder.java b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientBuilder.java index 18b3d1f36..1641c23f1 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientBuilder.java +++ b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientBuilder.java @@ -27,6 +27,12 @@ public HttpClient.Builder baseUrl(String baseUrl) { return this; } + @Override + public HttpClient.Builder connectionTimeout(Duration connectionTimeout) { + this.connectionTimeout = connectionTimeout; + return this; + } + @Override public HttpClient.Builder requestTimeout(Duration requestTimeout) { this.requestTimeout = requestTimeout; diff --git a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContextBuilder.java b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContextBuilder.java index 08675e4d5..98ba0a801 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContextBuilder.java +++ b/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContextBuilder.java @@ -28,6 +28,12 @@ public HttpClientContext.Builder baseUrl(String baseUrl) { return this; } + @Override + public HttpClientContext.Builder connectionTimeout(Duration connectionTimeout) { + this.connectionTimeout = connectionTimeout; + return this; + } + @Override public HttpClientContext.Builder requestTimeout(Duration requestTimeout) { this.requestTimeout = requestTimeout; diff --git a/http-client/client/src/main/java/io/avaje/http/client/HttpClient.java b/http-client/client/src/main/java/io/avaje/http/client/HttpClient.java index d351c7674..ca9501244 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/HttpClient.java +++ b/http-client/client/src/main/java/io/avaje/http/client/HttpClient.java @@ -125,6 +125,13 @@ interface Builder { */ Builder baseUrl(String baseUrl); + /** + * Set the connection timeout to use. + * + * @see java.net.http.HttpClient.Builder#connectTimeout(Duration) + */ + Builder connectionTimeout(Duration connectionTimeout); + /** * Set the default request timeout. * diff --git a/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java b/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java index 0e2289b57..12ce33d3d 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java +++ b/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java @@ -102,6 +102,13 @@ interface Builder { */ Builder baseUrl(String baseUrl); + /** + * Set the connection timeout to use. + * + * @see java.net.http.HttpClient.Builder#connectTimeout(Duration) + */ + Builder connectionTimeout(Duration connectionTimeout); + /** * Set the default request timeout. * diff --git a/http-client/client/src/test/java/io/avaje/http/client/BaseWebTest.java b/http-client/client/src/test/java/io/avaje/http/client/BaseWebTest.java index 6003b7087..7b38ff6fc 100644 --- a/http-client/client/src/test/java/io/avaje/http/client/BaseWebTest.java +++ b/http-client/client/src/test/java/io/avaje/http/client/BaseWebTest.java @@ -6,6 +6,8 @@ import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; +import java.time.Duration; + public class BaseWebTest { static Javalin webServer; @@ -26,6 +28,8 @@ public static void shutdown() { public static HttpClientContext client() { return HttpClientContext.builder() .baseUrl(baseUrl) + .connectionTimeout(Duration.ofSeconds(1)) + .requestTimeout(Duration.ofSeconds(1)) .bodyAdapter(new JacksonBodyAdapter(new ObjectMapper())) .build(); } diff --git a/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java b/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java index c81792bfc..c2b1aabcd 100644 --- a/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java +++ b/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java @@ -36,6 +36,7 @@ class HelloControllerTest extends BaseWebTest { void newClientTest() { HttpClient client = HttpClient.builder() .baseUrl("http://localhost:8887") + .connectionTimeout(Duration.ofSeconds(1)) .bodyAdapter(new JacksonBodyAdapter()) .build(); From 5802966b35e2adbfbb34eefc44a9efb403a5220c Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 17 Jan 2023 07:45:47 +1300 Subject: [PATCH 0502/1323] [maven-release-plugin] prepare release avaje-http-client-1.22 --- http-client/client/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/http-client/client/pom.xml b/http-client/client/pom.xml index 70bdae8c2..408247ce4 100644 --- a/http-client/client/pom.xml +++ b/http-client/client/pom.xml @@ -10,11 +10,11 @@ io.avaje avaje-http-client - 1.22-SNAPSHOT + 1.22 scm:git:git@github.com:avaje/avaje-http-client.git - HEAD + avaje-http-client-1.22 From b82b61a1c606d71ed5d08a2fa1d64b458a2b5395 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 17 Jan 2023 07:46:09 +1300 Subject: [PATCH 0503/1323] [maven-release-plugin] prepare for next development iteration --- http-client/client/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/http-client/client/pom.xml b/http-client/client/pom.xml index 408247ce4..6f7c1bf46 100644 --- a/http-client/client/pom.xml +++ b/http-client/client/pom.xml @@ -10,11 +10,11 @@ io.avaje avaje-http-client - 1.22 + 1.23-SNAPSHOT scm:git:git@github.com:avaje/avaje-http-client.git - avaje-http-client-1.22 + HEAD From ba331ca88ae08d3f96a08a36c570f809a8b0894e Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 17 Jan 2023 08:05:33 +1300 Subject: [PATCH 0504/1323] Bump to 1.23-SNAPSHOT after release --- http-client/gson-adapter/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/http-client/gson-adapter/pom.xml b/http-client/gson-adapter/pom.xml index 9bd29fcb1..c48776883 100644 --- a/http-client/gson-adapter/pom.xml +++ b/http-client/gson-adapter/pom.xml @@ -10,7 +10,7 @@ io.avaje avaje-http-client-gson - 1.22-SNAPSHOT + 1.23-SNAPSHOT scm:git:git@github.com:avaje/avaje-http-client.git @@ -28,7 +28,7 @@ io.avaje avaje-http-client - 1.22-SNAPSHOT + 1.23-SNAPSHOT provided From 2f693fab8ff859d5394dbccee0c4fe029d4f92ac Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 17 Jan 2023 08:36:56 +1300 Subject: [PATCH 0505/1323] Bump to 1.23-SNAPSHOT after release --- http-client/test/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/http-client/test/pom.xml b/http-client/test/pom.xml index a6d110a47..4f1691531 100644 --- a/http-client/test/pom.xml +++ b/http-client/test/pom.xml @@ -16,13 +16,13 @@ io.avaje avaje-http-client - 1.22-SNAPSHOT + 1.23-SNAPSHOT io.avaje avaje-http-client-gson - 1.22-SNAPSHOT + 1.23-SNAPSHOT From 0a2829d47c10cc9d6a55ab3ff433e3003234e46a Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 17 Jan 2023 09:21:41 +1300 Subject: [PATCH 0506/1323] Flatten module structure --- .../pom.xml | 5 - .../http/client/gson/GsonBodyAdapter.java | 0 .../java/io/avaje/http/client/gson/Foo.java | 0 .../http/client/gson/GsonBodyAdapterTest.java | 0 http-client/client/pom.xml | 157 ------------------ http-client/pom.xml | 155 +++++++++++++++-- .../java/io/avaje/http/client/AuthToken.java | 0 .../avaje/http/client/AuthTokenProvider.java | 0 .../avaje/http/client/BasicAuthIntercept.java | 0 .../io/avaje/http/client/BodyAdapter.java | 0 .../io/avaje/http/client/BodyContent.java | 0 .../java/io/avaje/http/client/BodyReader.java | 0 .../java/io/avaje/http/client/BodyWriter.java | 0 .../io/avaje/http/client/DBaseBuilder.java | 0 .../java/io/avaje/http/client/DHttpApi.java | 0 .../java/io/avaje/http/client/DHttpAsync.java | 0 .../java/io/avaje/http/client/DHttpCall.java | 0 .../avaje/http/client/DHttpClientBuilder.java | 0 .../avaje/http/client/DHttpClientContext.java | 0 .../client/DHttpClientContextBuilder.java | 0 .../avaje/http/client/DHttpClientRequest.java | 0 .../client/DHttpClientRequestWithRetry.java | 0 .../http/client/DRequestInterceptors.java | 0 .../avaje/http/client/DRequestListeners.java | 0 .../java/io/avaje/http/client/GzipUtil.java | 0 .../io/avaje/http/client/HttpApiProvider.java | 0 .../avaje/http/client/HttpAsyncResponse.java | 0 .../java/io/avaje/http/client/HttpCall.java | 0 .../avaje/http/client/HttpCallResponse.java | 0 .../java/io/avaje/http/client/HttpClient.java | 0 .../avaje/http/client/HttpClientContext.java | 0 .../avaje/http/client/HttpClientRequest.java | 2 +- .../avaje/http/client/HttpClientResponse.java | 0 .../io/avaje/http/client/HttpException.java | 0 .../avaje/http/client/JacksonBodyAdapter.java | 0 .../avaje/http/client/JsonbBodyAdapter.java | 0 .../io/avaje/http/client/PathConversion.java | 0 .../avaje/http/client/RequestIntercept.java | 0 .../io/avaje/http/client/RequestListener.java | 0 .../io/avaje/http/client/RequestLogger.java | 0 .../io/avaje/http/client/RetryHandler.java | 0 .../avaje/http/client/SimpleRetryHandler.java | 0 .../io/avaje/http/client/SpiHttpClient.java | 0 .../java/io/avaje/http/client/UrlBuilder.java | 0 .../io/avaje/http/client/package-info.java | 0 .../src/main/java/module-info.java | 0 .../java/io/avaje/http/client/AsyncTest.java | 0 .../io/avaje/http/client/AuthTokenTest.java | 0 .../io/avaje/http/client/BaseWebTest.java | 4 +- .../http/client/BasicAuthInterceptTest.java | 0 .../io/avaje/http/client/DHttpApiTest.java | 0 .../http/client/DHttpClientContextTest.java | 0 .../http/client/DHttpClientRequestTest.java | 0 .../http/client/DRequestInterceptorsTest.java | 0 .../http/client/DRequestListenersTest.java | 0 .../avaje/http/client/HelloBasicAuthTest.java | 0 .../http/client/HelloControllerTest.java | 10 +- .../avaje/http/client/PathConversionTest.java | 0 .../http/client/RequestListenerTest.java | 4 +- .../avaje/http/client/RequestLoggerTest.java | 0 .../java/io/avaje/http/client/RetryTest.java | 2 +- .../io/avaje/http/client/UrlBuilderTest.java | 0 .../java/io/avaje/http/client/VerbTest.java | 2 +- .../example/dinject/ConfigureWithDITest.java | 0 .../java/org/example/dinject/MyDIConfig.java | 0 .../example/github/BasicClientInterface.java | 0 .../java/org/example/github/GithubTest.java | 0 .../test/java/org/example/github/Repo.java | 0 .../org/example/github/RepoJsonAdapter.java | 0 .../test/java/org/example/github/Simple.java | 0 .../org/example/github/SimpleProvider.java | 0 .../BasicClientInterface$HttpClient.java | 0 .../github/httpclient/Simple$HttpClient.java | 0 .../test/java/org/example/webserver/App.java | 0 .../org/example/webserver/ErrorResponse.java | 0 .../webserver/HelloController$Route.java | 0 .../example/webserver/HelloController.java | 0 .../java/org/example/webserver/HelloDto.java | 0 .../java/org/example/webserver/HelloForm.java | 0 .../io.avaje.http.client.HttpApiProvider | 0 .../{client => }/src/test/resources/dummy.txt | 0 .../src/test/resources/logback-test.xml | 0 pom.xml | 2 + tests/pom.xml | 3 +- .../test-client-direct-use}/pom.xml | 14 +- .../src/main/java/example/github/Repo.java | 0 .../src/main/java/example/github/Simple.java | 0 .../java/example/github/SimpleHttpClient.java | 0 .../src/main/java/module-info.java | 0 .../io.avaje.http.client.HttpApiProvider | 0 .../test/java/example/github/GithubTest.java | 0 .../src/test/resources/logback-test.xml | 0 .../pom.xml | 0 .../src/main/java/org/example/CommonApi.java | 0 .../main/java/org/example/CommonParams.java | 0 .../main/java/org/example/GitHubService.java | 0 .../main/java/org/example/GitHubUsers.java | 0 .../src/main/java/org/example/JunkApi.java | 0 .../src/main/java/org/example/MyForm.java | 0 .../src/main/java/org/example/OtherApi.java | 0 .../src/main/java/org/example/Repo.java | 0 .../src/main/java/org/example/Simple.java | 0 .../java/org/example/client/package-info.java | 0 .../main/java/org/example/package-info.java | 0 .../org/example/server/CommonController.java | 0 .../main/java/org/example/server/Main.java | 0 .../test/java/org/example/CommonApiTest.java | 0 .../java/org/example/GitHubServiceTest.java | 0 .../src/test/java/org/example/SimpleTest.java | 0 .../io.avaje.http.client.HttpApiProvider | 0 .../src/test/resources/logback-test.xml | 0 111 files changed, 170 insertions(+), 190 deletions(-) rename {http-client/gson-adapter => http-client-gson-adapter}/pom.xml (89%) rename {http-client/gson-adapter => http-client-gson-adapter}/src/main/java/io/avaje/http/client/gson/GsonBodyAdapter.java (100%) rename {http-client/gson-adapter => http-client-gson-adapter}/src/test/java/io/avaje/http/client/gson/Foo.java (100%) rename {http-client/gson-adapter => http-client-gson-adapter}/src/test/java/io/avaje/http/client/gson/GsonBodyAdapterTest.java (100%) delete mode 100644 http-client/client/pom.xml rename http-client/{client => }/src/main/java/io/avaje/http/client/AuthToken.java (100%) rename http-client/{client => }/src/main/java/io/avaje/http/client/AuthTokenProvider.java (100%) rename http-client/{client => }/src/main/java/io/avaje/http/client/BasicAuthIntercept.java (100%) rename http-client/{client => }/src/main/java/io/avaje/http/client/BodyAdapter.java (100%) rename http-client/{client => }/src/main/java/io/avaje/http/client/BodyContent.java (100%) rename http-client/{client => }/src/main/java/io/avaje/http/client/BodyReader.java (100%) rename http-client/{client => }/src/main/java/io/avaje/http/client/BodyWriter.java (100%) rename http-client/{client => }/src/main/java/io/avaje/http/client/DBaseBuilder.java (100%) rename http-client/{client => }/src/main/java/io/avaje/http/client/DHttpApi.java (100%) rename http-client/{client => }/src/main/java/io/avaje/http/client/DHttpAsync.java (100%) rename http-client/{client => }/src/main/java/io/avaje/http/client/DHttpCall.java (100%) rename http-client/{client => }/src/main/java/io/avaje/http/client/DHttpClientBuilder.java (100%) rename http-client/{client => }/src/main/java/io/avaje/http/client/DHttpClientContext.java (100%) rename http-client/{client => }/src/main/java/io/avaje/http/client/DHttpClientContextBuilder.java (100%) rename http-client/{client => }/src/main/java/io/avaje/http/client/DHttpClientRequest.java (100%) rename http-client/{client => }/src/main/java/io/avaje/http/client/DHttpClientRequestWithRetry.java (100%) rename http-client/{client => }/src/main/java/io/avaje/http/client/DRequestInterceptors.java (100%) rename http-client/{client => }/src/main/java/io/avaje/http/client/DRequestListeners.java (100%) rename http-client/{client => }/src/main/java/io/avaje/http/client/GzipUtil.java (100%) rename http-client/{client => }/src/main/java/io/avaje/http/client/HttpApiProvider.java (100%) rename http-client/{client => }/src/main/java/io/avaje/http/client/HttpAsyncResponse.java (100%) rename http-client/{client => }/src/main/java/io/avaje/http/client/HttpCall.java (100%) rename http-client/{client => }/src/main/java/io/avaje/http/client/HttpCallResponse.java (100%) rename http-client/{client => }/src/main/java/io/avaje/http/client/HttpClient.java (100%) rename http-client/{client => }/src/main/java/io/avaje/http/client/HttpClientContext.java (100%) rename http-client/{client => }/src/main/java/io/avaje/http/client/HttpClientRequest.java (99%) rename http-client/{client => }/src/main/java/io/avaje/http/client/HttpClientResponse.java (100%) rename http-client/{client => }/src/main/java/io/avaje/http/client/HttpException.java (100%) rename http-client/{client => }/src/main/java/io/avaje/http/client/JacksonBodyAdapter.java (100%) rename http-client/{client => }/src/main/java/io/avaje/http/client/JsonbBodyAdapter.java (100%) rename http-client/{client => }/src/main/java/io/avaje/http/client/PathConversion.java (100%) rename http-client/{client => }/src/main/java/io/avaje/http/client/RequestIntercept.java (100%) rename http-client/{client => }/src/main/java/io/avaje/http/client/RequestListener.java (100%) rename http-client/{client => }/src/main/java/io/avaje/http/client/RequestLogger.java (100%) rename http-client/{client => }/src/main/java/io/avaje/http/client/RetryHandler.java (100%) rename http-client/{client => }/src/main/java/io/avaje/http/client/SimpleRetryHandler.java (100%) rename http-client/{client => }/src/main/java/io/avaje/http/client/SpiHttpClient.java (100%) rename http-client/{client => }/src/main/java/io/avaje/http/client/UrlBuilder.java (100%) rename http-client/{client => }/src/main/java/io/avaje/http/client/package-info.java (100%) rename http-client/{client => }/src/main/java/module-info.java (100%) rename http-client/{client => }/src/test/java/io/avaje/http/client/AsyncTest.java (100%) rename http-client/{client => }/src/test/java/io/avaje/http/client/AuthTokenTest.java (100%) rename http-client/{client => }/src/test/java/io/avaje/http/client/BaseWebTest.java (91%) rename http-client/{client => }/src/test/java/io/avaje/http/client/BasicAuthInterceptTest.java (100%) rename http-client/{client => }/src/test/java/io/avaje/http/client/DHttpApiTest.java (100%) rename http-client/{client => }/src/test/java/io/avaje/http/client/DHttpClientContextTest.java (100%) rename http-client/{client => }/src/test/java/io/avaje/http/client/DHttpClientRequestTest.java (100%) rename http-client/{client => }/src/test/java/io/avaje/http/client/DRequestInterceptorsTest.java (100%) rename http-client/{client => }/src/test/java/io/avaje/http/client/DRequestListenersTest.java (100%) rename http-client/{client => }/src/test/java/io/avaje/http/client/HelloBasicAuthTest.java (100%) rename http-client/{client => }/src/test/java/io/avaje/http/client/HelloControllerTest.java (99%) rename http-client/{client => }/src/test/java/io/avaje/http/client/PathConversionTest.java (100%) rename http-client/{client => }/src/test/java/io/avaje/http/client/RequestListenerTest.java (97%) rename http-client/{client => }/src/test/java/io/avaje/http/client/RequestLoggerTest.java (100%) rename http-client/{client => }/src/test/java/io/avaje/http/client/RetryTest.java (98%) rename http-client/{client => }/src/test/java/io/avaje/http/client/UrlBuilderTest.java (100%) rename http-client/{client => }/src/test/java/io/avaje/http/client/VerbTest.java (98%) rename http-client/{client => }/src/test/java/org/example/dinject/ConfigureWithDITest.java (100%) rename http-client/{client => }/src/test/java/org/example/dinject/MyDIConfig.java (100%) rename http-client/{client => }/src/test/java/org/example/github/BasicClientInterface.java (100%) rename http-client/{client => }/src/test/java/org/example/github/GithubTest.java (100%) rename http-client/{client => }/src/test/java/org/example/github/Repo.java (100%) rename http-client/{client => }/src/test/java/org/example/github/RepoJsonAdapter.java (100%) rename http-client/{client => }/src/test/java/org/example/github/Simple.java (100%) rename http-client/{client => }/src/test/java/org/example/github/SimpleProvider.java (100%) rename http-client/{client => }/src/test/java/org/example/github/httpclient/BasicClientInterface$HttpClient.java (100%) rename http-client/{client => }/src/test/java/org/example/github/httpclient/Simple$HttpClient.java (100%) rename http-client/{client => }/src/test/java/org/example/webserver/App.java (100%) rename http-client/{client => }/src/test/java/org/example/webserver/ErrorResponse.java (100%) rename http-client/{client => }/src/test/java/org/example/webserver/HelloController$Route.java (100%) rename http-client/{client => }/src/test/java/org/example/webserver/HelloController.java (100%) rename http-client/{client => }/src/test/java/org/example/webserver/HelloDto.java (100%) rename http-client/{client => }/src/test/java/org/example/webserver/HelloForm.java (100%) rename http-client/{client => }/src/test/resources/META-INF/services/io.avaje.http.client.HttpApiProvider (100%) rename http-client/{client => }/src/test/resources/dummy.txt (100%) rename http-client/{client => }/src/test/resources/logback-test.xml (100%) rename {http-client/test => tests/test-client-direct-use}/pom.xml (81%) rename {http-client/test => tests/test-client-direct-use}/src/main/java/example/github/Repo.java (100%) rename {http-client/test => tests/test-client-direct-use}/src/main/java/example/github/Simple.java (100%) rename {http-client/test => tests/test-client-direct-use}/src/main/java/example/github/SimpleHttpClient.java (100%) rename {http-client/test => tests/test-client-direct-use}/src/main/java/module-info.java (100%) rename {http-client/test => tests/test-client-direct-use}/src/main/resources/META-INF/services/io.avaje.http.client.HttpApiProvider (100%) rename {http-client/test => tests/test-client-direct-use}/src/test/java/example/github/GithubTest.java (100%) rename {http-client/test => tests/test-client-direct-use}/src/test/resources/logback-test.xml (100%) rename tests/{test-client => test-client-generation}/pom.xml (100%) rename tests/{test-client => test-client-generation}/src/main/java/org/example/CommonApi.java (100%) rename tests/{test-client => test-client-generation}/src/main/java/org/example/CommonParams.java (100%) rename tests/{test-client => test-client-generation}/src/main/java/org/example/GitHubService.java (100%) rename tests/{test-client => test-client-generation}/src/main/java/org/example/GitHubUsers.java (100%) rename tests/{test-client => test-client-generation}/src/main/java/org/example/JunkApi.java (100%) rename tests/{test-client => test-client-generation}/src/main/java/org/example/MyForm.java (100%) rename tests/{test-client => test-client-generation}/src/main/java/org/example/OtherApi.java (100%) rename tests/{test-client => test-client-generation}/src/main/java/org/example/Repo.java (100%) rename tests/{test-client => test-client-generation}/src/main/java/org/example/Simple.java (100%) rename tests/{test-client => test-client-generation}/src/main/java/org/example/client/package-info.java (100%) rename tests/{test-client => test-client-generation}/src/main/java/org/example/package-info.java (100%) rename tests/{test-client => test-client-generation}/src/main/java/org/example/server/CommonController.java (100%) rename tests/{test-client => test-client-generation}/src/main/java/org/example/server/Main.java (100%) rename tests/{test-client => test-client-generation}/src/test/java/org/example/CommonApiTest.java (100%) rename tests/{test-client => test-client-generation}/src/test/java/org/example/GitHubServiceTest.java (100%) rename tests/{test-client => test-client-generation}/src/test/java/org/example/SimpleTest.java (100%) rename tests/{test-client => test-client-generation}/src/test/resources/META-INF/services/io.avaje.http.client.HttpApiProvider (100%) rename tests/{test-client => test-client-generation}/src/test/resources/logback-test.xml (100%) diff --git a/http-client/gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml similarity index 89% rename from http-client/gson-adapter/pom.xml rename to http-client-gson-adapter/pom.xml index c48776883..6b47b6c3b 100644 --- a/http-client/gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -12,11 +12,6 @@ avaje-http-client-gson 1.23-SNAPSHOT - - scm:git:git@github.com:avaje/avaje-http-client.git - HEAD - - diff --git a/http-client/gson-adapter/src/main/java/io/avaje/http/client/gson/GsonBodyAdapter.java b/http-client-gson-adapter/src/main/java/io/avaje/http/client/gson/GsonBodyAdapter.java similarity index 100% rename from http-client/gson-adapter/src/main/java/io/avaje/http/client/gson/GsonBodyAdapter.java rename to http-client-gson-adapter/src/main/java/io/avaje/http/client/gson/GsonBodyAdapter.java diff --git a/http-client/gson-adapter/src/test/java/io/avaje/http/client/gson/Foo.java b/http-client-gson-adapter/src/test/java/io/avaje/http/client/gson/Foo.java similarity index 100% rename from http-client/gson-adapter/src/test/java/io/avaje/http/client/gson/Foo.java rename to http-client-gson-adapter/src/test/java/io/avaje/http/client/gson/Foo.java diff --git a/http-client/gson-adapter/src/test/java/io/avaje/http/client/gson/GsonBodyAdapterTest.java b/http-client-gson-adapter/src/test/java/io/avaje/http/client/gson/GsonBodyAdapterTest.java similarity index 100% rename from http-client/gson-adapter/src/test/java/io/avaje/http/client/gson/GsonBodyAdapterTest.java rename to http-client-gson-adapter/src/test/java/io/avaje/http/client/gson/GsonBodyAdapterTest.java diff --git a/http-client/client/pom.xml b/http-client/client/pom.xml deleted file mode 100644 index 6f7c1bf46..000000000 --- a/http-client/client/pom.xml +++ /dev/null @@ -1,157 +0,0 @@ - - - 4.0.0 - - org.avaje - java11-oss - 3.9 - - - - io.avaje - avaje-http-client - 1.23-SNAPSHOT - - - scm:git:git@github.com:avaje/avaje-http-client.git - HEAD - - - - false - - - - - - io.avaje - avaje-applog - 1.0 - - - - com.fasterxml.jackson.core - jackson-databind - 2.14.1 - true - - - - io.avaje - avaje-jsonb - 1.1-RC3 - true - - - - io.avaje - avaje-inject - 8.10 - true - - - - - - - - - - - - - io.avaje - avaje-applog-slf4j - 1.0 - test - - - - io.avaje - junit - 1.1 - test - - - - io.javalin - javalin - 5.2.0 - test - - - - io.avaje - avaje-http-api - 1.20 - test - - - - io.avaje - avaje-http-hibernate-validator - 2.8 - test - - - - org.avaje.composite - logback - 1.1 - test - - - - - - - - - - - - - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.10.1 - - - default-testCompile - - - - io.avaje - avaje-inject-generator - 8.10 - - - - - - - - - - maven-surefire-plugin - 3.0.0-M6 - - - - - - - - - - - - - - - - - - diff --git a/http-client/pom.xml b/http-client/pom.xml index 3d204e5bf..6f7c1bf46 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,21 +4,154 @@ org.avaje java11-oss - 3.8 + 3.9 + io.avaje - avaje-http-client-parent - 1 - pom + avaje-http-client + 1.23-SNAPSHOT - + + scm:git:git@github.com:avaje/avaje-http-client.git + HEAD + - - client - gson-adapter - test - + + false + - + + + + io.avaje + avaje-applog + 1.0 + + + + com.fasterxml.jackson.core + jackson-databind + 2.14.1 + true + + + + io.avaje + avaje-jsonb + 1.1-RC3 + true + + + + io.avaje + avaje-inject + 8.10 + true + + + + + + + + + + + + + io.avaje + avaje-applog-slf4j + 1.0 + test + + + + io.avaje + junit + 1.1 + test + + + + io.javalin + javalin + 5.2.0 + test + + + io.avaje + avaje-http-api + 1.20 + test + + + + io.avaje + avaje-http-hibernate-validator + 2.8 + test + + + + org.avaje.composite + logback + 1.1 + test + + + + + + + + + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.10.1 + + + default-testCompile + + + + io.avaje + avaje-inject-generator + 8.10 + + + + + + + + + + maven-surefire-plugin + 3.0.0-M6 + + + + + + + + + + + + + + + + + + diff --git a/http-client/client/src/main/java/io/avaje/http/client/AuthToken.java b/http-client/src/main/java/io/avaje/http/client/AuthToken.java similarity index 100% rename from http-client/client/src/main/java/io/avaje/http/client/AuthToken.java rename to http-client/src/main/java/io/avaje/http/client/AuthToken.java diff --git a/http-client/client/src/main/java/io/avaje/http/client/AuthTokenProvider.java b/http-client/src/main/java/io/avaje/http/client/AuthTokenProvider.java similarity index 100% rename from http-client/client/src/main/java/io/avaje/http/client/AuthTokenProvider.java rename to http-client/src/main/java/io/avaje/http/client/AuthTokenProvider.java diff --git a/http-client/client/src/main/java/io/avaje/http/client/BasicAuthIntercept.java b/http-client/src/main/java/io/avaje/http/client/BasicAuthIntercept.java similarity index 100% rename from http-client/client/src/main/java/io/avaje/http/client/BasicAuthIntercept.java rename to http-client/src/main/java/io/avaje/http/client/BasicAuthIntercept.java diff --git a/http-client/client/src/main/java/io/avaje/http/client/BodyAdapter.java b/http-client/src/main/java/io/avaje/http/client/BodyAdapter.java similarity index 100% rename from http-client/client/src/main/java/io/avaje/http/client/BodyAdapter.java rename to http-client/src/main/java/io/avaje/http/client/BodyAdapter.java diff --git a/http-client/client/src/main/java/io/avaje/http/client/BodyContent.java b/http-client/src/main/java/io/avaje/http/client/BodyContent.java similarity index 100% rename from http-client/client/src/main/java/io/avaje/http/client/BodyContent.java rename to http-client/src/main/java/io/avaje/http/client/BodyContent.java diff --git a/http-client/client/src/main/java/io/avaje/http/client/BodyReader.java b/http-client/src/main/java/io/avaje/http/client/BodyReader.java similarity index 100% rename from http-client/client/src/main/java/io/avaje/http/client/BodyReader.java rename to http-client/src/main/java/io/avaje/http/client/BodyReader.java diff --git a/http-client/client/src/main/java/io/avaje/http/client/BodyWriter.java b/http-client/src/main/java/io/avaje/http/client/BodyWriter.java similarity index 100% rename from http-client/client/src/main/java/io/avaje/http/client/BodyWriter.java rename to http-client/src/main/java/io/avaje/http/client/BodyWriter.java diff --git a/http-client/client/src/main/java/io/avaje/http/client/DBaseBuilder.java b/http-client/src/main/java/io/avaje/http/client/DBaseBuilder.java similarity index 100% rename from http-client/client/src/main/java/io/avaje/http/client/DBaseBuilder.java rename to http-client/src/main/java/io/avaje/http/client/DBaseBuilder.java diff --git a/http-client/client/src/main/java/io/avaje/http/client/DHttpApi.java b/http-client/src/main/java/io/avaje/http/client/DHttpApi.java similarity index 100% rename from http-client/client/src/main/java/io/avaje/http/client/DHttpApi.java rename to http-client/src/main/java/io/avaje/http/client/DHttpApi.java diff --git a/http-client/client/src/main/java/io/avaje/http/client/DHttpAsync.java b/http-client/src/main/java/io/avaje/http/client/DHttpAsync.java similarity index 100% rename from http-client/client/src/main/java/io/avaje/http/client/DHttpAsync.java rename to http-client/src/main/java/io/avaje/http/client/DHttpAsync.java diff --git a/http-client/client/src/main/java/io/avaje/http/client/DHttpCall.java b/http-client/src/main/java/io/avaje/http/client/DHttpCall.java similarity index 100% rename from http-client/client/src/main/java/io/avaje/http/client/DHttpCall.java rename to http-client/src/main/java/io/avaje/http/client/DHttpCall.java diff --git a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientBuilder.java b/http-client/src/main/java/io/avaje/http/client/DHttpClientBuilder.java similarity index 100% rename from http-client/client/src/main/java/io/avaje/http/client/DHttpClientBuilder.java rename to http-client/src/main/java/io/avaje/http/client/DHttpClientBuilder.java diff --git a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContext.java b/http-client/src/main/java/io/avaje/http/client/DHttpClientContext.java similarity index 100% rename from http-client/client/src/main/java/io/avaje/http/client/DHttpClientContext.java rename to http-client/src/main/java/io/avaje/http/client/DHttpClientContext.java diff --git a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientContextBuilder.java b/http-client/src/main/java/io/avaje/http/client/DHttpClientContextBuilder.java similarity index 100% rename from http-client/client/src/main/java/io/avaje/http/client/DHttpClientContextBuilder.java rename to http-client/src/main/java/io/avaje/http/client/DHttpClientContextBuilder.java diff --git a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java b/http-client/src/main/java/io/avaje/http/client/DHttpClientRequest.java similarity index 100% rename from http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java rename to http-client/src/main/java/io/avaje/http/client/DHttpClientRequest.java diff --git a/http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequestWithRetry.java b/http-client/src/main/java/io/avaje/http/client/DHttpClientRequestWithRetry.java similarity index 100% rename from http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequestWithRetry.java rename to http-client/src/main/java/io/avaje/http/client/DHttpClientRequestWithRetry.java diff --git a/http-client/client/src/main/java/io/avaje/http/client/DRequestInterceptors.java b/http-client/src/main/java/io/avaje/http/client/DRequestInterceptors.java similarity index 100% rename from http-client/client/src/main/java/io/avaje/http/client/DRequestInterceptors.java rename to http-client/src/main/java/io/avaje/http/client/DRequestInterceptors.java diff --git a/http-client/client/src/main/java/io/avaje/http/client/DRequestListeners.java b/http-client/src/main/java/io/avaje/http/client/DRequestListeners.java similarity index 100% rename from http-client/client/src/main/java/io/avaje/http/client/DRequestListeners.java rename to http-client/src/main/java/io/avaje/http/client/DRequestListeners.java diff --git a/http-client/client/src/main/java/io/avaje/http/client/GzipUtil.java b/http-client/src/main/java/io/avaje/http/client/GzipUtil.java similarity index 100% rename from http-client/client/src/main/java/io/avaje/http/client/GzipUtil.java rename to http-client/src/main/java/io/avaje/http/client/GzipUtil.java diff --git a/http-client/client/src/main/java/io/avaje/http/client/HttpApiProvider.java b/http-client/src/main/java/io/avaje/http/client/HttpApiProvider.java similarity index 100% rename from http-client/client/src/main/java/io/avaje/http/client/HttpApiProvider.java rename to http-client/src/main/java/io/avaje/http/client/HttpApiProvider.java diff --git a/http-client/client/src/main/java/io/avaje/http/client/HttpAsyncResponse.java b/http-client/src/main/java/io/avaje/http/client/HttpAsyncResponse.java similarity index 100% rename from http-client/client/src/main/java/io/avaje/http/client/HttpAsyncResponse.java rename to http-client/src/main/java/io/avaje/http/client/HttpAsyncResponse.java diff --git a/http-client/client/src/main/java/io/avaje/http/client/HttpCall.java b/http-client/src/main/java/io/avaje/http/client/HttpCall.java similarity index 100% rename from http-client/client/src/main/java/io/avaje/http/client/HttpCall.java rename to http-client/src/main/java/io/avaje/http/client/HttpCall.java diff --git a/http-client/client/src/main/java/io/avaje/http/client/HttpCallResponse.java b/http-client/src/main/java/io/avaje/http/client/HttpCallResponse.java similarity index 100% rename from http-client/client/src/main/java/io/avaje/http/client/HttpCallResponse.java rename to http-client/src/main/java/io/avaje/http/client/HttpCallResponse.java diff --git a/http-client/client/src/main/java/io/avaje/http/client/HttpClient.java b/http-client/src/main/java/io/avaje/http/client/HttpClient.java similarity index 100% rename from http-client/client/src/main/java/io/avaje/http/client/HttpClient.java rename to http-client/src/main/java/io/avaje/http/client/HttpClient.java diff --git a/http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java b/http-client/src/main/java/io/avaje/http/client/HttpClientContext.java similarity index 100% rename from http-client/client/src/main/java/io/avaje/http/client/HttpClientContext.java rename to http-client/src/main/java/io/avaje/http/client/HttpClientContext.java diff --git a/http-client/client/src/main/java/io/avaje/http/client/HttpClientRequest.java b/http-client/src/main/java/io/avaje/http/client/HttpClientRequest.java similarity index 99% rename from http-client/client/src/main/java/io/avaje/http/client/HttpClientRequest.java rename to http-client/src/main/java/io/avaje/http/client/HttpClientRequest.java index 90054a81c..22cc04417 100644 --- a/http-client/client/src/main/java/io/avaje/http/client/HttpClientRequest.java +++ b/http-client/src/main/java/io/avaje/http/client/HttpClientRequest.java @@ -145,7 +145,7 @@ public interface HttpClientRequest { *
{code
    *
    *  HttpResponse res = clientContext.request()
-   *       .url("http://127.0.0.1:8887")
+   *       .url("http://127.0.0.1:8889")
    *       .path("hello")
    *       .GET()
    *       .asString();
diff --git a/http-client/client/src/main/java/io/avaje/http/client/HttpClientResponse.java b/http-client/src/main/java/io/avaje/http/client/HttpClientResponse.java
similarity index 100%
rename from http-client/client/src/main/java/io/avaje/http/client/HttpClientResponse.java
rename to http-client/src/main/java/io/avaje/http/client/HttpClientResponse.java
diff --git a/http-client/client/src/main/java/io/avaje/http/client/HttpException.java b/http-client/src/main/java/io/avaje/http/client/HttpException.java
similarity index 100%
rename from http-client/client/src/main/java/io/avaje/http/client/HttpException.java
rename to http-client/src/main/java/io/avaje/http/client/HttpException.java
diff --git a/http-client/client/src/main/java/io/avaje/http/client/JacksonBodyAdapter.java b/http-client/src/main/java/io/avaje/http/client/JacksonBodyAdapter.java
similarity index 100%
rename from http-client/client/src/main/java/io/avaje/http/client/JacksonBodyAdapter.java
rename to http-client/src/main/java/io/avaje/http/client/JacksonBodyAdapter.java
diff --git a/http-client/client/src/main/java/io/avaje/http/client/JsonbBodyAdapter.java b/http-client/src/main/java/io/avaje/http/client/JsonbBodyAdapter.java
similarity index 100%
rename from http-client/client/src/main/java/io/avaje/http/client/JsonbBodyAdapter.java
rename to http-client/src/main/java/io/avaje/http/client/JsonbBodyAdapter.java
diff --git a/http-client/client/src/main/java/io/avaje/http/client/PathConversion.java b/http-client/src/main/java/io/avaje/http/client/PathConversion.java
similarity index 100%
rename from http-client/client/src/main/java/io/avaje/http/client/PathConversion.java
rename to http-client/src/main/java/io/avaje/http/client/PathConversion.java
diff --git a/http-client/client/src/main/java/io/avaje/http/client/RequestIntercept.java b/http-client/src/main/java/io/avaje/http/client/RequestIntercept.java
similarity index 100%
rename from http-client/client/src/main/java/io/avaje/http/client/RequestIntercept.java
rename to http-client/src/main/java/io/avaje/http/client/RequestIntercept.java
diff --git a/http-client/client/src/main/java/io/avaje/http/client/RequestListener.java b/http-client/src/main/java/io/avaje/http/client/RequestListener.java
similarity index 100%
rename from http-client/client/src/main/java/io/avaje/http/client/RequestListener.java
rename to http-client/src/main/java/io/avaje/http/client/RequestListener.java
diff --git a/http-client/client/src/main/java/io/avaje/http/client/RequestLogger.java b/http-client/src/main/java/io/avaje/http/client/RequestLogger.java
similarity index 100%
rename from http-client/client/src/main/java/io/avaje/http/client/RequestLogger.java
rename to http-client/src/main/java/io/avaje/http/client/RequestLogger.java
diff --git a/http-client/client/src/main/java/io/avaje/http/client/RetryHandler.java b/http-client/src/main/java/io/avaje/http/client/RetryHandler.java
similarity index 100%
rename from http-client/client/src/main/java/io/avaje/http/client/RetryHandler.java
rename to http-client/src/main/java/io/avaje/http/client/RetryHandler.java
diff --git a/http-client/client/src/main/java/io/avaje/http/client/SimpleRetryHandler.java b/http-client/src/main/java/io/avaje/http/client/SimpleRetryHandler.java
similarity index 100%
rename from http-client/client/src/main/java/io/avaje/http/client/SimpleRetryHandler.java
rename to http-client/src/main/java/io/avaje/http/client/SimpleRetryHandler.java
diff --git a/http-client/client/src/main/java/io/avaje/http/client/SpiHttpClient.java b/http-client/src/main/java/io/avaje/http/client/SpiHttpClient.java
similarity index 100%
rename from http-client/client/src/main/java/io/avaje/http/client/SpiHttpClient.java
rename to http-client/src/main/java/io/avaje/http/client/SpiHttpClient.java
diff --git a/http-client/client/src/main/java/io/avaje/http/client/UrlBuilder.java b/http-client/src/main/java/io/avaje/http/client/UrlBuilder.java
similarity index 100%
rename from http-client/client/src/main/java/io/avaje/http/client/UrlBuilder.java
rename to http-client/src/main/java/io/avaje/http/client/UrlBuilder.java
diff --git a/http-client/client/src/main/java/io/avaje/http/client/package-info.java b/http-client/src/main/java/io/avaje/http/client/package-info.java
similarity index 100%
rename from http-client/client/src/main/java/io/avaje/http/client/package-info.java
rename to http-client/src/main/java/io/avaje/http/client/package-info.java
diff --git a/http-client/client/src/main/java/module-info.java b/http-client/src/main/java/module-info.java
similarity index 100%
rename from http-client/client/src/main/java/module-info.java
rename to http-client/src/main/java/module-info.java
diff --git a/http-client/client/src/test/java/io/avaje/http/client/AsyncTest.java b/http-client/src/test/java/io/avaje/http/client/AsyncTest.java
similarity index 100%
rename from http-client/client/src/test/java/io/avaje/http/client/AsyncTest.java
rename to http-client/src/test/java/io/avaje/http/client/AsyncTest.java
diff --git a/http-client/client/src/test/java/io/avaje/http/client/AuthTokenTest.java b/http-client/src/test/java/io/avaje/http/client/AuthTokenTest.java
similarity index 100%
rename from http-client/client/src/test/java/io/avaje/http/client/AuthTokenTest.java
rename to http-client/src/test/java/io/avaje/http/client/AuthTokenTest.java
diff --git a/http-client/client/src/test/java/io/avaje/http/client/BaseWebTest.java b/http-client/src/test/java/io/avaje/http/client/BaseWebTest.java
similarity index 91%
rename from http-client/client/src/test/java/io/avaje/http/client/BaseWebTest.java
rename to http-client/src/test/java/io/avaje/http/client/BaseWebTest.java
index 7b38ff6fc..d71186b38 100644
--- a/http-client/client/src/test/java/io/avaje/http/client/BaseWebTest.java
+++ b/http-client/src/test/java/io/avaje/http/client/BaseWebTest.java
@@ -16,8 +16,8 @@ public class BaseWebTest {
 
   @BeforeAll
   public static void init() {
-    webServer = App.start(8887);
-    baseUrl = "http://localhost:8887";
+    webServer = App.start(8889);
+    baseUrl = "http://localhost:8889";
   }
 
   @AfterAll
diff --git a/http-client/client/src/test/java/io/avaje/http/client/BasicAuthInterceptTest.java b/http-client/src/test/java/io/avaje/http/client/BasicAuthInterceptTest.java
similarity index 100%
rename from http-client/client/src/test/java/io/avaje/http/client/BasicAuthInterceptTest.java
rename to http-client/src/test/java/io/avaje/http/client/BasicAuthInterceptTest.java
diff --git a/http-client/client/src/test/java/io/avaje/http/client/DHttpApiTest.java b/http-client/src/test/java/io/avaje/http/client/DHttpApiTest.java
similarity index 100%
rename from http-client/client/src/test/java/io/avaje/http/client/DHttpApiTest.java
rename to http-client/src/test/java/io/avaje/http/client/DHttpApiTest.java
diff --git a/http-client/client/src/test/java/io/avaje/http/client/DHttpClientContextTest.java b/http-client/src/test/java/io/avaje/http/client/DHttpClientContextTest.java
similarity index 100%
rename from http-client/client/src/test/java/io/avaje/http/client/DHttpClientContextTest.java
rename to http-client/src/test/java/io/avaje/http/client/DHttpClientContextTest.java
diff --git a/http-client/client/src/test/java/io/avaje/http/client/DHttpClientRequestTest.java b/http-client/src/test/java/io/avaje/http/client/DHttpClientRequestTest.java
similarity index 100%
rename from http-client/client/src/test/java/io/avaje/http/client/DHttpClientRequestTest.java
rename to http-client/src/test/java/io/avaje/http/client/DHttpClientRequestTest.java
diff --git a/http-client/client/src/test/java/io/avaje/http/client/DRequestInterceptorsTest.java b/http-client/src/test/java/io/avaje/http/client/DRequestInterceptorsTest.java
similarity index 100%
rename from http-client/client/src/test/java/io/avaje/http/client/DRequestInterceptorsTest.java
rename to http-client/src/test/java/io/avaje/http/client/DRequestInterceptorsTest.java
diff --git a/http-client/client/src/test/java/io/avaje/http/client/DRequestListenersTest.java b/http-client/src/test/java/io/avaje/http/client/DRequestListenersTest.java
similarity index 100%
rename from http-client/client/src/test/java/io/avaje/http/client/DRequestListenersTest.java
rename to http-client/src/test/java/io/avaje/http/client/DRequestListenersTest.java
diff --git a/http-client/client/src/test/java/io/avaje/http/client/HelloBasicAuthTest.java b/http-client/src/test/java/io/avaje/http/client/HelloBasicAuthTest.java
similarity index 100%
rename from http-client/client/src/test/java/io/avaje/http/client/HelloBasicAuthTest.java
rename to http-client/src/test/java/io/avaje/http/client/HelloBasicAuthTest.java
diff --git a/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java b/http-client/src/test/java/io/avaje/http/client/HelloControllerTest.java
similarity index 99%
rename from http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java
rename to http-client/src/test/java/io/avaje/http/client/HelloControllerTest.java
index c2b1aabcd..9968c7e93 100644
--- a/http-client/client/src/test/java/io/avaje/http/client/HelloControllerTest.java
+++ b/http-client/src/test/java/io/avaje/http/client/HelloControllerTest.java
@@ -35,7 +35,7 @@ class HelloControllerTest extends BaseWebTest {
   @Test
   void newClientTest() {
     HttpClient client = HttpClient.builder()
-      .baseUrl("http://localhost:8887")
+      .baseUrl("http://localhost:8889")
       .connectionTimeout(Duration.ofSeconds(1))
       .bodyAdapter(new JacksonBodyAdapter())
       .build();
@@ -51,7 +51,7 @@ void newClientTest() {
       .GET().asString();
 
     assertThat(hres.statusCode()).isEqualTo(200);
-    assertThat(hres.uri().toString()).isEqualTo("http://localhost:8887/hello/message?A=a&B=b");
+    assertThat(hres.uri().toString()).isEqualTo("http://localhost:8889/hello/message?A=a&B=b");
 
     HttpClient.Metrics metrics = client.metrics();
     assertThat(metrics.totalCount()).isEqualTo(1);
@@ -75,7 +75,7 @@ void queryParamMap() {
       .GET().asString();
 
     assertThat(hres.statusCode()).isEqualTo(200);
-    assertThat(hres.uri().toString()).isEqualTo("http://localhost:8887/hello/message?A=a&B=b");
+    assertThat(hres.uri().toString()).isEqualTo("http://localhost:8889/hello/message?A=a&B=b");
 
     HttpClientContext.Metrics metrics = clientContext.metrics();
     assertThat(metrics.totalCount()).isEqualTo(1);
@@ -664,7 +664,7 @@ void asyncViaCall_get_asDiscarding() throws ExecutionException, InterruptedExcep
   void get_helloMessage_via_url() {
 
     final HttpResponse hres = clientContext.request()
-      .url("http://127.0.0.1:8887")
+      .url("http://127.0.0.1:8889")
       .path("hello").path("message")
       .GET().asString();
 
@@ -979,7 +979,7 @@ void postForm_asVoid_validResponse() {
     assertThat(res.previousResponse()).isEmpty();
     assertThat(res.sslSession()).isEmpty();
     assertThat(res.version()).isEqualTo(HTTP_1_1);
-    assertThat(res.uri().toString()).isEqualTo("http://localhost:8887/hello/saveform");
+    assertThat(res.uri().toString()).isEqualTo("http://localhost:8889/hello/saveform");
   }
 
   @Test
diff --git a/http-client/client/src/test/java/io/avaje/http/client/PathConversionTest.java b/http-client/src/test/java/io/avaje/http/client/PathConversionTest.java
similarity index 100%
rename from http-client/client/src/test/java/io/avaje/http/client/PathConversionTest.java
rename to http-client/src/test/java/io/avaje/http/client/PathConversionTest.java
diff --git a/http-client/client/src/test/java/io/avaje/http/client/RequestListenerTest.java b/http-client/src/test/java/io/avaje/http/client/RequestListenerTest.java
similarity index 97%
rename from http-client/client/src/test/java/io/avaje/http/client/RequestListenerTest.java
rename to http-client/src/test/java/io/avaje/http/client/RequestListenerTest.java
index 8788c58b6..cb8115338 100644
--- a/http-client/client/src/test/java/io/avaje/http/client/RequestListenerTest.java
+++ b/http-client/src/test/java/io/avaje/http/client/RequestListenerTest.java
@@ -19,11 +19,11 @@ static class TDRequestListener implements RequestListener {
     public void response(Event event) {
       if (hasBody) {
         assertThat(event.responseBody()).isEqualTo("post");
-        assertThat(event.uri().toString()).isEqualTo("http://localhost:8887/post");
+        assertThat(event.uri().toString()).isEqualTo("http://localhost:8889/post");
         assertThat(event.requestBody()).isEqualTo("post-request-body");
       } else {
         assertThat(event.responseBody()).isEqualTo("hello world");
-        assertThat(event.uri().toString()).isEqualTo("http://localhost:8887/hello/message");
+        assertThat(event.uri().toString()).isEqualTo("http://localhost:8889/hello/message");
         assertThat(event.requestBody()).isNull();
       }
       assertThat(event.responseTimeMicros()).isGreaterThan(1L);
diff --git a/http-client/client/src/test/java/io/avaje/http/client/RequestLoggerTest.java b/http-client/src/test/java/io/avaje/http/client/RequestLoggerTest.java
similarity index 100%
rename from http-client/client/src/test/java/io/avaje/http/client/RequestLoggerTest.java
rename to http-client/src/test/java/io/avaje/http/client/RequestLoggerTest.java
diff --git a/http-client/client/src/test/java/io/avaje/http/client/RetryTest.java b/http-client/src/test/java/io/avaje/http/client/RetryTest.java
similarity index 98%
rename from http-client/client/src/test/java/io/avaje/http/client/RetryTest.java
rename to http-client/src/test/java/io/avaje/http/client/RetryTest.java
index 82c5fe68c..41f76a0f0 100644
--- a/http-client/client/src/test/java/io/avaje/http/client/RetryTest.java
+++ b/http-client/src/test/java/io/avaje/http/client/RetryTest.java
@@ -11,7 +11,7 @@ class RetryTest extends BaseWebTest {
 
   HttpClientContext initClientWithRetry(MyIntercept myIntercept, RetryHandler retryHandler) {
     return HttpClientContext.builder()
-      .baseUrl("http://localhost:8887")
+      .baseUrl("http://localhost:8889")
       .bodyAdapter(new JacksonBodyAdapter())
       .retryHandler(retryHandler)
       .requestIntercept(myIntercept)
diff --git a/http-client/client/src/test/java/io/avaje/http/client/UrlBuilderTest.java b/http-client/src/test/java/io/avaje/http/client/UrlBuilderTest.java
similarity index 100%
rename from http-client/client/src/test/java/io/avaje/http/client/UrlBuilderTest.java
rename to http-client/src/test/java/io/avaje/http/client/UrlBuilderTest.java
diff --git a/http-client/client/src/test/java/io/avaje/http/client/VerbTest.java b/http-client/src/test/java/io/avaje/http/client/VerbTest.java
similarity index 98%
rename from http-client/client/src/test/java/io/avaje/http/client/VerbTest.java
rename to http-client/src/test/java/io/avaje/http/client/VerbTest.java
index ab49dbdc3..fa100a669 100644
--- a/http-client/client/src/test/java/io/avaje/http/client/VerbTest.java
+++ b/http-client/src/test/java/io/avaje/http/client/VerbTest.java
@@ -124,7 +124,7 @@ void delete_with_body_BodyPublishers() {
   @Test
   void delete_with_body_Path() throws URISyntaxException {
 
-    final URL resource = getClass().getResource("/dummy.txt");
+    final URL resource = getClass().getClassLoader().getResource("dummy.txt");
     HttpResponse res = clientContext.request()
       .path("delete")
       .body(Path.of(resource.toURI()))
diff --git a/http-client/client/src/test/java/org/example/dinject/ConfigureWithDITest.java b/http-client/src/test/java/org/example/dinject/ConfigureWithDITest.java
similarity index 100%
rename from http-client/client/src/test/java/org/example/dinject/ConfigureWithDITest.java
rename to http-client/src/test/java/org/example/dinject/ConfigureWithDITest.java
diff --git a/http-client/client/src/test/java/org/example/dinject/MyDIConfig.java b/http-client/src/test/java/org/example/dinject/MyDIConfig.java
similarity index 100%
rename from http-client/client/src/test/java/org/example/dinject/MyDIConfig.java
rename to http-client/src/test/java/org/example/dinject/MyDIConfig.java
diff --git a/http-client/client/src/test/java/org/example/github/BasicClientInterface.java b/http-client/src/test/java/org/example/github/BasicClientInterface.java
similarity index 100%
rename from http-client/client/src/test/java/org/example/github/BasicClientInterface.java
rename to http-client/src/test/java/org/example/github/BasicClientInterface.java
diff --git a/http-client/client/src/test/java/org/example/github/GithubTest.java b/http-client/src/test/java/org/example/github/GithubTest.java
similarity index 100%
rename from http-client/client/src/test/java/org/example/github/GithubTest.java
rename to http-client/src/test/java/org/example/github/GithubTest.java
diff --git a/http-client/client/src/test/java/org/example/github/Repo.java b/http-client/src/test/java/org/example/github/Repo.java
similarity index 100%
rename from http-client/client/src/test/java/org/example/github/Repo.java
rename to http-client/src/test/java/org/example/github/Repo.java
diff --git a/http-client/client/src/test/java/org/example/github/RepoJsonAdapter.java b/http-client/src/test/java/org/example/github/RepoJsonAdapter.java
similarity index 100%
rename from http-client/client/src/test/java/org/example/github/RepoJsonAdapter.java
rename to http-client/src/test/java/org/example/github/RepoJsonAdapter.java
diff --git a/http-client/client/src/test/java/org/example/github/Simple.java b/http-client/src/test/java/org/example/github/Simple.java
similarity index 100%
rename from http-client/client/src/test/java/org/example/github/Simple.java
rename to http-client/src/test/java/org/example/github/Simple.java
diff --git a/http-client/client/src/test/java/org/example/github/SimpleProvider.java b/http-client/src/test/java/org/example/github/SimpleProvider.java
similarity index 100%
rename from http-client/client/src/test/java/org/example/github/SimpleProvider.java
rename to http-client/src/test/java/org/example/github/SimpleProvider.java
diff --git a/http-client/client/src/test/java/org/example/github/httpclient/BasicClientInterface$HttpClient.java b/http-client/src/test/java/org/example/github/httpclient/BasicClientInterface$HttpClient.java
similarity index 100%
rename from http-client/client/src/test/java/org/example/github/httpclient/BasicClientInterface$HttpClient.java
rename to http-client/src/test/java/org/example/github/httpclient/BasicClientInterface$HttpClient.java
diff --git a/http-client/client/src/test/java/org/example/github/httpclient/Simple$HttpClient.java b/http-client/src/test/java/org/example/github/httpclient/Simple$HttpClient.java
similarity index 100%
rename from http-client/client/src/test/java/org/example/github/httpclient/Simple$HttpClient.java
rename to http-client/src/test/java/org/example/github/httpclient/Simple$HttpClient.java
diff --git a/http-client/client/src/test/java/org/example/webserver/App.java b/http-client/src/test/java/org/example/webserver/App.java
similarity index 100%
rename from http-client/client/src/test/java/org/example/webserver/App.java
rename to http-client/src/test/java/org/example/webserver/App.java
diff --git a/http-client/client/src/test/java/org/example/webserver/ErrorResponse.java b/http-client/src/test/java/org/example/webserver/ErrorResponse.java
similarity index 100%
rename from http-client/client/src/test/java/org/example/webserver/ErrorResponse.java
rename to http-client/src/test/java/org/example/webserver/ErrorResponse.java
diff --git a/http-client/client/src/test/java/org/example/webserver/HelloController$Route.java b/http-client/src/test/java/org/example/webserver/HelloController$Route.java
similarity index 100%
rename from http-client/client/src/test/java/org/example/webserver/HelloController$Route.java
rename to http-client/src/test/java/org/example/webserver/HelloController$Route.java
diff --git a/http-client/client/src/test/java/org/example/webserver/HelloController.java b/http-client/src/test/java/org/example/webserver/HelloController.java
similarity index 100%
rename from http-client/client/src/test/java/org/example/webserver/HelloController.java
rename to http-client/src/test/java/org/example/webserver/HelloController.java
diff --git a/http-client/client/src/test/java/org/example/webserver/HelloDto.java b/http-client/src/test/java/org/example/webserver/HelloDto.java
similarity index 100%
rename from http-client/client/src/test/java/org/example/webserver/HelloDto.java
rename to http-client/src/test/java/org/example/webserver/HelloDto.java
diff --git a/http-client/client/src/test/java/org/example/webserver/HelloForm.java b/http-client/src/test/java/org/example/webserver/HelloForm.java
similarity index 100%
rename from http-client/client/src/test/java/org/example/webserver/HelloForm.java
rename to http-client/src/test/java/org/example/webserver/HelloForm.java
diff --git a/http-client/client/src/test/resources/META-INF/services/io.avaje.http.client.HttpApiProvider b/http-client/src/test/resources/META-INF/services/io.avaje.http.client.HttpApiProvider
similarity index 100%
rename from http-client/client/src/test/resources/META-INF/services/io.avaje.http.client.HttpApiProvider
rename to http-client/src/test/resources/META-INF/services/io.avaje.http.client.HttpApiProvider
diff --git a/http-client/client/src/test/resources/dummy.txt b/http-client/src/test/resources/dummy.txt
similarity index 100%
rename from http-client/client/src/test/resources/dummy.txt
rename to http-client/src/test/resources/dummy.txt
diff --git a/http-client/client/src/test/resources/logback-test.xml b/http-client/src/test/resources/logback-test.xml
similarity index 100%
rename from http-client/client/src/test/resources/logback-test.xml
rename to http-client/src/test/resources/logback-test.xml
diff --git a/pom.xml b/pom.xml
index a12ff39d5..ff5936812 100644
--- a/pom.xml
+++ b/pom.xml
@@ -33,6 +33,8 @@
 
   
     http-api
+    http-client
+    http-client-gson-adapter
     http-generator-core
     http-generator-javalin
     http-generator-jex
diff --git a/tests/pom.xml b/tests/pom.xml
index f14840ab8..f5b19daaf 100644
--- a/tests/pom.xml
+++ b/tests/pom.xml
@@ -16,7 +16,8 @@
     test-javalin
     test-javalin-jsonb
     test-jex
-    test-client
+    test-client-generation
+    test-client-direct-use
   
 
   
diff --git a/http-client/test/pom.xml b/tests/test-client-direct-use/pom.xml
similarity index 81%
rename from http-client/test/pom.xml
rename to tests/test-client-direct-use/pom.xml
index 4f1691531..c52d0a53a 100644
--- a/http-client/test/pom.xml
+++ b/tests/test-client-direct-use/pom.xml
@@ -4,12 +4,18 @@
          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
   4.0.0
   
-    avaje-http-client-parent
-    io.avaje
-    1
+    java11-oss
+    org.avaje
+    3.8
+    
   
 
-  test
+  test-client-direct-use
+  1
+
+  
+    UTF-8
+  
 
   
 
diff --git a/http-client/test/src/main/java/example/github/Repo.java b/tests/test-client-direct-use/src/main/java/example/github/Repo.java
similarity index 100%
rename from http-client/test/src/main/java/example/github/Repo.java
rename to tests/test-client-direct-use/src/main/java/example/github/Repo.java
diff --git a/http-client/test/src/main/java/example/github/Simple.java b/tests/test-client-direct-use/src/main/java/example/github/Simple.java
similarity index 100%
rename from http-client/test/src/main/java/example/github/Simple.java
rename to tests/test-client-direct-use/src/main/java/example/github/Simple.java
diff --git a/http-client/test/src/main/java/example/github/SimpleHttpClient.java b/tests/test-client-direct-use/src/main/java/example/github/SimpleHttpClient.java
similarity index 100%
rename from http-client/test/src/main/java/example/github/SimpleHttpClient.java
rename to tests/test-client-direct-use/src/main/java/example/github/SimpleHttpClient.java
diff --git a/http-client/test/src/main/java/module-info.java b/tests/test-client-direct-use/src/main/java/module-info.java
similarity index 100%
rename from http-client/test/src/main/java/module-info.java
rename to tests/test-client-direct-use/src/main/java/module-info.java
diff --git a/http-client/test/src/main/resources/META-INF/services/io.avaje.http.client.HttpApiProvider b/tests/test-client-direct-use/src/main/resources/META-INF/services/io.avaje.http.client.HttpApiProvider
similarity index 100%
rename from http-client/test/src/main/resources/META-INF/services/io.avaje.http.client.HttpApiProvider
rename to tests/test-client-direct-use/src/main/resources/META-INF/services/io.avaje.http.client.HttpApiProvider
diff --git a/http-client/test/src/test/java/example/github/GithubTest.java b/tests/test-client-direct-use/src/test/java/example/github/GithubTest.java
similarity index 100%
rename from http-client/test/src/test/java/example/github/GithubTest.java
rename to tests/test-client-direct-use/src/test/java/example/github/GithubTest.java
diff --git a/http-client/test/src/test/resources/logback-test.xml b/tests/test-client-direct-use/src/test/resources/logback-test.xml
similarity index 100%
rename from http-client/test/src/test/resources/logback-test.xml
rename to tests/test-client-direct-use/src/test/resources/logback-test.xml
diff --git a/tests/test-client/pom.xml b/tests/test-client-generation/pom.xml
similarity index 100%
rename from tests/test-client/pom.xml
rename to tests/test-client-generation/pom.xml
diff --git a/tests/test-client/src/main/java/org/example/CommonApi.java b/tests/test-client-generation/src/main/java/org/example/CommonApi.java
similarity index 100%
rename from tests/test-client/src/main/java/org/example/CommonApi.java
rename to tests/test-client-generation/src/main/java/org/example/CommonApi.java
diff --git a/tests/test-client/src/main/java/org/example/CommonParams.java b/tests/test-client-generation/src/main/java/org/example/CommonParams.java
similarity index 100%
rename from tests/test-client/src/main/java/org/example/CommonParams.java
rename to tests/test-client-generation/src/main/java/org/example/CommonParams.java
diff --git a/tests/test-client/src/main/java/org/example/GitHubService.java b/tests/test-client-generation/src/main/java/org/example/GitHubService.java
similarity index 100%
rename from tests/test-client/src/main/java/org/example/GitHubService.java
rename to tests/test-client-generation/src/main/java/org/example/GitHubService.java
diff --git a/tests/test-client/src/main/java/org/example/GitHubUsers.java b/tests/test-client-generation/src/main/java/org/example/GitHubUsers.java
similarity index 100%
rename from tests/test-client/src/main/java/org/example/GitHubUsers.java
rename to tests/test-client-generation/src/main/java/org/example/GitHubUsers.java
diff --git a/tests/test-client/src/main/java/org/example/JunkApi.java b/tests/test-client-generation/src/main/java/org/example/JunkApi.java
similarity index 100%
rename from tests/test-client/src/main/java/org/example/JunkApi.java
rename to tests/test-client-generation/src/main/java/org/example/JunkApi.java
diff --git a/tests/test-client/src/main/java/org/example/MyForm.java b/tests/test-client-generation/src/main/java/org/example/MyForm.java
similarity index 100%
rename from tests/test-client/src/main/java/org/example/MyForm.java
rename to tests/test-client-generation/src/main/java/org/example/MyForm.java
diff --git a/tests/test-client/src/main/java/org/example/OtherApi.java b/tests/test-client-generation/src/main/java/org/example/OtherApi.java
similarity index 100%
rename from tests/test-client/src/main/java/org/example/OtherApi.java
rename to tests/test-client-generation/src/main/java/org/example/OtherApi.java
diff --git a/tests/test-client/src/main/java/org/example/Repo.java b/tests/test-client-generation/src/main/java/org/example/Repo.java
similarity index 100%
rename from tests/test-client/src/main/java/org/example/Repo.java
rename to tests/test-client-generation/src/main/java/org/example/Repo.java
diff --git a/tests/test-client/src/main/java/org/example/Simple.java b/tests/test-client-generation/src/main/java/org/example/Simple.java
similarity index 100%
rename from tests/test-client/src/main/java/org/example/Simple.java
rename to tests/test-client-generation/src/main/java/org/example/Simple.java
diff --git a/tests/test-client/src/main/java/org/example/client/package-info.java b/tests/test-client-generation/src/main/java/org/example/client/package-info.java
similarity index 100%
rename from tests/test-client/src/main/java/org/example/client/package-info.java
rename to tests/test-client-generation/src/main/java/org/example/client/package-info.java
diff --git a/tests/test-client/src/main/java/org/example/package-info.java b/tests/test-client-generation/src/main/java/org/example/package-info.java
similarity index 100%
rename from tests/test-client/src/main/java/org/example/package-info.java
rename to tests/test-client-generation/src/main/java/org/example/package-info.java
diff --git a/tests/test-client/src/main/java/org/example/server/CommonController.java b/tests/test-client-generation/src/main/java/org/example/server/CommonController.java
similarity index 100%
rename from tests/test-client/src/main/java/org/example/server/CommonController.java
rename to tests/test-client-generation/src/main/java/org/example/server/CommonController.java
diff --git a/tests/test-client/src/main/java/org/example/server/Main.java b/tests/test-client-generation/src/main/java/org/example/server/Main.java
similarity index 100%
rename from tests/test-client/src/main/java/org/example/server/Main.java
rename to tests/test-client-generation/src/main/java/org/example/server/Main.java
diff --git a/tests/test-client/src/test/java/org/example/CommonApiTest.java b/tests/test-client-generation/src/test/java/org/example/CommonApiTest.java
similarity index 100%
rename from tests/test-client/src/test/java/org/example/CommonApiTest.java
rename to tests/test-client-generation/src/test/java/org/example/CommonApiTest.java
diff --git a/tests/test-client/src/test/java/org/example/GitHubServiceTest.java b/tests/test-client-generation/src/test/java/org/example/GitHubServiceTest.java
similarity index 100%
rename from tests/test-client/src/test/java/org/example/GitHubServiceTest.java
rename to tests/test-client-generation/src/test/java/org/example/GitHubServiceTest.java
diff --git a/tests/test-client/src/test/java/org/example/SimpleTest.java b/tests/test-client-generation/src/test/java/org/example/SimpleTest.java
similarity index 100%
rename from tests/test-client/src/test/java/org/example/SimpleTest.java
rename to tests/test-client-generation/src/test/java/org/example/SimpleTest.java
diff --git a/tests/test-client/src/test/resources/META-INF/services/io.avaje.http.client.HttpApiProvider b/tests/test-client-generation/src/test/resources/META-INF/services/io.avaje.http.client.HttpApiProvider
similarity index 100%
rename from tests/test-client/src/test/resources/META-INF/services/io.avaje.http.client.HttpApiProvider
rename to tests/test-client-generation/src/test/resources/META-INF/services/io.avaje.http.client.HttpApiProvider
diff --git a/tests/test-client/src/test/resources/logback-test.xml b/tests/test-client-generation/src/test/resources/logback-test.xml
similarity index 100%
rename from tests/test-client/src/test/resources/logback-test.xml
rename to tests/test-client-generation/src/test/resources/logback-test.xml

From 448f3ad9dfe8884687a17b4d23e1cbf7bece4abb Mon Sep 17 00:00:00 2001
From: Rob Bygrave 
Date: Tue, 17 Jan 2023 09:33:36 +1300
Subject: [PATCH 0507/1323] Rename avaje-http-generator-parent to
 avaje-http-parent

---
 http-api/pom.xml                     | 4 ++--
 http-client-gson-adapter/pom.xml     | 8 ++++----
 http-client/pom.xml                  | 8 ++++----
 http-generator-client/pom.xml        | 2 +-
 http-generator-core/pom.xml          | 2 +-
 http-generator-helidon/pom.xml       | 2 +-
 http-generator-javalin/pom.xml       | 2 +-
 http-generator-jex/pom.xml           | 2 +-
 http-generator-nima/pom.xml          | 2 +-
 pom.xml                              | 4 ++--
 tests/test-client-direct-use/pom.xml | 2 +-
 tests/test-client-generation/pom.xml | 4 ++--
 tests/test-helidon/pom.xml           | 2 +-
 tests/test-javalin-jsonb/pom.xml     | 2 +-
 tests/test-javalin/pom.xml           | 2 +-
 tests/test-jex/pom.xml               | 2 +-
 tests/test-nima-jsonb/pom.xml        | 2 +-
 tests/test-nima/pom.xml              | 2 +-
 18 files changed, 27 insertions(+), 27 deletions(-)

diff --git a/http-api/pom.xml b/http-api/pom.xml
index ad9d130fa..ebb17cb58 100644
--- a/http-api/pom.xml
+++ b/http-api/pom.xml
@@ -3,7 +3,7 @@
   4.0.0
   
     io.avaje
-    avaje-http-generator-parent
+    avaje-http-parent
     1.23-SNAPSHOT
     ..
   
@@ -12,7 +12,7 @@
 
   
     scm:git:git@github.com:avaje/avaje-http.git
-    avaje-http-generator-parent-1.19
+    avaje-http-parent-1.19
   
 
   
diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml
index 6b47b6c3b..30148efcb 100644
--- a/http-client-gson-adapter/pom.xml
+++ b/http-client-gson-adapter/pom.xml
@@ -2,10 +2,10 @@
 
   4.0.0
   
-    org.avaje
-    java11-oss
-    3.9
-    
+    io.avaje
+    avaje-http-parent
+    1.23-SNAPSHOT
+    ..
   
 
   io.avaje
diff --git a/http-client/pom.xml b/http-client/pom.xml
index 6f7c1bf46..62331e7c1 100644
--- a/http-client/pom.xml
+++ b/http-client/pom.xml
@@ -2,10 +2,10 @@
 
   4.0.0
   
-    org.avaje
-    java11-oss
-    3.9
-    
+    io.avaje
+    avaje-http-parent
+    1.23-SNAPSHOT
+    ..
   
 
   io.avaje
diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml
index 140a9aa8a..0d209d7f5 100644
--- a/http-generator-client/pom.xml
+++ b/http-generator-client/pom.xml
@@ -4,7 +4,7 @@
 
   
     io.avaje
-    avaje-http-generator-parent
+    avaje-http-parent
     1.23-SNAPSHOT
     ..
   
diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml
index d5cfe3c25..88680ff11 100644
--- a/http-generator-core/pom.xml
+++ b/http-generator-core/pom.xml
@@ -6,7 +6,7 @@
 
   
     io.avaje
-    avaje-http-generator-parent
+    avaje-http-parent
     1.23-SNAPSHOT
     ..
   
diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml
index d5623fdc4..dc4237ef9 100644
--- a/http-generator-helidon/pom.xml
+++ b/http-generator-helidon/pom.xml
@@ -6,7 +6,7 @@
 
   
     io.avaje
-    avaje-http-generator-parent
+    avaje-http-parent
     1.23-SNAPSHOT
     ..
   
diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml
index 2262c4688..269b5c91e 100644
--- a/http-generator-javalin/pom.xml
+++ b/http-generator-javalin/pom.xml
@@ -6,7 +6,7 @@
 
   
     io.avaje
-    avaje-http-generator-parent
+    avaje-http-parent
     1.23-SNAPSHOT
     ..
   
diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml
index 2ae1b6ceb..f90dd1410 100644
--- a/http-generator-jex/pom.xml
+++ b/http-generator-jex/pom.xml
@@ -6,7 +6,7 @@
 
   
     io.avaje
-    avaje-http-generator-parent
+    avaje-http-parent
     1.23-SNAPSHOT
     ..
   
diff --git a/http-generator-nima/pom.xml b/http-generator-nima/pom.xml
index 884575f2c..75339e430 100644
--- a/http-generator-nima/pom.xml
+++ b/http-generator-nima/pom.xml
@@ -1,7 +1,7 @@
 
 
   
-    avaje-http-generator-parent
+    avaje-http-parent
     io.avaje
     1.23-SNAPSHOT
   
diff --git a/pom.xml b/pom.xml
index ff5936812..6dab42685 100644
--- a/pom.xml
+++ b/pom.xml
@@ -8,13 +8,13 @@
   
 
   io.avaje
-  avaje-http-generator-parent
+  avaje-http-parent
   1.23-SNAPSHOT
   pom
 
   
     scm:git:git@github.com:avaje/avaje-http.git
-    avaje-http-generator-parent-1.19
+    avaje-http-parent-1.19
   
 
   
diff --git a/tests/test-client-direct-use/pom.xml b/tests/test-client-direct-use/pom.xml
index c52d0a53a..ac049b3d8 100644
--- a/tests/test-client-direct-use/pom.xml
+++ b/tests/test-client-direct-use/pom.xml
@@ -6,7 +6,7 @@
   
     java11-oss
     org.avaje
-    3.8
+    3.9
     
   
 
diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml
index 5c2dc3978..7b5c7061b 100644
--- a/tests/test-client-generation/pom.xml
+++ b/tests/test-client-generation/pom.xml
@@ -4,13 +4,13 @@
   
     java11-oss
     org.avaje
-    3.8
+    3.9
     
   
 
   4.0.0
 
-  test-client
+  test-client-generation
   1
 
   
diff --git a/tests/test-helidon/pom.xml b/tests/test-helidon/pom.xml
index ea03df3ee..dc8239437 100644
--- a/tests/test-helidon/pom.xml
+++ b/tests/test-helidon/pom.xml
@@ -9,7 +9,7 @@
   
     org.avaje
     java11-oss
-    3.8
+    3.9
     
   
 
diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml
index 290e56c0f..b19709a9c 100644
--- a/tests/test-javalin-jsonb/pom.xml
+++ b/tests/test-javalin-jsonb/pom.xml
@@ -10,7 +10,7 @@
   
     org.avaje
     java11-oss
-    3.8
+    3.9
     
   
 
diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml
index 5ca6ca25c..50b140123 100644
--- a/tests/test-javalin/pom.xml
+++ b/tests/test-javalin/pom.xml
@@ -9,7 +9,7 @@
   
     org.avaje
     java11-oss
-    3.8
+    3.9
     
   
 
diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml
index 59907959a..20f1e5d3b 100644
--- a/tests/test-jex/pom.xml
+++ b/tests/test-jex/pom.xml
@@ -9,7 +9,7 @@
   
     org.avaje
     java11-oss
-    3.8
+    3.9
     
   
 
diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml
index ea8feacf3..6ffafa610 100644
--- a/tests/test-nima-jsonb/pom.xml
+++ b/tests/test-nima-jsonb/pom.xml
@@ -2,7 +2,7 @@
 
 	4.0.0
 	
-		avaje-http-generator-parent
+		avaje-http-parent
 		io.avaje
 		1.23-SNAPSHOT
 		../../pom.xml
diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml
index 1ec5b8823..c42511d37 100644
--- a/tests/test-nima/pom.xml
+++ b/tests/test-nima/pom.xml
@@ -4,7 +4,7 @@
          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
   4.0.0
   
-    avaje-http-generator-parent
+    avaje-http-parent
     io.avaje
     1.23-SNAPSHOT
     ../../pom.xml

From 1c34331113f0b3a4fd5b99fdc8d249a0225f021d Mon Sep 17 00:00:00 2001
From: Rob Bygrave 
Date: Tue, 17 Jan 2023 09:36:11 +1300
Subject: [PATCH 0508/1323] Rename test module from test-client-direct-use to
 test-client

---
 tests/pom.xml                                                   | 2 +-
 tests/{test-client-direct-use => test-client}/pom.xml           | 2 +-
 .../src/main/java/example/github/Repo.java                      | 0
 .../src/main/java/example/github/Simple.java                    | 0
 .../src/main/java/example/github/SimpleHttpClient.java          | 0
 .../src/main/java/module-info.java                              | 0
 .../META-INF/services/io.avaje.http.client.HttpApiProvider      | 0
 .../src/test/java/example/github/GithubTest.java                | 0
 .../src/test/resources/logback-test.xml                         | 0
 9 files changed, 2 insertions(+), 2 deletions(-)
 rename tests/{test-client-direct-use => test-client}/pom.xml (96%)
 rename tests/{test-client-direct-use => test-client}/src/main/java/example/github/Repo.java (100%)
 rename tests/{test-client-direct-use => test-client}/src/main/java/example/github/Simple.java (100%)
 rename tests/{test-client-direct-use => test-client}/src/main/java/example/github/SimpleHttpClient.java (100%)
 rename tests/{test-client-direct-use => test-client}/src/main/java/module-info.java (100%)
 rename tests/{test-client-direct-use => test-client}/src/main/resources/META-INF/services/io.avaje.http.client.HttpApiProvider (100%)
 rename tests/{test-client-direct-use => test-client}/src/test/java/example/github/GithubTest.java (100%)
 rename tests/{test-client-direct-use => test-client}/src/test/resources/logback-test.xml (100%)

diff --git a/tests/pom.xml b/tests/pom.xml
index f5b19daaf..84158fda5 100644
--- a/tests/pom.xml
+++ b/tests/pom.xml
@@ -16,8 +16,8 @@
     test-javalin
     test-javalin-jsonb
     test-jex
+    test-client
     test-client-generation
-    test-client-direct-use
   
 
   
diff --git a/tests/test-client-direct-use/pom.xml b/tests/test-client/pom.xml
similarity index 96%
rename from tests/test-client-direct-use/pom.xml
rename to tests/test-client/pom.xml
index ac049b3d8..3807597d8 100644
--- a/tests/test-client-direct-use/pom.xml
+++ b/tests/test-client/pom.xml
@@ -10,7 +10,7 @@
     
   
 
-  test-client-direct-use
+  test-client
   1
 
   
diff --git a/tests/test-client-direct-use/src/main/java/example/github/Repo.java b/tests/test-client/src/main/java/example/github/Repo.java
similarity index 100%
rename from tests/test-client-direct-use/src/main/java/example/github/Repo.java
rename to tests/test-client/src/main/java/example/github/Repo.java
diff --git a/tests/test-client-direct-use/src/main/java/example/github/Simple.java b/tests/test-client/src/main/java/example/github/Simple.java
similarity index 100%
rename from tests/test-client-direct-use/src/main/java/example/github/Simple.java
rename to tests/test-client/src/main/java/example/github/Simple.java
diff --git a/tests/test-client-direct-use/src/main/java/example/github/SimpleHttpClient.java b/tests/test-client/src/main/java/example/github/SimpleHttpClient.java
similarity index 100%
rename from tests/test-client-direct-use/src/main/java/example/github/SimpleHttpClient.java
rename to tests/test-client/src/main/java/example/github/SimpleHttpClient.java
diff --git a/tests/test-client-direct-use/src/main/java/module-info.java b/tests/test-client/src/main/java/module-info.java
similarity index 100%
rename from tests/test-client-direct-use/src/main/java/module-info.java
rename to tests/test-client/src/main/java/module-info.java
diff --git a/tests/test-client-direct-use/src/main/resources/META-INF/services/io.avaje.http.client.HttpApiProvider b/tests/test-client/src/main/resources/META-INF/services/io.avaje.http.client.HttpApiProvider
similarity index 100%
rename from tests/test-client-direct-use/src/main/resources/META-INF/services/io.avaje.http.client.HttpApiProvider
rename to tests/test-client/src/main/resources/META-INF/services/io.avaje.http.client.HttpApiProvider
diff --git a/tests/test-client-direct-use/src/test/java/example/github/GithubTest.java b/tests/test-client/src/test/java/example/github/GithubTest.java
similarity index 100%
rename from tests/test-client-direct-use/src/test/java/example/github/GithubTest.java
rename to tests/test-client/src/test/java/example/github/GithubTest.java
diff --git a/tests/test-client-direct-use/src/test/resources/logback-test.xml b/tests/test-client/src/test/resources/logback-test.xml
similarity index 100%
rename from tests/test-client-direct-use/src/test/resources/logback-test.xml
rename to tests/test-client/src/test/resources/logback-test.xml

From b60f87bb67036b343d7223d8c1e9769b43b51c9e Mon Sep 17 00:00:00 2001
From: Rob Bygrave 
Date: Tue, 17 Jan 2023 10:05:31 +1300
Subject: [PATCH 0509/1323] No functional change, refactor tidy
 ControllerReader and MethodReader

---
 .../http/generator/core/ControllerReader.java | 15 ++++++------
 .../http/generator/core/MethodReader.java     | 24 ++++++++-----------
 2 files changed, 18 insertions(+), 21 deletions(-)

diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java
index 8b00eaea5..5aea90f62 100644
--- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java
+++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java
@@ -141,17 +141,18 @@ private boolean initDocHidden() {
   }
 
   private boolean initHasValid() {
-    Annotation jakarta = null;
+    Annotation jakartaValidAnnotation = null;
     try {
-      var anno =
-          (Class)
-              Class.forName(Valid.class.getCanonicalName().replace("javax", "jakarta"));
-      jakarta = findAnnotation(anno);
+      jakartaValidAnnotation = findAnnotation(jakarataValidAnnotation());
     } catch (final ClassNotFoundException e) {
-
+      // ignore
     }
+    return findAnnotation(Valid.class) != null || jakartaValidAnnotation != null;
+  }
 
-    return findAnnotation(Valid.class) != null || jakarta != null;
+  @SuppressWarnings("unchecked")
+  private static Class jakarataValidAnnotation() throws ClassNotFoundException {
+    return (Class)Class.forName(Valid.class.getCanonicalName().replace("javax", "jakarta"));
   }
 
   String produces() {
diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java
index 2d549432a..44201fd61 100644
--- a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java
+++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java
@@ -61,11 +61,7 @@ public class MethodReader {
   private final PathSegments pathSegments;
   private final boolean hasValid;
 
-  MethodReader(
-      ControllerReader bean,
-      ExecutableElement element,
-      ExecutableType actualExecutable,
-      ProcessingContext ctx) {
+  MethodReader(ControllerReader bean, ExecutableElement element, ExecutableType actualExecutable, ProcessingContext ctx) {
     this.ctx = ctx;
     this.bean = bean;
     this.element = element;
@@ -78,18 +74,13 @@ public class MethodReader {
     this.apiResponses = getApiResponses();
     initWebMethodViaAnnotation();
     if (isWebMethod()) {
-
-      Annotation jakarta = null;
+      Annotation jakartaValidAnnotation = null;
       try {
-        final var anno =
-            (Class)
-                Class.forName(Valid.class.getCanonicalName().replace("javax", "jakarta"));
-        jakarta = findAnnotation(anno);
+        jakartaValidAnnotation = findAnnotation(jakartaValidAnnotation());
       } catch (final ClassNotFoundException e) {
-
+        // ignore
       }
-
-      this.hasValid = findAnnotation(Valid.class) != null || jakarta != null;
+      this.hasValid = findAnnotation(Valid.class) != null || jakartaValidAnnotation != null;
       this.pathSegments = PathSegments.parse(Util.combinePath(bean.path(), webMethodPath));
     } else {
       this.hasValid = false;
@@ -97,6 +88,11 @@ public class MethodReader {
     }
   }
 
+  @SuppressWarnings("unchecked")
+  private static Class jakartaValidAnnotation() throws ClassNotFoundException {
+    return (Class) Class.forName(Valid.class.getCanonicalName().replace("javax", "jakarta"));
+  }
+
   @Override
   public String toString() {
     return element.toString();

From 7151aa1b13414fbd7ac65b16a403fce0af034146 Mon Sep 17 00:00:00 2001
From: Rob Bygrave 
Date: Tue, 17 Jan 2023 15:11:35 +1300
Subject: [PATCH 0510/1323] [http-client] ENH: Add response as() methods that
 return HttpResponse wrapping bean, list and stream

These allow access to the http status code and headers for
success responses that we want as a bean, list of stream.
---
 .../io/avaje/http/client/BodyAdapter.java     |   1 -
 .../java/io/avaje/http/client/DHttpAsync.java |  71 +++++++---
 .../avaje/http/client/DHttpClientContext.java |  25 ++--
 .../avaje/http/client/DHttpClientRequest.java | 122 ++++++++++------
 .../avaje/http/client/HttpAsyncResponse.java  | 124 +++++++++++++++++
 .../avaje/http/client/HttpClientResponse.java | 107 ++++++++++++--
 .../avaje/http/client/JsonbBodyAdapter.java   |   8 +-
 .../http/client/HelloControllerTest.java      | 131 +++++++++++++++++-
 8 files changed, 497 insertions(+), 92 deletions(-)

diff --git a/http-client/src/main/java/io/avaje/http/client/BodyAdapter.java b/http-client/src/main/java/io/avaje/http/client/BodyAdapter.java
index 012e50349..5d3fa2d5b 100644
--- a/http-client/src/main/java/io/avaje/http/client/BodyAdapter.java
+++ b/http-client/src/main/java/io/avaje/http/client/BodyAdapter.java
@@ -33,7 +33,6 @@ default  BodyReader beanReader(ParameterizedType type) {
     throw new UnsupportedOperationException("Parameterized types not supported for this adapter");
   }
 
-
   /**
    * Return a BodyReader to read response content and convert to a list of beans.
    *
diff --git a/http-client/src/main/java/io/avaje/http/client/DHttpAsync.java b/http-client/src/main/java/io/avaje/http/client/DHttpAsync.java
index 770f6d38b..c69638438 100644
--- a/http-client/src/main/java/io/avaje/http/client/DHttpAsync.java
+++ b/http-client/src/main/java/io/avaje/http/client/DHttpAsync.java
@@ -61,43 +61,72 @@ public CompletableFuture> asInputStream() {
 
   @Override
   public  CompletableFuture bean(Class type) {
-    return request
-      .performSendAsync(true, HttpResponse.BodyHandlers.ofByteArray())
-      .thenApply(httpResponse -> request.asyncBean(type, httpResponse));
+    return as(type).thenApply(HttpResponse::body);
   }
 
   @Override
-  public  CompletableFuture> list(Class type) {
-    return request
-      .performSendAsync(true, HttpResponse.BodyHandlers.ofByteArray())
-      .thenApply(httpResponse -> request.asyncList(type, httpResponse));
+  public  CompletableFuture bean(ParameterizedType type) {
+    final CompletableFuture> future = as(type);
+    return future.thenApply(HttpResponse::body);
   }
 
   @Override
-  public  CompletableFuture> stream(Class type) {
-    return request
-      .performSendAsync(false, HttpResponse.BodyHandlers.ofLines())
-      .thenApply(httpResponse -> request.asyncStream(type, httpResponse));
+  public  CompletableFuture> as(Class type) {
+    return asyncAsBytes().thenApply(httpResponse -> request.asyncBean(type, httpResponse));
   }
 
   @Override
-  public  CompletableFuture bean(ParameterizedType type) {
-    return request
-      .performSendAsync(true, HttpResponse.BodyHandlers.ofByteArray())
-      .thenApply(httpResponse -> request.asyncBean(type, httpResponse));
+  public  CompletableFuture> as(ParameterizedType type) {
+    return asyncAsBytes().thenApply(httpResponse -> request.asyncBean(type, httpResponse));
+  }
+
+  @Override
+  public  CompletableFuture> list(Class type) {
+    return asList(type).thenApply(HttpResponse::body);
   }
 
   @Override
   public  CompletableFuture> list(ParameterizedType type) {
-    return request
-      .performSendAsync(true, HttpResponse.BodyHandlers.ofByteArray())
-      .thenApply(httpResponse -> request.asyncList(type, httpResponse));
+    final CompletableFuture>> future = asList(type);
+    return future.thenApply(HttpResponse::body);
+  }
+
+  @Override
+  public  CompletableFuture>> asList(Class type) {
+    return asyncAsBytes().thenApply(httpResponse -> request.asyncList(type, httpResponse));
+  }
+
+  @Override
+  public  CompletableFuture>> asList(ParameterizedType type) {
+    return asyncAsBytes().thenApply(httpResponse -> request.asyncList(type, httpResponse));
+  }
+
+  @Override
+  public  CompletableFuture> stream(Class type) {
+    return asStream(type).thenApply(HttpResponse::body);
   }
 
   @Override
   public  CompletableFuture> stream(ParameterizedType type) {
-    return request
-      .performSendAsync(false, HttpResponse.BodyHandlers.ofLines())
-      .thenApply(httpResponse -> request.asyncStream(type, httpResponse));
+    final CompletableFuture>> future = asStream(type);
+    return future.thenApply(HttpResponse::body);
+  }
+
+  @Override
+  public  CompletableFuture>> asStream(Class type) {
+    return asyncAsLines().thenApply(httpResponse -> request.asyncStream(type, httpResponse));
+  }
+
+  @Override
+  public  CompletableFuture>> asStream(ParameterizedType type) {
+    return asyncAsLines().thenApply(httpResponse -> request.asyncStream(type, httpResponse));
+  }
+
+  private CompletableFuture> asyncAsBytes() {
+    return request.performSendAsync(true, HttpResponse.BodyHandlers.ofByteArray());
+  }
+
+  private CompletableFuture>> asyncAsLines() {
+    return request.performSendAsync(false, HttpResponse.BodyHandlers.ofLines());
   }
 }
diff --git a/http-client/src/main/java/io/avaje/http/client/DHttpClientContext.java b/http-client/src/main/java/io/avaje/http/client/DHttpClientContext.java
index cd44ab73b..786602b0f 100644
--- a/http-client/src/main/java/io/avaje/http/client/DHttpClientContext.java
+++ b/http-client/src/main/java/io/avaje/http/client/DHttpClientContext.java
@@ -269,29 +269,30 @@  BodyContent write(T bean, String contentType) {
     return bodyAdapter.beanWriter(bean.getClass()).write(bean, contentType);
   }
 
-   BodyReader beanReader(Class cls) {
-    return bodyAdapter.beanReader(cls);
+   BodyReader beanReader(Class type) {
+    return bodyAdapter.beanReader(type);
   }
 
-   BodyReader beanReader(ParameterizedType cls) {
-    return bodyAdapter.beanReader(cls);
+   BodyReader beanReader(ParameterizedType type) {
+    return bodyAdapter.beanReader(type);
   }
 
-   T readBean(Class cls, BodyContent content) {
-    return bodyAdapter.beanReader(cls).read(content);
+   T readBean(Class type, BodyContent content) {
+    return bodyAdapter.beanReader(type).read(content);
   }
 
-   List readList(Class cls, BodyContent content) {
-    return bodyAdapter.listReader(cls).read(content);
+   List readList(Class type, BodyContent content) {
+    return bodyAdapter.listReader(type).read(content);
   }
 
   @SuppressWarnings("unchecked")
-   T readBean(ParameterizedType cls, BodyContent content) {
-    return (T) bodyAdapter.beanReader(cls).read(content);
+   T readBean(ParameterizedType type, BodyContent content) {
+    return (T) bodyAdapter.beanReader(type).read(content);
   }
 
-   List readList(ParameterizedType cls, BodyContent content) {
-    return (List) bodyAdapter.listReader(cls).read(content);
+  @SuppressWarnings("unchecked")
+   List readList(ParameterizedType type, BodyContent content) {
+    return (List) bodyAdapter.listReader(type).read(content);
   }
 
   void afterResponse(DHttpClientRequest request) {
diff --git a/http-client/src/main/java/io/avaje/http/client/DHttpClientRequest.java b/http-client/src/main/java/io/avaje/http/client/DHttpClientRequest.java
index fd6988703..dc468d631 100644
--- a/http-client/src/main/java/io/avaje/http/client/DHttpClientRequest.java
+++ b/http-client/src/main/java/io/avaje/http/client/DHttpClientRequest.java
@@ -414,7 +414,7 @@ private void readResponseContent() {
   @Override
   public HttpResponse asVoid() {
     readResponseContent();
-    return new HttpVoidResponse(httpResponse);
+    return new HttpWrapperResponse<>(httpResponse);
   }
 
   @Override
@@ -424,50 +424,75 @@ public  T read(BodyReader reader) {
   }
 
   @Override
-  public  T bean(Class cls) {
+  public  HttpResponse as(Class type) {
+    return new HttpWrapperResponse<>(bean(type), httpResponse);
+  }
+
+  @Override
+  public  HttpResponse as(ParameterizedType type) {
+    return new HttpWrapperResponse<>(bean(type), httpResponse);
+  }
+
+  @Override
+  public  T bean(Class type) {
     readResponseContent();
-    return context.readBean(cls, encodedResponseBody);
+    return context.readBean(type, encodedResponseBody);
   }
 
   @Override
-  public  List list(Class cls) {
+  public  T bean(ParameterizedType type) {
     readResponseContent();
-    return context.readList(cls, encodedResponseBody);
+    return context.readBean(type, encodedResponseBody);
   }
 
   @Override
-  public  Stream stream(Class cls) {
-    final HttpResponse> res = handler(HttpResponse.BodyHandlers.ofLines());
-    this.httpResponse = res;
-    if (res.statusCode() >= 300) {
-      throw new HttpException(res, context);
-    }
-    final BodyReader bodyReader = context.beanReader(cls);
-    return res.body().map(bodyReader::readBody);
+  public  HttpResponse> asList(Class type) {
+    return new HttpWrapperResponse<>(list(type), httpResponse);
   }
 
+  @Override
+  public  HttpResponse> asList(ParameterizedType type) {
+    return new HttpWrapperResponse<>(list(type), httpResponse);
+  }
 
   @Override
-  public  T bean(ParameterizedType cls) {
+  public  List list(Class type) {
     readResponseContent();
-    return context.readBean(cls, encodedResponseBody);
+    return context.readList(type, encodedResponseBody);
   }
 
   @Override
-  public  List list(ParameterizedType cls) {
+  public  List list(ParameterizedType type) {
     readResponseContent();
-    return context.readList(cls, encodedResponseBody);
+    return context.readList(type, encodedResponseBody);
+  }
+
+  @Override
+  public  HttpResponse> asStream(Class type) {
+    return new HttpWrapperResponse<>(stream(type), httpResponse);
+  }
+
+  @Override
+  public  HttpResponse> asStream(ParameterizedType type) {
+    return new HttpWrapperResponse<>(stream(type), httpResponse);
   }
 
+  @Override
+  public  Stream stream(Class type) {
+    return stream(context.beanReader(type));
+  }
 
   @Override
-  public  Stream stream(ParameterizedType cls) {
+  public  Stream stream(ParameterizedType type) {
+    return stream(context.beanReader(type));
+  }
+
+  private  Stream stream(BodyReader bodyReader) {
     final HttpResponse> res = handler(HttpResponse.BodyHandlers.ofLines());
     this.httpResponse = res;
     if (res.statusCode() >= 300) {
       throw new HttpException(res, context);
     }
-    final BodyReader bodyReader = context.beanReader(cls);
     return res.body().map(bodyReader::readBody);
   }
 
@@ -484,7 +509,7 @@ public  HttpResponse handler(HttpResponse.BodyHandler responseHandler)
   private  HttpResponse sendWith(HttpResponse.BodyHandler responseHandler) {
     context.beforeRequest(this);
     addHeaders();
-    HttpResponse response = performSend(responseHandler);
+    final HttpResponse response = performSend(responseHandler);
     httpResponse = response;
     return response;
   }
@@ -508,20 +533,30 @@ protected  CompletableFuture> performSendAsync(boolean loggab
 
   protected HttpResponse asyncVoid(HttpResponse response) {
     afterAsyncEncoded(response);
-    return new HttpVoidResponse(response);
+    return new HttpWrapperResponse<>(response);
   }
 
-  protected  E asyncBean(Class type, HttpResponse response) {
+  protected  HttpResponse asyncBean(Class type, HttpResponse response) {
+    afterAsyncEncoded(response);
+    return new HttpWrapperResponse<>(context.readBean(type, encodedResponseBody), httpResponse);
+  }
+
+  protected  E asyncBean(ParameterizedType type, HttpResponse response) {
     afterAsyncEncoded(response);
     return context.readBean(type, encodedResponseBody);
   }
 
-  protected  List asyncList(Class type, HttpResponse response) {
+  protected  HttpResponse> asyncList(Class type, HttpResponse response) {
     afterAsyncEncoded(response);
-    return context.readList(type, encodedResponseBody);
+    return new HttpWrapperResponse<>(context.readList(type, encodedResponseBody), httpResponse);
+  }
+
+  protected  HttpResponse> asyncList(ParameterizedType type, HttpResponse response) {
+    afterAsyncEncoded(response);
+    return new HttpWrapperResponse<>(context.readList(type, encodedResponseBody), httpResponse);
   }
 
-  protected  Stream asyncStream(Class type, HttpResponse> response) {
+  protected  HttpResponse> asyncStream(Class type, HttpResponse> response) {
     responseTimeNanos = System.nanoTime() - startAsyncNanos;
     httpResponse = response;
     context.afterResponse(this);
@@ -529,20 +564,10 @@ protected  Stream asyncStream(Class type, HttpResponse>
       throw new HttpException(response, context);
     }
     final BodyReader bodyReader = context.beanReader(type);
-    return response.body().map(bodyReader::readBody);
+    return new HttpWrapperResponse<>(response.body().map(bodyReader::readBody), httpResponse);
   }
 
-  protected  E asyncBean(ParameterizedType type, HttpResponse response) {
-    afterAsyncEncoded(response);
-    return context.readBean(type, encodedResponseBody);
-  }
-
-  protected  List asyncList(ParameterizedType type, HttpResponse response) {
-    afterAsyncEncoded(response);
-    return context.readList(type, encodedResponseBody);
-  }
-
-  protected  Stream asyncStream(ParameterizedType type, HttpResponse> response) {
+  protected  HttpResponse> asyncStream(ParameterizedType type, HttpResponse> response) {
     responseTimeNanos = System.nanoTime() - startAsyncNanos;
     httpResponse = response;
     context.afterResponse(this);
@@ -550,7 +575,7 @@ protected  Stream asyncStream(ParameterizedType type, HttpResponse bodyReader = context.beanReader(type);
-    return response.body().map(bodyReader::readBody);
+    return new HttpWrapperResponse<>(response.body().map(bodyReader::readBody), httpResponse);
   }
 
   private void afterAsyncEncoded(HttpResponse response) {
@@ -728,13 +753,20 @@ public String responseBody() {
     }
   }
 
-  static class HttpVoidResponse implements HttpResponse {
+  static final class HttpWrapperResponse implements HttpResponse {
 
     private final HttpResponse orig;
+    private final B body;
+
+    HttpWrapperResponse(HttpResponse orig) {
+      this.orig = orig;
+      this.body = null;
+    }
 
     @SuppressWarnings({"raw"})
-    HttpVoidResponse(HttpResponse orig) {
+    HttpWrapperResponse(B body, HttpResponse orig) {
       this.orig = orig;
+      this.body = body;
     }
 
     @Override
@@ -747,9 +779,11 @@ public HttpRequest request() {
       return orig.request();
     }
 
+    @SuppressWarnings("unchecked")
     @Override
-    public Optional> previousResponse() {
-      return Optional.empty();
+    public Optional> previousResponse() {
+      final Optional> previous = orig.previousResponse();
+      return (Optional>)previous;
     }
 
     @Override
@@ -758,8 +792,8 @@ public HttpHeaders headers() {
     }
 
     @Override
-    public Void body() {
-      return null;
+    public B body() {
+      return body;
     }
 
     @Override
diff --git a/http-client/src/main/java/io/avaje/http/client/HttpAsyncResponse.java b/http-client/src/main/java/io/avaje/http/client/HttpAsyncResponse.java
index 7e6dee89d..8626b4270 100644
--- a/http-client/src/main/java/io/avaje/http/client/HttpAsyncResponse.java
+++ b/http-client/src/main/java/io/avaje/http/client/HttpAsyncResponse.java
@@ -232,6 +232,46 @@ default  CompletableFuture> withHandler(HttpResponse.BodyHand
     return handler(bodyHandler);
   }
 
+  /**
+   * Process converting the response body to the given type.
+   * 

+ * If the HTTP statusCode is not in the 2XX range a HttpException is throw which contains + * the HttpResponse. This is the cause in the CompletionException. + * + *

{@code
+   *
+   *    clientContext.request()
+   *       ...
+   *       .POST().async()
+   *       .as(HelloDto.class)
+   *       .whenComplete((helloResponse, throwable) -> {
+   *
+   *         if (throwable != null) {
+   *           HttpException httpException = (HttpException) throwable.getCause();
+   *           int statusCode = httpException.statusCode();
+   *
+   *           // maybe convert json error response body to a bean (using Jackson/Gson)
+   *           MyErrorBean errorResponse = httpException.bean(MyErrorBean.class);
+   *           ..
+   *
+   *         } else {
+   *           int statusCode = helloResponse.statusCode();
+   *           HelloDto helloDto = helloResponse.body();
+   *           ...
+   *         }
+   *       });
+   * }
+ * + * @param type The bean type to convert the content to + * @return The CompletableFuture of the response + */ + CompletableFuture> as(Class type); + + /** + * The same as {@link #as(Class)} but using a generic type. + */ + CompletableFuture> as(ParameterizedType type); + /** * Process expecting a bean response body (typically from json content). *

@@ -266,6 +306,48 @@ default CompletableFuture> withHandler(HttpResponse.BodyHand */ CompletableFuture bean(Class type); + /** + * Process converting the response body to a list of the given type. + *

+ * If the HTTP statusCode is not in the 2XX range a HttpException is throw which contains + * the HttpResponse. This is the cause in the CompletionException. + * + *

{@code
+   *
+   *    clientContext.request()
+   *       ...
+   *       .POST().async()
+   *       .asList(HelloDto.class)
+   *       .whenComplete((helloResponse, throwable) -> {
+   *
+   *         if (throwable != null) {
+   *           // error response
+   *           HttpException httpException = (HttpException) throwable.getCause();
+   *           int statusCode = httpException.statusCode();
+   *
+   *           // maybe convert json error response body to a bean (using Jackson/Gson)
+   *           MyErrorBean errorResponse = httpException.bean(MyErrorBean.class);
+   *           ..
+   *
+   *         } else {
+   *           // success response
+   *           int statusCode = helloResponse.statusCode();
+   *           List body = helloResponse.body();
+   *           ...
+   *         }
+   *       });
+   * }
+ * + * @param type The type to convert the content to + * @return The CompletableFuture of the response + */ + CompletableFuture>> asList(Class type); + + /** + * The same as {@link #asList(Class)} but using a generic type. + */ + CompletableFuture>> asList(ParameterizedType type); + /** * Process expecting a list of beans response body (typically from json content). *

@@ -297,6 +379,48 @@ default CompletableFuture> withHandler(HttpResponse.BodyHand */ CompletableFuture> list(Class type); + /** + * Process converting the response body to a stream of the given type. + *

+ * If the HTTP statusCode is not in the 2XX range a HttpException is throw which contains + * the HttpResponse. This is the cause in the CompletionException. + * + *

{@code
+   *
+   *    clientContext.request()
+   *       ...
+   *       .POST().async()
+   *       .asStream(HelloDto.class)
+   *       .whenComplete((helloResponse, throwable) -> {
+   *
+   *         if (throwable != null) {
+   *           // error response
+   *           HttpException httpException = (HttpException) throwable.getCause();
+   *           int statusCode = httpException.statusCode();
+   *
+   *           // maybe convert json error response body to a bean (using Jackson/Gson)
+   *           MyErrorBean errorResponse = httpException.bean(MyErrorBean.class);
+   *           ..
+   *
+   *         } else {
+   *           // success response
+   *           int statusCode = helloResponse.statusCode();
+   *           Stream body = helloResponse.body();
+   *           ...
+   *         }
+   *       });
+   * }
+ * + * @param type The type to convert the content to + * @return The CompletableFuture of the response + */ + CompletableFuture>> asStream(Class type); + + /** + * The same as {@link #asStream(Class)} but using a generic type. + */ + CompletableFuture>> asStream(ParameterizedType type); + /** * Process response as a stream of beans (x-json-stream). *

diff --git a/http-client/src/main/java/io/avaje/http/client/HttpClientResponse.java b/http-client/src/main/java/io/avaje/http/client/HttpClientResponse.java index 13f4e6537..6d066c2b9 100644 --- a/http-client/src/main/java/io/avaje/http/client/HttpClientResponse.java +++ b/http-client/src/main/java/io/avaje/http/client/HttpClientResponse.java @@ -60,11 +60,104 @@ public interface HttpClientResponse { */ T read(BodyReader reader); + /** + * Return the response with the body containing a single instance of the given type. + *

+ * If the HTTP statusCode is not in the 2XX range a HttpException is throw which contains + * the HttpResponse. This is the cause in the CompletionException when using an async request. + * + * @param type The type of the bean to convert the response content into. + * @param The type that the content is converted to. + * @return The response containing the converted body. + * @throws HttpException when the response has error status codes + */ + HttpResponse as(Class type); + + /** + * Return the response with the body containing a single instance of the given parameterized type. + *

+ * If the HTTP statusCode is not in the 2XX range a HttpException is throw which contains + * the HttpResponse. This is the cause in the CompletionException when using an async request. + * + * @param type The parameterized type of the bean to convert the response content into. + * @return The response containing the converted body. + * @throws HttpException when the response has error status codes + */ + HttpResponse as(ParameterizedType type); + + /** + * Return the response with the body containing a list of the given type. + *

+ * If the HTTP statusCode is not in the 2XX range a HttpException is throw which contains + * the HttpResponse. This is the cause in the CompletionException when using an async request. + * + * @param type The type of the bean to convert the response content into. + * @param The type that the content is converted to. + * @return The response containing the converted body. + * @throws HttpException when the response has error status codes + */ + HttpResponse> asList(Class type); + + /** + * Return the response with the body containing a list of the given parameterized type. + *

+ * If the HTTP statusCode is not in the 2XX range a HttpException is throw which contains + * the HttpResponse. This is the cause in the CompletionException when using an async request. + * + * @param type The type of the bean to convert the response content into. + * @param The type that the content is converted to. + * @return The response containing the converted body. + * @throws HttpException when the response has error status codes + */ + HttpResponse> asList(ParameterizedType type); + + /** + * Return the response with the body containing a stream of beans of the given type. + *

+ * Typically the response is expected to be {@literal application/x-json-stream} + * newline delimited json payload. + *

+ * Note that for this stream request the response content is not deemed + * 'loggable' by avaje-http-client. This is because the entire response + * may not be available at the time of the callback. As such {@link RequestLogger} + * will not include response content when logging stream request/response + *

+ * If the HTTP statusCode is not in the 2XX range a HttpException is throw which contains + * the HttpResponse. This is the cause in the CompletionException when using an async request. + * + * @param type The type of the bean to convert the response content into. + * @param The type that the content is converted to. + * @return The response containing the converted body. + * @throws HttpException when the response has error status codes + */ + HttpResponse> asStream(Class type); + + /** + * Return the response with the body containing a stream of beans of the given parameterized type. + *

+ * Typically the response is expected to be {@literal application/x-json-stream} + * newline delimited json payload. + *

+ * Note that for this stream request the response content is not deemed + * 'loggable' by avaje-http-client. This is because the entire response + * may not be available at the time of the callback. As such {@link RequestLogger} + * will not include response content when logging stream request/response + *

+ * If the HTTP statusCode is not in the 2XX range a HttpException is throw which contains + * the HttpResponse. This is the cause in the CompletionException when using an async request. + * + * @param type The type of the bean to convert the response content into. + * @param The type that the content is converted to. + * @return The response containing the converted body. + * @throws HttpException when the response has error status codes + */ + HttpResponse> asStream(ParameterizedType type); + /** * Return the response as a single bean. *

* If the HTTP statusCode is not in the 2XX range a HttpException is throw which contains - * the HttpResponse. This is the cause in the CompletionException. + * the HttpResponse. This is the cause in the CompletionException when using an async request. * * @param type The type of the bean to convert the response content into. * @param The type that the content is converted to. @@ -77,7 +170,7 @@ public interface HttpClientResponse { * Return the response as a list of beans. *

* If the HTTP statusCode is not in the 2XX range a HttpException is throw which contains - * the HttpResponse. This is the cause in the CompletionException. + * the HttpResponse. This is the cause in the CompletionException when using an async request. * * @param type The type of the bean to convert the response content into. * @param The type that the content is converted to. @@ -86,7 +179,6 @@ public interface HttpClientResponse { */ List list(Class type); - /** * Return the response as a stream of beans. *

@@ -99,7 +191,7 @@ public interface HttpClientResponse { * will not include response content when logging stream request/response *

* If the HTTP statusCode is not in the 2XX range a HttpException is throw which contains - * the HttpResponse. This is the cause in the CompletionException. + * the HttpResponse. This is the cause in the CompletionException when using an async request. * * @param type The type of the bean to convert the response content into. * @param The type that the content is converted to. @@ -112,7 +204,7 @@ public interface HttpClientResponse { * Return the response as a single bean. *

* If the HTTP statusCode is not in the 2XX range a HttpException is throw which contains - * the HttpResponse. This is the cause in the CompletionException. + * the HttpResponse. This is the cause in the CompletionException when using an async request. * * @param type The parameterized type of the bean to convert the response content into. * @return The bean the response is converted into. @@ -124,7 +216,7 @@ public interface HttpClientResponse { * Return the response as a list of beans. *

* If the HTTP statusCode is not in the 2XX range a HttpException is throw which contains - * the HttpResponse. This is the cause in the CompletionException. + * the HttpResponse. This is the cause in the CompletionException when using an async request. * * @param type The parameterized type of the bean to convert the response content into. * @return The list of beans the response is converted into. @@ -144,7 +236,7 @@ public interface HttpClientResponse { * will not include response content when logging stream request/response *

* If the HTTP statusCode is not in the 2XX range a HttpException is throw which contains - * the HttpResponse. This is the cause in the CompletionException. + * the HttpResponse. This is the cause in the CompletionException when using an async request. * * @param type The parameterized type of the bean to convert the response content into. * @return The stream of beans from the response @@ -152,7 +244,6 @@ public interface HttpClientResponse { */ Stream stream(ParameterizedType type); - /** * Return the response with check for 200 range status code. *

+ * If the HTTP statusCode is not in the 2XX range a HttpException is throw which contains + * the HttpResponse. This is the cause in the CompletionException. + * + *

{@code
+   *
+   *  HttpCall> call =
+   *    client.request()
+   *       ...
+   *       .POST()
+   *       .call().as(HelloDto.class);
+   *
+   * }
+ * + * @param type The bean type to convert the content to + * @return The HttpCall to allow sync or async execution + */ + HttpCall> as(Class type); + + /** + * Same as {@link #as(Class)} but takes a generic parameterized type. + */ + HttpCall> as(ParameterizedType type); + + /** + * Same as {@link #as(Class)} but returns {@code HttpResponse>}. + */ + HttpCall>> asList(Class type); + + /** + * Same as {@link #as(Class)} but returns {@code HttpResponse>}. + */ + HttpCall>> asList(ParameterizedType type); + + /** + * Same as {@link #as(Class)} but returns {@code HttpResponse>}. + */ + HttpCall>> asStream(Class type); + + /** + * Same as {@link #as(Class)} but returns {@code HttpResponse>}. + */ + HttpCall>> asStream(ParameterizedType type); + /** * A bean response to execute async or sync. *

@@ -135,7 +181,7 @@ default HttpCall> withHandler(HttpResponse.BodyHandler bo *

{@code
    *
    *  HttpCall call =
-   *    clientContext.request()
+   *    client.request()
    *       ...
    *       .POST()
    *       .call().bean(HelloDto.class);
@@ -156,7 +202,7 @@ default  HttpCall> withHandler(HttpResponse.BodyHandler bo
    * 
{@code
    *
    *  HttpCall> call =
-   *    clientContext.request()
+   *    client.request()
    *       ...
    *       .GET()
    *       .call().list(HelloDto.class);
@@ -176,7 +222,7 @@ default  HttpCall> withHandler(HttpResponse.BodyHandler bo
    * 
{@code
    *
    *  HttpCall> call =
-   *    clientContext.request()
+   *    client.request()
    *       ...
    *       .GET()
    *       .call().stream(HelloDto.class);
diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java
index 8d559d115..dc76753d6 100644
--- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java
+++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java
@@ -137,7 +137,20 @@ private void writeResponse(UType type) {
       writer.append(".stream(");
       writeGeneric(param1);
     } else if (isHttpResponse(mainType)) {
-      writeWithHandler();
+      if (bodyHandlerParam == null) {
+        UType paramType = type.paramRaw();
+        if (paramType.mainType().equals("java.util.List")) {
+          writer.append(".asList(");
+          writeGeneric(paramType.paramRaw());
+        } else if (paramType.mainType().equals("java.util.stream.Stream")) {
+          writer.append(".asStream(");
+          writeGeneric(paramType.paramRaw());
+        } else {
+          writer.append(".as(");
+          writeGeneric(paramType);
+        }
+      } else {
+        writer.append(".handler(%s);", bodyHandlerParam.name()).eol();      }
     } else {
       writer.append(".bean(");
       writeGeneric(type);
@@ -159,14 +172,6 @@ void writeGeneric(UType type) {
     writer.append(");").eol();
   }
 
-  private void writeWithHandler() {
-    if (bodyHandlerParam != null) {
-      writer.append(".handler(%s);", bodyHandlerParam.name()).eol();
-    } else {
-      writer.append(".handler(responseHandler);").eol(); // Better to barf here?
-    }
-  }
-
   private void writeQueryParams(PathSegments pathSegments) {
     for (MethodParam param : method.params()) {
       ParamType paramType = param.paramType();
diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java
index 6743c189a..2fbc53959 100644
--- a/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java
+++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java
@@ -165,6 +165,7 @@ private String extractRawParam() {
         case "java.util.Set":
         case "java.util.List":
         case "java.util.stream.Stream":
+        case "java.net.http.HttpResponse":
         case "java.util.concurrent.CompletableFuture":
         case "io.avaje.http.client.HttpCall":
           var first = rawType.indexOf("<") + 1;
diff --git a/tests/test-client-generation/src/main/java/org/example/WithAsResponseApi.java b/tests/test-client-generation/src/main/java/org/example/WithAsResponseApi.java
new file mode 100644
index 000000000..cb5b99f47
--- /dev/null
+++ b/tests/test-client-generation/src/main/java/org/example/WithAsResponseApi.java
@@ -0,0 +1,35 @@
+package org.example;
+
+import io.avaje.http.api.Client;
+import io.avaje.http.api.Get;
+import io.avaje.http.client.HttpCall;
+
+import java.net.http.HttpResponse;
+import java.util.List;
+import java.util.UUID;
+import java.util.stream.Stream;
+
+@Client
+public interface WithAsResponseApi {
+
+  @Get("/{id}")
+  Repo get(UUID id);
+
+  @Get("/as/{id}")
+  HttpResponse getAs(UUID id);
+
+  @Get("/as-list/{id}")
+  HttpResponse> getAsList(UUID id);
+
+  @Get("/as-stream/{id}")
+  HttpResponse> getAsStream(UUID id);
+
+  @Get("/call-as/{id}")
+  HttpCall> getCallAs(UUID id);
+
+  @Get("/call-as-list/{id}")
+  HttpCall>> getCallAsList(UUID id);
+
+  @Get("/call-as-stream/{id}")
+  HttpCall>> getCallAsStream(UUID id);
+}

From 896e44514a8a12880545f24ccc391dee83414f65 Mon Sep 17 00:00:00 2001
From: Josiah Noel <32279667+SentryMan@users.noreply.github.com>
Date: Wed, 18 Jan 2023 13:38:38 -0500
Subject: [PATCH 0536/1323] use renamed class

---
 http-client/README.md | 64 +++++++++++++++++++++----------------------
 1 file changed, 31 insertions(+), 33 deletions(-)

diff --git a/http-client/README.md b/http-client/README.md
index 5513b53a9..344ccee09 100644
--- a/http-client/README.md
+++ b/http-client/README.md
@@ -2,9 +2,7 @@
 [![Maven Central](https://img.shields.io/maven-central/v/io.avaje/avaje-http-client.svg?label=Maven%20Central)](https://mvnrepository.com/artifact/io.avaje/avaje-http-client)
 [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://github.com/avaje/avaje-http-client/blob/master/LICENSE)
 
-# avaje-http-client
-
-Documentation at [avaje.io/http-client](https://avaje.io/http-client/)
+# [Avaje-HTTP-Client](https://avaje.io/http-client/)
 
 A lightweight wrapper to the [JDK 11+ Java Http Client](http://openjdk.java.net/groups/net/httpclient/intro.html)
 
@@ -28,14 +26,14 @@ A lightweight wrapper to the [JDK 11+ Java Http Client](http://openjdk.java.net/
 
 ```
 
-### Create HttpClientContext
+### Create HttpClient
 
-Create a HttpClientContext with a baseUrl, Jackson or Gson based JSON
+Create a HttpClient with a baseUrl, Jackson or Gson based JSON
  body adapter, logger.
 
 ```java
-  public HttpClientContext client() {
-    return HttpClientContext.builder()
+  public HttpClient client() {
+    return HttpClient.builder()
       .baseUrl(baseUrl)
       .bodyAdapter(new JsonbBodyAdapter())
       //.bodyAdapter(new JacksonBodyAdapter(new ObjectMapper()))
@@ -47,7 +45,7 @@ Create a HttpClientContext with a baseUrl, Jackson or Gson based JSON
 
 ## Requests
 
-From HttpClientContext:
+From HttpClient:
  - Create a request
  - Build the url via path(), matrixParam(), queryParam()
  - Optionally set headers(), cookies() etc
@@ -78,7 +76,7 @@ From HttpClientContext:
 
 #### Example GET as String
 ```java
-HttpResponse hres = clientContext.request()
+HttpResponse hres = client.request()
   .path("hello")
   .GET()
   .asString();
@@ -86,7 +84,7 @@ HttpResponse hres = clientContext.request()
 
 #### Example GET as JSON marshalling into a java class/dto
 ```java
-CustomerDto customer = clientContext.request()
+CustomerDto customer = client.request()
   .path("customers").path(42)
   .GET()
   .bean(CustomerDto.class);
@@ -98,7 +96,7 @@ CustomerDto customer = clientContext.request()
 - In the example below hres is of type HttpResponse<String>
 
 ```java
-clientContext.request()
+client.request()
    .path("hello")
    .GET()
    .async().asString()  // CompletableFuture>
@@ -173,7 +171,7 @@ When sending body content we can use:
 
 #### GET as String
 ```java
-HttpResponse hres = clientContext.request()
+HttpResponse hres = client.request()
   .path("hello")
   .GET()
   .asString();
@@ -185,7 +183,7 @@ HttpResponse hres = clientContext.request()
  - In the example below hres is of type HttpResponse<String>
 
 ```java
-clientContext.request()
+client.request()
    .path("hello")
    .GET()
    .async().asString()
@@ -205,7 +203,7 @@ clientContext.request()
 
 #### GET as json to single bean
 ```java
-Customer customer = clientContext.request()
+Customer customer = client.request()
   .path("customers").path(42)
   .GET()
   .bean(Customer.class);
@@ -213,7 +211,7 @@ Customer customer = clientContext.request()
 
 #### GET as json to a list of beans
 ```java
-List list = clientContext.request()
+List list = client.request()
   .path("customers")
   .GET()
   .list(Customer.class);
@@ -221,7 +219,7 @@ List list = clientContext.request()
 
 #### GET as `application/x-json-stream` as a stream of beans
 ```java
-Stream stream = clientContext.request()
+Stream stream = client.request()
   .path("customers/all")
   .GET()
   .stream(Customer.class);
@@ -232,7 +230,7 @@ Stream stream = clientContext.request()
 ```java
 Hello bean = new Hello(42, "rob", "other");
 
-HttpResponse res = clientContext.request()
+HttpResponse res = client.request()
   .path("hello")
   .body(bean)
   .POST()
@@ -248,7 +246,7 @@ Multiple calls to `path()` append with a `/`. This is make it easier to build a
 programmatically and also build paths that include `matrixParam()`
 
 ```java
-HttpResponse res = clientContext.request()
+HttpResponse res = client.request()
   .path("customers")
   .path("42")
   .path("contacts")
@@ -257,7 +255,7 @@ HttpResponse res = clientContext.request()
 
 // is the same as ...
 
-HttpResponse res = clientContext.request()
+HttpResponse res = client.request()
   .path("customers/42/contacts")
   .GET()
   .asString();
@@ -265,7 +263,7 @@ HttpResponse res = clientContext.request()
 
 #### MatrixParam
 ```java
-HttpResponse httpRes = clientContext.request()
+HttpResponse httpRes = client.request()
   .path("books")
   .matrixParam("author", "rob")
   .matrixParam("country", "nz")
@@ -277,7 +275,7 @@ HttpResponse httpRes = clientContext.request()
 
 #### QueryParam
 ```java
-List beans = clientContext.request()
+List beans = client.request()
   .path("products")
   .queryParam("sortBy", "name")
   .queryParam("maxCount", "100")
@@ -287,7 +285,7 @@ List beans = clientContext.request()
 
 #### FormParam
 ```java
-HttpResponse res = clientContext.request()
+HttpResponse res = client.request()
   .path("register/user")
   .formParam("name", "Bazz")
   .formParam("email", "user@foo.com")
@@ -355,7 +353,7 @@ The `bean()`, `list()` and `stream()` responses throw a `HttpException` if the s
 
 ```java
 
-clientContext.request()
+client.request()
    .path("hello/world")
    .GET()
    .async().asDiscarding()
@@ -374,7 +372,7 @@ clientContext.request()
 ###  .async().asString() - HttpResponse<String>
 
 ```java
-clientContext.request()
+client.request()
    .path("hello/world")
    .GET()
    .async().asString()
@@ -393,7 +391,7 @@ clientContext.request()
 ### .async().bean(HelloDto.class)
 
 ```java
-clientContext.request()
+client.request()
    ...
    .POST().async()
    .bean(HelloDto.class)
@@ -420,7 +418,7 @@ clientContext.request()
 The example below is a line subscriber processing response content line by line.
 
 ```java
-CompletableFuture> future = clientContext.request()
+CompletableFuture> future = client.request()
    .path("hello/lineStream")
    .GET().async()
    .handler(HttpResponse.BodyHandlers.fromLineSubscriber(new Flow.Subscriber<>() {
@@ -460,7 +458,7 @@ choose `async()` to execute the request asynchronously.
 
 ```java
 HttpCall> call =
-  clientContext.request()
+  client.request()
     .path("customers")
     .GET()
     .call().list(Customer.class);
@@ -484,8 +482,8 @@ header ("Basic Auth").
 ##### Example
 
 ```java
-HttpClientContext clientContext =
-   HttpClientContext.builder()
+HttpClient client =
+   HttpClient.builder()
      .baseUrl(baseUrl)
      ...
      .requestIntercept(new BasicAuthIntercept("myUsername", "myPassword"))  
-
-    
-      io.avaje
-      avaje-inject-generator
-      8.11
-      provided
-    
-
   
 
 
diff --git a/http-hibernate-validator/src/main/java/io/avaje/http/hibernate/validator/package-info.java b/http-hibernate-validator/src/main/java/io/avaje/http/hibernate/validator/package-info.java
index 01ee5a58a..f36cfcc89 100644
--- a/http-hibernate-validator/src/main/java/io/avaje/http/hibernate/validator/package-info.java
+++ b/http-hibernate-validator/src/main/java/io/avaje/http/hibernate/validator/package-info.java
@@ -1,4 +1,4 @@
-@InjectModule(name = "bean-validator", provides = io.avaje.http.api.Validator.class)
+/**
+ * Provides a Hibernate Validator to use with avaje-http.
+ */
 package io.avaje.http.hibernate.validator;
-
-import io.avaje.inject.InjectModule;
diff --git a/http-hibernate-validator/src/main/java/module-info.java b/http-hibernate-validator/src/main/java/module-info.java
new file mode 100644
index 000000000..dbd4a1f54
--- /dev/null
+++ b/http-hibernate-validator/src/main/java/module-info.java
@@ -0,0 +1,12 @@
+import io.avaje.http.hibernate.validator.ValidatorProvider;
+
+module io.avaje.http.hibernate.validator {
+
+  exports io.avaje.http.hibernate.validator;
+
+  requires io.avaje.http.api;
+  requires io.avaje.inject;
+  requires jakarta.validation;
+
+  provides io.avaje.inject.spi.Plugin with ValidatorProvider;
+}

From 85b0130dd637fc9d129e49cb2b964924d37c39eb Mon Sep 17 00:00:00 2001
From: Josiah Noel <32279667+SentryMan@users.noreply.github.com>
Date: Thu, 19 Jan 2023 22:39:12 -0500
Subject: [PATCH 0543/1323] update version

---
 http-hibernate-validator/pom.xml                                | 2 +-
 .../resources/META-INF/services/io.avaje.inject.spi.Plugin      | 0
 2 files changed, 1 insertion(+), 1 deletion(-)
 rename http-hibernate-validator/src/{ => main}/resources/META-INF/services/io.avaje.inject.spi.Plugin (100%)

diff --git a/http-hibernate-validator/pom.xml b/http-hibernate-validator/pom.xml
index f5ac927f3..d80d808ca 100644
--- a/http-hibernate-validator/pom.xml
+++ b/http-hibernate-validator/pom.xml
@@ -4,7 +4,7 @@
 
   io.avaje
   avaje-http-hibernate-validator
-  3.0
+  3.2
 
   
     org.avaje
diff --git a/http-hibernate-validator/src/resources/META-INF/services/io.avaje.inject.spi.Plugin b/http-hibernate-validator/src/main/resources/META-INF/services/io.avaje.inject.spi.Plugin
similarity index 100%
rename from http-hibernate-validator/src/resources/META-INF/services/io.avaje.inject.spi.Plugin
rename to http-hibernate-validator/src/main/resources/META-INF/services/io.avaje.inject.spi.Plugin

From 2882d29ca8f6b778c9ca7d2372db14e95b1d3f9a Mon Sep 17 00:00:00 2001
From: Josiah Noel <32279667+SentryMan@users.noreply.github.com>
Date: Thu, 19 Jan 2023 22:42:29 -0500
Subject: [PATCH 0544/1323] Update pom.xml

---
 http-hibernate-validator/pom.xml | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/http-hibernate-validator/pom.xml b/http-hibernate-validator/pom.xml
index d80d808ca..cbbe91e2f 100644
--- a/http-hibernate-validator/pom.xml
+++ b/http-hibernate-validator/pom.xml
@@ -8,7 +8,7 @@
 
   
     org.avaje
-    java8-oss
+    java11-oss
     3.9
     
   
@@ -51,7 +51,7 @@
     
       io.avaje
       avaje-inject-generator
-      8.11
+      8.12-RC1
       provided
     
 

From 50ee7a2d0b0b64cf163b3913c0a4cc59bd3f988b Mon Sep 17 00:00:00 2001
From: Rob Bygrave 
Date: Fri, 20 Jan 2023 17:09:18 +1300
Subject: [PATCH 0545/1323] Fix pom format and avaje-inject version

---
 http-hibernate-validator/pom.xml | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/http-hibernate-validator/pom.xml b/http-hibernate-validator/pom.xml
index 54031b099..01f63773b 100644
--- a/http-hibernate-validator/pom.xml
+++ b/http-hibernate-validator/pom.xml
@@ -1,5 +1,6 @@
 
-
+
   4.0.0
 
   io.avaje
@@ -26,11 +27,11 @@
       8.0.0.Final
     
 
-  	
-	  	org.glassfish.expressly
-	  	expressly
-		  5.0.0
-	  
+    
+      org.glassfish.expressly
+      expressly
+      5.0.0
+    
 
     
       io.avaje
@@ -42,7 +43,7 @@
     
       io.avaje
       avaje-inject
-      8.11
+      8.12-RC1
       provided
     
 

From 332a143644d892a8e2a151fca509b7cebfa71369 Mon Sep 17 00:00:00 2001
From: Rob Bygrave 
Date: Fri, 20 Jan 2023 17:47:12 +1300
Subject: [PATCH 0546/1323] Add module-info for http-client-gson + the helidon
 generators

---
 http-client-gson-adapter/src/main/java/module-info.java | 7 +++++++
 http-generator-helidon/src/main/java/module-info.java   | 7 +++++++
 http-generator-nima/src/main/java/module-info.java      | 7 +++++++
 3 files changed, 21 insertions(+)
 create mode 100644 http-client-gson-adapter/src/main/java/module-info.java
 create mode 100644 http-generator-helidon/src/main/java/module-info.java
 create mode 100644 http-generator-nima/src/main/java/module-info.java

diff --git a/http-client-gson-adapter/src/main/java/module-info.java b/http-client-gson-adapter/src/main/java/module-info.java
new file mode 100644
index 000000000..9933af689
--- /dev/null
+++ b/http-client-gson-adapter/src/main/java/module-info.java
@@ -0,0 +1,7 @@
+module io.avaje.http.client.gson {
+
+  exports io.avaje.http.client.gson;
+
+  requires io.avaje.http.client;
+  requires com.google.gson;
+}
diff --git a/http-generator-helidon/src/main/java/module-info.java b/http-generator-helidon/src/main/java/module-info.java
new file mode 100644
index 000000000..fce86d176
--- /dev/null
+++ b/http-generator-helidon/src/main/java/module-info.java
@@ -0,0 +1,7 @@
+module io.avaje.http.helidon.generator {
+
+  provides javax.annotation.processing.Processor with io.avaje.http.generator.helidon.HelidonProcessor;
+
+  requires transitive io.avaje.http.generator.core;
+  requires java.compiler;
+}
diff --git a/http-generator-nima/src/main/java/module-info.java b/http-generator-nima/src/main/java/module-info.java
new file mode 100644
index 000000000..9a1c8873a
--- /dev/null
+++ b/http-generator-nima/src/main/java/module-info.java
@@ -0,0 +1,7 @@
+module io.avaje.http.nima.generator {
+
+  provides javax.annotation.processing.Processor with io.avaje.http.generator.helidon.nima.NimaProcessor;
+
+  requires transitive io.avaje.http.generator.core;
+  requires java.compiler;
+}

From c40e5c5adb727b41efa61bd5269cf0f98a583a3f Mon Sep 17 00:00:00 2001
From: Rob Bygrave 
Date: Sat, 21 Jan 2023 08:14:56 +1300
Subject: [PATCH 0547/1323] Update tests to use
 io.avaje:openapi-maven-plugin:1.0

---
 tests/test-javalin-jsonb/pom.xml | 4 ++--
 tests/test-javalin/pom.xml       | 4 ++--
 tests/test-jex/pom.xml           | 4 ++--
 3 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml
index cf3c14100..ba1adaff5 100644
--- a/tests/test-javalin-jsonb/pom.xml
+++ b/tests/test-javalin-jsonb/pom.xml
@@ -114,9 +114,9 @@
     
 
       
-        io.dinject
+        io.avaje
         openapi-maven-plugin
-        1.2
+        1.0
         
           
             main
diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml
index 93037b313..12176fe4b 100644
--- a/tests/test-javalin/pom.xml
+++ b/tests/test-javalin/pom.xml
@@ -113,9 +113,9 @@
     
 
       
-        io.dinject
+        io.avaje
         openapi-maven-plugin
-        1.2
+        1.0
         
           
             main
diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml
index 11dd65e2a..a5e7413df 100644
--- a/tests/test-jex/pom.xml
+++ b/tests/test-jex/pom.xml
@@ -105,9 +105,9 @@
     
 
       
-        io.dinject
+        io.avaje
         openapi-maven-plugin
-        1.2
+        1.0
         
           
             main

From 9544536bba136d90985b9696de5ab11d203a9f39 Mon Sep 17 00:00:00 2001
From: Rob Bygrave 
Date: Sat, 21 Jan 2023 08:16:14 +1300
Subject: [PATCH 0548/1323] [maven-release-plugin] prepare release
 avaje-http-parent-1.23

---
 http-api/pom.xml                 | 4 ++--
 http-client-gson-adapter/pom.xml | 6 +++---
 http-client/pom.xml              | 6 +++---
 http-generator-client/pom.xml    | 2 +-
 http-generator-core/pom.xml      | 4 ++--
 http-generator-helidon/pom.xml   | 2 +-
 http-generator-javalin/pom.xml   | 2 +-
 http-generator-jex/pom.xml       | 2 +-
 http-generator-nima/pom.xml      | 2 +-
 pom.xml                          | 4 ++--
 10 files changed, 17 insertions(+), 17 deletions(-)

diff --git a/http-api/pom.xml b/http-api/pom.xml
index ebb17cb58..52a9da703 100644
--- a/http-api/pom.xml
+++ b/http-api/pom.xml
@@ -4,7 +4,7 @@
   
     io.avaje
     avaje-http-parent
-    1.23-SNAPSHOT
+    1.23
     ..
   
 
@@ -12,7 +12,7 @@
 
   
     scm:git:git@github.com:avaje/avaje-http.git
-    avaje-http-parent-1.19
+    avaje-http-parent-1.23
   
 
   
diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml
index 30148efcb..959638ce7 100644
--- a/http-client-gson-adapter/pom.xml
+++ b/http-client-gson-adapter/pom.xml
@@ -4,13 +4,13 @@
   
     io.avaje
     avaje-http-parent
-    1.23-SNAPSHOT
+    1.23
     ..
   
 
   io.avaje
   avaje-http-client-gson
-  1.23-SNAPSHOT
+  1.23
 
   
 
@@ -23,7 +23,7 @@
     
       io.avaje
       avaje-http-client
-      1.23-SNAPSHOT
+      1.23
       provided
     
 
diff --git a/http-client/pom.xml b/http-client/pom.xml
index e21d77dab..b0235a85e 100644
--- a/http-client/pom.xml
+++ b/http-client/pom.xml
@@ -4,17 +4,17 @@
   
     io.avaje
     avaje-http-parent
-    1.23-SNAPSHOT
+    1.23
     ..
   
 
   io.avaje
   avaje-http-client
-  1.23-SNAPSHOT
+  1.23
 
   
     scm:git:git@github.com:avaje/avaje-http-client.git
-    HEAD
+    avaje-http-parent-1.23
   
 
   
diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml
index 0d209d7f5..e1d0a971b 100644
--- a/http-generator-client/pom.xml
+++ b/http-generator-client/pom.xml
@@ -5,7 +5,7 @@
   
     io.avaje
     avaje-http-parent
-    1.23-SNAPSHOT
+    1.23
     ..
   
 
diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml
index 88680ff11..d311c3f5b 100644
--- a/http-generator-core/pom.xml
+++ b/http-generator-core/pom.xml
@@ -7,7 +7,7 @@
   
     io.avaje
     avaje-http-parent
-    1.23-SNAPSHOT
+    1.23
     ..
   
 
@@ -32,7 +32,7 @@
     
       io.avaje
       avaje-http-api
-      1.23-SNAPSHOT
+      1.23
     
 
     
diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml
index dc4237ef9..57a39cc3e 100644
--- a/http-generator-helidon/pom.xml
+++ b/http-generator-helidon/pom.xml
@@ -7,7 +7,7 @@
   
     io.avaje
     avaje-http-parent
-    1.23-SNAPSHOT
+    1.23
     ..
   
 
diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml
index 269b5c91e..a61ee0e26 100644
--- a/http-generator-javalin/pom.xml
+++ b/http-generator-javalin/pom.xml
@@ -7,7 +7,7 @@
   
     io.avaje
     avaje-http-parent
-    1.23-SNAPSHOT
+    1.23
     ..
   
 
diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml
index f90dd1410..d96560b30 100644
--- a/http-generator-jex/pom.xml
+++ b/http-generator-jex/pom.xml
@@ -7,7 +7,7 @@
   
     io.avaje
     avaje-http-parent
-    1.23-SNAPSHOT
+    1.23
     ..
   
 
diff --git a/http-generator-nima/pom.xml b/http-generator-nima/pom.xml
index 75339e430..6ba4f493f 100644
--- a/http-generator-nima/pom.xml
+++ b/http-generator-nima/pom.xml
@@ -3,7 +3,7 @@
   
     avaje-http-parent
     io.avaje
-    1.23-SNAPSHOT
+    1.23
   
   4.0.0
 
diff --git a/pom.xml b/pom.xml
index 6dab42685..cc647b943 100644
--- a/pom.xml
+++ b/pom.xml
@@ -9,12 +9,12 @@
 
   io.avaje
   avaje-http-parent
-  1.23-SNAPSHOT
+  1.23
   pom
 
   
     scm:git:git@github.com:avaje/avaje-http.git
-    avaje-http-parent-1.19
+    avaje-http-parent-1.23
   
 
   

From 09e3c79f19197f939573d1e8a5e1e7253d8423b1 Mon Sep 17 00:00:00 2001
From: Rob Bygrave 
Date: Sat, 21 Jan 2023 08:16:21 +1300
Subject: [PATCH 0549/1323] [maven-release-plugin] prepare for next development
 iteration

---
 http-api/pom.xml                 | 4 ++--
 http-client-gson-adapter/pom.xml | 6 +++---
 http-client/pom.xml              | 6 +++---
 http-generator-client/pom.xml    | 2 +-
 http-generator-core/pom.xml      | 4 ++--
 http-generator-helidon/pom.xml   | 2 +-
 http-generator-javalin/pom.xml   | 2 +-
 http-generator-jex/pom.xml       | 2 +-
 http-generator-nima/pom.xml      | 2 +-
 pom.xml                          | 4 ++--
 10 files changed, 17 insertions(+), 17 deletions(-)

diff --git a/http-api/pom.xml b/http-api/pom.xml
index 52a9da703..948b79898 100644
--- a/http-api/pom.xml
+++ b/http-api/pom.xml
@@ -4,7 +4,7 @@
   
     io.avaje
     avaje-http-parent
-    1.23
+    1.24-SNAPSHOT
     ..
   
 
@@ -12,7 +12,7 @@
 
   
     scm:git:git@github.com:avaje/avaje-http.git
-    avaje-http-parent-1.23
+    avaje-http-parent-1.19
   
 
   
diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml
index 959638ce7..f9cd26e71 100644
--- a/http-client-gson-adapter/pom.xml
+++ b/http-client-gson-adapter/pom.xml
@@ -4,13 +4,13 @@
   
     io.avaje
     avaje-http-parent
-    1.23
+    1.24-SNAPSHOT
     ..
   
 
   io.avaje
   avaje-http-client-gson
-  1.23
+  1.24-SNAPSHOT
 
   
 
@@ -23,7 +23,7 @@
     
       io.avaje
       avaje-http-client
-      1.23
+      1.24-SNAPSHOT
       provided
     
 
diff --git a/http-client/pom.xml b/http-client/pom.xml
index b0235a85e..9704a96da 100644
--- a/http-client/pom.xml
+++ b/http-client/pom.xml
@@ -4,17 +4,17 @@
   
     io.avaje
     avaje-http-parent
-    1.23
+    1.24-SNAPSHOT
     ..
   
 
   io.avaje
   avaje-http-client
-  1.23
+  1.24-SNAPSHOT
 
   
     scm:git:git@github.com:avaje/avaje-http-client.git
-    avaje-http-parent-1.23
+    HEAD
   
 
   
diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml
index e1d0a971b..0fb4cba5c 100644
--- a/http-generator-client/pom.xml
+++ b/http-generator-client/pom.xml
@@ -5,7 +5,7 @@
   
     io.avaje
     avaje-http-parent
-    1.23
+    1.24-SNAPSHOT
     ..
   
 
diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml
index d311c3f5b..03db45019 100644
--- a/http-generator-core/pom.xml
+++ b/http-generator-core/pom.xml
@@ -7,7 +7,7 @@
   
     io.avaje
     avaje-http-parent
-    1.23
+    1.24-SNAPSHOT
     ..
   
 
@@ -32,7 +32,7 @@
     
       io.avaje
       avaje-http-api
-      1.23
+      1.24-SNAPSHOT
     
 
     
diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml
index 57a39cc3e..c6430fa62 100644
--- a/http-generator-helidon/pom.xml
+++ b/http-generator-helidon/pom.xml
@@ -7,7 +7,7 @@
   
     io.avaje
     avaje-http-parent
-    1.23
+    1.24-SNAPSHOT
     ..
   
 
diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml
index a61ee0e26..993dff58d 100644
--- a/http-generator-javalin/pom.xml
+++ b/http-generator-javalin/pom.xml
@@ -7,7 +7,7 @@
   
     io.avaje
     avaje-http-parent
-    1.23
+    1.24-SNAPSHOT
     ..
   
 
diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml
index d96560b30..99a94ebbe 100644
--- a/http-generator-jex/pom.xml
+++ b/http-generator-jex/pom.xml
@@ -7,7 +7,7 @@
   
     io.avaje
     avaje-http-parent
-    1.23
+    1.24-SNAPSHOT
     ..
   
 
diff --git a/http-generator-nima/pom.xml b/http-generator-nima/pom.xml
index 6ba4f493f..f46fd4530 100644
--- a/http-generator-nima/pom.xml
+++ b/http-generator-nima/pom.xml
@@ -3,7 +3,7 @@
   
     avaje-http-parent
     io.avaje
-    1.23
+    1.24-SNAPSHOT
   
   4.0.0
 
diff --git a/pom.xml b/pom.xml
index cc647b943..d296ed315 100644
--- a/pom.xml
+++ b/pom.xml
@@ -9,12 +9,12 @@
 
   io.avaje
   avaje-http-parent
-  1.23
+  1.24-SNAPSHOT
   pom
 
   
     scm:git:git@github.com:avaje/avaje-http.git
-    avaje-http-parent-1.23
+    avaje-http-parent-1.19
   
 
   

From 915da513aaabbcbc22cc1e20e897abee31edc1b0 Mon Sep 17 00:00:00 2001
From: Josiah Noel <32279667+SentryMan@users.noreply.github.com>
Date: Wed, 25 Jan 2023 00:39:31 -0500
Subject: [PATCH 0550/1323] fix roles

---
 .../main/java/io/avaje/http/generator/core/MethodReader.java | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java
index c49348237..b8474a1fc 100644
--- a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java
+++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java
@@ -250,8 +250,9 @@ public void buildApiDocumentation(ProcessingContext ctx) {
   }
 
   public List roles() {
-    methodRoles.addAll(bean.roles());
-    return methodRoles;
+    var roles = new ArrayList<>(methodRoles);
+    roles.addAll(bean.roles());
+    return roles;
   }
 
   public boolean isWebMethod() {

From 103a971352021cd7a11919111c35e2699f6cdf6a Mon Sep 17 00:00:00 2001
From: Josiah Noel <32279667+SentryMan@users.noreply.github.com>
Date: Wed, 25 Jan 2023 10:13:01 -0500
Subject: [PATCH 0551/1323] Revert "[maven-release-plugin] prepare for next
 development iteration"

This reverts commit 09e3c79f19197f939573d1e8a5e1e7253d8423b1.
---
 http-api/pom.xml                 | 4 ++--
 http-client-gson-adapter/pom.xml | 6 +++---
 http-client/pom.xml              | 6 +++---
 http-generator-client/pom.xml    | 2 +-
 http-generator-core/pom.xml      | 4 ++--
 http-generator-helidon/pom.xml   | 2 +-
 http-generator-javalin/pom.xml   | 2 +-
 http-generator-jex/pom.xml       | 2 +-
 http-generator-nima/pom.xml      | 2 +-
 pom.xml                          | 4 ++--
 10 files changed, 17 insertions(+), 17 deletions(-)

diff --git a/http-api/pom.xml b/http-api/pom.xml
index 948b79898..52a9da703 100644
--- a/http-api/pom.xml
+++ b/http-api/pom.xml
@@ -4,7 +4,7 @@
   
     io.avaje
     avaje-http-parent
-    1.24-SNAPSHOT
+    1.23
     ..
   
 
@@ -12,7 +12,7 @@
 
   
     scm:git:git@github.com:avaje/avaje-http.git
-    avaje-http-parent-1.19
+    avaje-http-parent-1.23
   
 
   
diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml
index f9cd26e71..959638ce7 100644
--- a/http-client-gson-adapter/pom.xml
+++ b/http-client-gson-adapter/pom.xml
@@ -4,13 +4,13 @@
   
     io.avaje
     avaje-http-parent
-    1.24-SNAPSHOT
+    1.23
     ..
   
 
   io.avaje
   avaje-http-client-gson
-  1.24-SNAPSHOT
+  1.23
 
   
 
@@ -23,7 +23,7 @@
     
       io.avaje
       avaje-http-client
-      1.24-SNAPSHOT
+      1.23
       provided
     
 
diff --git a/http-client/pom.xml b/http-client/pom.xml
index 9704a96da..b0235a85e 100644
--- a/http-client/pom.xml
+++ b/http-client/pom.xml
@@ -4,17 +4,17 @@
   
     io.avaje
     avaje-http-parent
-    1.24-SNAPSHOT
+    1.23
     ..
   
 
   io.avaje
   avaje-http-client
-  1.24-SNAPSHOT
+  1.23
 
   
     scm:git:git@github.com:avaje/avaje-http-client.git
-    HEAD
+    avaje-http-parent-1.23
   
 
   
diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml
index 0fb4cba5c..e1d0a971b 100644
--- a/http-generator-client/pom.xml
+++ b/http-generator-client/pom.xml
@@ -5,7 +5,7 @@
   
     io.avaje
     avaje-http-parent
-    1.24-SNAPSHOT
+    1.23
     ..
   
 
diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml
index 03db45019..d311c3f5b 100644
--- a/http-generator-core/pom.xml
+++ b/http-generator-core/pom.xml
@@ -7,7 +7,7 @@
   
     io.avaje
     avaje-http-parent
-    1.24-SNAPSHOT
+    1.23
     ..
   
 
@@ -32,7 +32,7 @@
     
       io.avaje
       avaje-http-api
-      1.24-SNAPSHOT
+      1.23
     
 
     
diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml
index c6430fa62..57a39cc3e 100644
--- a/http-generator-helidon/pom.xml
+++ b/http-generator-helidon/pom.xml
@@ -7,7 +7,7 @@
   
     io.avaje
     avaje-http-parent
-    1.24-SNAPSHOT
+    1.23
     ..
   
 
diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml
index 993dff58d..a61ee0e26 100644
--- a/http-generator-javalin/pom.xml
+++ b/http-generator-javalin/pom.xml
@@ -7,7 +7,7 @@
   
     io.avaje
     avaje-http-parent
-    1.24-SNAPSHOT
+    1.23
     ..
   
 
diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml
index 99a94ebbe..d96560b30 100644
--- a/http-generator-jex/pom.xml
+++ b/http-generator-jex/pom.xml
@@ -7,7 +7,7 @@
   
     io.avaje
     avaje-http-parent
-    1.24-SNAPSHOT
+    1.23
     ..
   
 
diff --git a/http-generator-nima/pom.xml b/http-generator-nima/pom.xml
index f46fd4530..6ba4f493f 100644
--- a/http-generator-nima/pom.xml
+++ b/http-generator-nima/pom.xml
@@ -3,7 +3,7 @@
   
     avaje-http-parent
     io.avaje
-    1.24-SNAPSHOT
+    1.23
   
   4.0.0
 
diff --git a/pom.xml b/pom.xml
index d296ed315..cc647b943 100644
--- a/pom.xml
+++ b/pom.xml
@@ -9,12 +9,12 @@
 
   io.avaje
   avaje-http-parent
-  1.24-SNAPSHOT
+  1.23
   pom
 
   
     scm:git:git@github.com:avaje/avaje-http.git
-    avaje-http-parent-1.19
+    avaje-http-parent-1.23
   
 
   

From ba4ae2520d681ab2f78d67ebb7bb55de25560b14 Mon Sep 17 00:00:00 2001
From: Josiah Noel <32279667+SentryMan@users.noreply.github.com>
Date: Wed, 25 Jan 2023 10:13:03 -0500
Subject: [PATCH 0552/1323] Revert "[maven-release-plugin] prepare release
 avaje-http-parent-1.23"

This reverts commit 9544536bba136d90985b9696de5ab11d203a9f39.
---
 http-api/pom.xml                 | 4 ++--
 http-client-gson-adapter/pom.xml | 6 +++---
 http-client/pom.xml              | 6 +++---
 http-generator-client/pom.xml    | 2 +-
 http-generator-core/pom.xml      | 4 ++--
 http-generator-helidon/pom.xml   | 2 +-
 http-generator-javalin/pom.xml   | 2 +-
 http-generator-jex/pom.xml       | 2 +-
 http-generator-nima/pom.xml      | 2 +-
 pom.xml                          | 4 ++--
 10 files changed, 17 insertions(+), 17 deletions(-)

diff --git a/http-api/pom.xml b/http-api/pom.xml
index 52a9da703..ebb17cb58 100644
--- a/http-api/pom.xml
+++ b/http-api/pom.xml
@@ -4,7 +4,7 @@
   
     io.avaje
     avaje-http-parent
-    1.23
+    1.23-SNAPSHOT
     ..
   
 
@@ -12,7 +12,7 @@
 
   
     scm:git:git@github.com:avaje/avaje-http.git
-    avaje-http-parent-1.23
+    avaje-http-parent-1.19
   
 
   
diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml
index 959638ce7..30148efcb 100644
--- a/http-client-gson-adapter/pom.xml
+++ b/http-client-gson-adapter/pom.xml
@@ -4,13 +4,13 @@
   
     io.avaje
     avaje-http-parent
-    1.23
+    1.23-SNAPSHOT
     ..
   
 
   io.avaje
   avaje-http-client-gson
-  1.23
+  1.23-SNAPSHOT
 
   
 
@@ -23,7 +23,7 @@
     
       io.avaje
       avaje-http-client
-      1.23
+      1.23-SNAPSHOT
       provided
     
 
diff --git a/http-client/pom.xml b/http-client/pom.xml
index b0235a85e..e21d77dab 100644
--- a/http-client/pom.xml
+++ b/http-client/pom.xml
@@ -4,17 +4,17 @@
   
     io.avaje
     avaje-http-parent
-    1.23
+    1.23-SNAPSHOT
     ..
   
 
   io.avaje
   avaje-http-client
-  1.23
+  1.23-SNAPSHOT
 
   
     scm:git:git@github.com:avaje/avaje-http-client.git
-    avaje-http-parent-1.23
+    HEAD
   
 
   
diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml
index e1d0a971b..0d209d7f5 100644
--- a/http-generator-client/pom.xml
+++ b/http-generator-client/pom.xml
@@ -5,7 +5,7 @@
   
     io.avaje
     avaje-http-parent
-    1.23
+    1.23-SNAPSHOT
     ..
   
 
diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml
index d311c3f5b..88680ff11 100644
--- a/http-generator-core/pom.xml
+++ b/http-generator-core/pom.xml
@@ -7,7 +7,7 @@
   
     io.avaje
     avaje-http-parent
-    1.23
+    1.23-SNAPSHOT
     ..
   
 
@@ -32,7 +32,7 @@
     
       io.avaje
       avaje-http-api
-      1.23
+      1.23-SNAPSHOT
     
 
     
diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml
index 57a39cc3e..dc4237ef9 100644
--- a/http-generator-helidon/pom.xml
+++ b/http-generator-helidon/pom.xml
@@ -7,7 +7,7 @@
   
     io.avaje
     avaje-http-parent
-    1.23
+    1.23-SNAPSHOT
     ..
   
 
diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml
index a61ee0e26..269b5c91e 100644
--- a/http-generator-javalin/pom.xml
+++ b/http-generator-javalin/pom.xml
@@ -7,7 +7,7 @@
   
     io.avaje
     avaje-http-parent
-    1.23
+    1.23-SNAPSHOT
     ..
   
 
diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml
index d96560b30..f90dd1410 100644
--- a/http-generator-jex/pom.xml
+++ b/http-generator-jex/pom.xml
@@ -7,7 +7,7 @@
   
     io.avaje
     avaje-http-parent
-    1.23
+    1.23-SNAPSHOT
     ..
   
 
diff --git a/http-generator-nima/pom.xml b/http-generator-nima/pom.xml
index 6ba4f493f..75339e430 100644
--- a/http-generator-nima/pom.xml
+++ b/http-generator-nima/pom.xml
@@ -3,7 +3,7 @@
   
     avaje-http-parent
     io.avaje
-    1.23
+    1.23-SNAPSHOT
   
   4.0.0
 
diff --git a/pom.xml b/pom.xml
index cc647b943..6dab42685 100644
--- a/pom.xml
+++ b/pom.xml
@@ -9,12 +9,12 @@
 
   io.avaje
   avaje-http-parent
-  1.23
+  1.23-SNAPSHOT
   pom
 
   
     scm:git:git@github.com:avaje/avaje-http.git
-    avaje-http-parent-1.23
+    avaje-http-parent-1.19
   
 
   

From 65a2914397f872a5ebe69ff2c51d43b1f55b3c3f Mon Sep 17 00:00:00 2001
From: Josiah Noel <32279667+SentryMan@users.noreply.github.com>
Date: Sat, 28 Jan 2023 00:20:05 -0500
Subject: [PATCH 0553/1323] now Inner Type Short names work again

---
 .../io/avaje/http/generator/core/UType.java   | 25 ++++++++++++++++++-
 .../io/avaje/http/generator/core/Util.java    | 10 +++++++-
 2 files changed, 33 insertions(+), 2 deletions(-)

diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java
index 2fbc53959..dfe907536 100644
--- a/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java
+++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java
@@ -202,12 +202,35 @@ public Set importTypes() {
       Set set = new LinkedHashSet<>();
       for (String type : allTypes) {
         if (!type.startsWith("java.lang.") && type.indexOf('.') > -1) {
-          set.add(type.replace("[]", ""));
+          set.add(innerTypesImport(type).replace("[]", ""));
         }
       }
       return set;
     }
 
+    public String innerTypesImport(String type) {
+
+      final var parts = type.split("\\.");
+      var result = "";
+      var foundUpper = false;
+
+      for (var i = 0; i < parts.length; i++) {
+        if (!Character.isUpperCase(parts[i].charAt(0))) {
+          result += parts[i] + ".";
+        } else if (!foundUpper) {
+          foundUpper = true;
+          result += parts[i] + (i == parts.length - 1 ? "" : ".");
+        } else {
+          break;
+        }
+      }
+
+      if (result.endsWith(".")) {
+        result = result.substring(0, result.length() - 1);
+      }
+      return result;
+    }
+
     @Override
     public boolean isGeneric() {
       return true;
diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/Util.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/Util.java
index 2f7e2d9e6..500b14016 100644
--- a/http-generator-core/src/main/java/io/avaje/http/generator/core/Util.java
+++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/Util.java
@@ -76,7 +76,15 @@ public static String shortName(String fullType) {
     if (p == -1) {
       return fullType;
     } else {
-      return fullType.substring(p + 1);
+      var result = "";
+      var foundClass = false;
+      for (final String part : fullType.split("\\.")) {
+        if (foundClass || Character.isUpperCase(part.charAt(0))) {
+          foundClass = true;
+          result += (result.isEmpty() ? "" : ".") + part;
+        }
+      }
+      return result;
     }
   }
 

From 98e675612a9fe4e5e60a2c3db65178fa4f9d8585 Mon Sep 17 00:00:00 2001
From: Josiah Noel <32279667+SentryMan@users.noreply.github.com>
Date: Sat, 28 Jan 2023 00:49:59 -0500
Subject: [PATCH 0554/1323] Revert "[maven-release-plugin] prepare for next
 development iteration"

This reverts commit 09e3c79f19197f939573d1e8a5e1e7253d8423b1.
---
 http-api/pom.xml                 | 4 ++--
 http-client-gson-adapter/pom.xml | 6 +++---
 http-client/pom.xml              | 6 +++---
 http-generator-client/pom.xml    | 2 +-
 http-generator-core/pom.xml      | 4 ++--
 http-generator-helidon/pom.xml   | 2 +-
 http-generator-javalin/pom.xml   | 2 +-
 http-generator-jex/pom.xml       | 2 +-
 http-generator-nima/pom.xml      | 2 +-
 pom.xml                          | 4 ++--
 10 files changed, 17 insertions(+), 17 deletions(-)

diff --git a/http-api/pom.xml b/http-api/pom.xml
index 948b79898..52a9da703 100644
--- a/http-api/pom.xml
+++ b/http-api/pom.xml
@@ -4,7 +4,7 @@
   
     io.avaje
     avaje-http-parent
-    1.24-SNAPSHOT
+    1.23
     ..
   
 
@@ -12,7 +12,7 @@
 
   
     scm:git:git@github.com:avaje/avaje-http.git
-    avaje-http-parent-1.19
+    avaje-http-parent-1.23
   
 
   
diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml
index f9cd26e71..959638ce7 100644
--- a/http-client-gson-adapter/pom.xml
+++ b/http-client-gson-adapter/pom.xml
@@ -4,13 +4,13 @@
   
     io.avaje
     avaje-http-parent
-    1.24-SNAPSHOT
+    1.23
     ..
   
 
   io.avaje
   avaje-http-client-gson
-  1.24-SNAPSHOT
+  1.23
 
   
 
@@ -23,7 +23,7 @@
     
       io.avaje
       avaje-http-client
-      1.24-SNAPSHOT
+      1.23
       provided
     
 
diff --git a/http-client/pom.xml b/http-client/pom.xml
index 9704a96da..b0235a85e 100644
--- a/http-client/pom.xml
+++ b/http-client/pom.xml
@@ -4,17 +4,17 @@
   
     io.avaje
     avaje-http-parent
-    1.24-SNAPSHOT
+    1.23
     ..
   
 
   io.avaje
   avaje-http-client
-  1.24-SNAPSHOT
+  1.23
 
   
     scm:git:git@github.com:avaje/avaje-http-client.git
-    HEAD
+    avaje-http-parent-1.23
   
 
   
diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml
index 0fb4cba5c..e1d0a971b 100644
--- a/http-generator-client/pom.xml
+++ b/http-generator-client/pom.xml
@@ -5,7 +5,7 @@
   
     io.avaje
     avaje-http-parent
-    1.24-SNAPSHOT
+    1.23
     ..
   
 
diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml
index 03db45019..d311c3f5b 100644
--- a/http-generator-core/pom.xml
+++ b/http-generator-core/pom.xml
@@ -7,7 +7,7 @@
   
     io.avaje
     avaje-http-parent
-    1.24-SNAPSHOT
+    1.23
     ..
   
 
@@ -32,7 +32,7 @@
     
       io.avaje
       avaje-http-api
-      1.24-SNAPSHOT
+      1.23
     
 
     
diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml
index c6430fa62..57a39cc3e 100644
--- a/http-generator-helidon/pom.xml
+++ b/http-generator-helidon/pom.xml
@@ -7,7 +7,7 @@
   
     io.avaje
     avaje-http-parent
-    1.24-SNAPSHOT
+    1.23
     ..
   
 
diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml
index 993dff58d..a61ee0e26 100644
--- a/http-generator-javalin/pom.xml
+++ b/http-generator-javalin/pom.xml
@@ -7,7 +7,7 @@
   
     io.avaje
     avaje-http-parent
-    1.24-SNAPSHOT
+    1.23
     ..
   
 
diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml
index 99a94ebbe..d96560b30 100644
--- a/http-generator-jex/pom.xml
+++ b/http-generator-jex/pom.xml
@@ -7,7 +7,7 @@
   
     io.avaje
     avaje-http-parent
-    1.24-SNAPSHOT
+    1.23
     ..
   
 
diff --git a/http-generator-nima/pom.xml b/http-generator-nima/pom.xml
index f46fd4530..6ba4f493f 100644
--- a/http-generator-nima/pom.xml
+++ b/http-generator-nima/pom.xml
@@ -3,7 +3,7 @@
   
     avaje-http-parent
     io.avaje
-    1.24-SNAPSHOT
+    1.23
   
   4.0.0
 
diff --git a/pom.xml b/pom.xml
index d296ed315..cc647b943 100644
--- a/pom.xml
+++ b/pom.xml
@@ -9,12 +9,12 @@
 
   io.avaje
   avaje-http-parent
-  1.24-SNAPSHOT
+  1.23
   pom
 
   
     scm:git:git@github.com:avaje/avaje-http.git
-    avaje-http-parent-1.19
+    avaje-http-parent-1.23
   
 
   

From 50f7c75e7be0f7004fafc87021a1efbe246cac41 Mon Sep 17 00:00:00 2001
From: Josiah Noel <32279667+SentryMan@users.noreply.github.com>
Date: Sat, 28 Jan 2023 00:50:03 -0500
Subject: [PATCH 0555/1323] Revert "[maven-release-plugin] prepare release
 avaje-http-parent-1.23"

This reverts commit 9544536bba136d90985b9696de5ab11d203a9f39.
---
 http-api/pom.xml                 | 4 ++--
 http-client-gson-adapter/pom.xml | 6 +++---
 http-client/pom.xml              | 6 +++---
 http-generator-client/pom.xml    | 2 +-
 http-generator-core/pom.xml      | 4 ++--
 http-generator-helidon/pom.xml   | 2 +-
 http-generator-javalin/pom.xml   | 2 +-
 http-generator-jex/pom.xml       | 2 +-
 http-generator-nima/pom.xml      | 2 +-
 pom.xml                          | 4 ++--
 10 files changed, 17 insertions(+), 17 deletions(-)

diff --git a/http-api/pom.xml b/http-api/pom.xml
index 52a9da703..ebb17cb58 100644
--- a/http-api/pom.xml
+++ b/http-api/pom.xml
@@ -4,7 +4,7 @@
   
     io.avaje
     avaje-http-parent
-    1.23
+    1.23-SNAPSHOT
     ..
   
 
@@ -12,7 +12,7 @@
 
   
     scm:git:git@github.com:avaje/avaje-http.git
-    avaje-http-parent-1.23
+    avaje-http-parent-1.19
   
 
   
diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml
index 959638ce7..30148efcb 100644
--- a/http-client-gson-adapter/pom.xml
+++ b/http-client-gson-adapter/pom.xml
@@ -4,13 +4,13 @@
   
     io.avaje
     avaje-http-parent
-    1.23
+    1.23-SNAPSHOT
     ..
   
 
   io.avaje
   avaje-http-client-gson
-  1.23
+  1.23-SNAPSHOT
 
   
 
@@ -23,7 +23,7 @@
     
       io.avaje
       avaje-http-client
-      1.23
+      1.23-SNAPSHOT
       provided
     
 
diff --git a/http-client/pom.xml b/http-client/pom.xml
index b0235a85e..e21d77dab 100644
--- a/http-client/pom.xml
+++ b/http-client/pom.xml
@@ -4,17 +4,17 @@
   
     io.avaje
     avaje-http-parent
-    1.23
+    1.23-SNAPSHOT
     ..
   
 
   io.avaje
   avaje-http-client
-  1.23
+  1.23-SNAPSHOT
 
   
     scm:git:git@github.com:avaje/avaje-http-client.git
-    avaje-http-parent-1.23
+    HEAD
   
 
   
diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml
index e1d0a971b..0d209d7f5 100644
--- a/http-generator-client/pom.xml
+++ b/http-generator-client/pom.xml
@@ -5,7 +5,7 @@
   
     io.avaje
     avaje-http-parent
-    1.23
+    1.23-SNAPSHOT
     ..
   
 
diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml
index d311c3f5b..88680ff11 100644
--- a/http-generator-core/pom.xml
+++ b/http-generator-core/pom.xml
@@ -7,7 +7,7 @@
   
     io.avaje
     avaje-http-parent
-    1.23
+    1.23-SNAPSHOT
     ..
   
 
@@ -32,7 +32,7 @@
     
       io.avaje
       avaje-http-api
-      1.23
+      1.23-SNAPSHOT
     
 
     
diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml
index 57a39cc3e..dc4237ef9 100644
--- a/http-generator-helidon/pom.xml
+++ b/http-generator-helidon/pom.xml
@@ -7,7 +7,7 @@
   
     io.avaje
     avaje-http-parent
-    1.23
+    1.23-SNAPSHOT
     ..
   
 
diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml
index a61ee0e26..269b5c91e 100644
--- a/http-generator-javalin/pom.xml
+++ b/http-generator-javalin/pom.xml
@@ -7,7 +7,7 @@
   
     io.avaje
     avaje-http-parent
-    1.23
+    1.23-SNAPSHOT
     ..
   
 
diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml
index d96560b30..f90dd1410 100644
--- a/http-generator-jex/pom.xml
+++ b/http-generator-jex/pom.xml
@@ -7,7 +7,7 @@
   
     io.avaje
     avaje-http-parent
-    1.23
+    1.23-SNAPSHOT
     ..
   
 
diff --git a/http-generator-nima/pom.xml b/http-generator-nima/pom.xml
index 6ba4f493f..75339e430 100644
--- a/http-generator-nima/pom.xml
+++ b/http-generator-nima/pom.xml
@@ -3,7 +3,7 @@
   
     avaje-http-parent
     io.avaje
-    1.23
+    1.23-SNAPSHOT
   
   4.0.0
 
diff --git a/pom.xml b/pom.xml
index cc647b943..6dab42685 100644
--- a/pom.xml
+++ b/pom.xml
@@ -9,12 +9,12 @@
 
   io.avaje
   avaje-http-parent
-  1.23
+  1.23-SNAPSHOT
   pom
 
   
     scm:git:git@github.com:avaje/avaje-http.git
-    avaje-http-parent-1.23
+    avaje-http-parent-1.19
   
 
   

From 5cc3e0bf0d06d5df4cfc8f4a1b9b5fad70f8cc63 Mon Sep 17 00:00:00 2001
From: Josiah Noel <32279667+SentryMan@users.noreply.github.com>
Date: Sat, 28 Jan 2023 01:02:42 -0500
Subject: [PATCH 0556/1323] fix java types

---
 .../src/main/java/io/avaje/http/generator/core/UType.java      | 3 ++-
 .../src/main/java/io/avaje/http/generator/core/Util.java       | 2 ++
 2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java
index dfe907536..a32d97bf8 100644
--- a/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java
+++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java
@@ -202,7 +202,8 @@ public Set importTypes() {
       Set set = new LinkedHashSet<>();
       for (String type : allTypes) {
         if (!type.startsWith("java.lang.") && type.indexOf('.') > -1) {
-          set.add(innerTypesImport(type).replace("[]", ""));
+          if (type.startsWith("java")) set.add(type.replace("[]", ""));
+          else set.add(innerTypesImport(type).replace("[]", ""));
         }
       }
       return set;
diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/Util.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/Util.java
index 500b14016..0357d0850 100644
--- a/http-generator-core/src/main/java/io/avaje/http/generator/core/Util.java
+++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/Util.java
@@ -75,6 +75,8 @@ public static String shortName(String fullType) {
     int p = fullType.lastIndexOf('.');
     if (p == -1) {
       return fullType;
+    } else if (fullType.startsWith("java")) {
+      return fullType.substring(p + 1);
     } else {
       var result = "";
       var foundClass = false;

From cd70bcc62f8d56cf09e9697e78db7a61b04d68fd Mon Sep 17 00:00:00 2001
From: Josiah Noel <32279667+SentryMan@users.noreply.github.com>
Date: Sat, 28 Jan 2023 09:58:49 -0500
Subject: [PATCH 0557/1323] Update UType.java

---
 .../src/main/java/io/avaje/http/generator/core/UType.java     | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java
index a32d97bf8..ad822fadd 100644
--- a/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java
+++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java
@@ -132,7 +132,7 @@ public String shortType() {
 
     @Override
     public String shortName() {
-      return Util.initLower(shortType());
+      return Util.initLower(shortType()).replace(".", "$");
     }
 
     @Override
@@ -256,7 +256,7 @@ public String shortType() {
 
     @Override
     public String shortName() {
-      return shortName;
+      return shortName.replace(".", "$");
     }
 
     @Override

From 206988956b6cebee7e376b955058b4af49db506b Mon Sep 17 00:00:00 2001
From: Josiah Noel <32279667+SentryMan@users.noreply.github.com>
Date: Sat, 28 Jan 2023 10:11:07 -0500
Subject: [PATCH 0558/1323] tests

---
 .../org/example/myapp/web/test/Outer1.java    | 26 +++++++++++++++++++
 .../org/example/myapp/web/test/Outer2.java    | 26 +++++++++++++++++++
 .../myapp/web/test/TestController.java        | 18 ++++++++++---
 3 files changed, 67 insertions(+), 3 deletions(-)
 create mode 100644 tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/Outer1.java
 create mode 100644 tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/Outer2.java

diff --git a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/Outer1.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/Outer1.java
new file mode 100644
index 000000000..76563e50a
--- /dev/null
+++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/Outer1.java
@@ -0,0 +1,26 @@
+package org.example.myapp.web.test;
+
+import io.avaje.jsonb.Json;
+
+public interface Outer1 {
+
+  @Json
+  class State {
+
+    private String field;
+
+    public State() {}
+
+    public String getField() {
+      return field;
+    }
+
+    public void setField(String field) {
+      this.field = field;
+    }
+
+    public State(final String field) {
+      this.field = field;
+    }
+  }
+}
diff --git a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/Outer2.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/Outer2.java
new file mode 100644
index 000000000..42d75abb4
--- /dev/null
+++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/Outer2.java
@@ -0,0 +1,26 @@
+package org.example.myapp.web.test;
+
+import io.avaje.jsonb.Json;
+
+public interface Outer2 {
+
+  @Json
+  class State {
+
+    private String field;
+
+    public State() {}
+
+    public String getField() {
+      return field;
+    }
+
+    public void setField(String field) {
+      this.field = field;
+    }
+
+    public State(final String field) {
+      this.field = field;
+    }
+  }
+}
diff --git a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController.java
index eec28ffcc..1c99baccb 100644
--- a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController.java
+++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController.java
@@ -8,12 +8,12 @@
 import io.avaje.http.api.Form;
 import io.avaje.http.api.Get;
 import io.avaje.http.api.Header;
+import io.avaje.http.api.MatrixParam;
 import io.avaje.http.api.MediaType;
 import io.avaje.http.api.Path;
 import io.avaje.http.api.Post;
 import io.avaje.http.api.Produces;
 import io.avaje.http.api.Put;
-import io.avaje.http.api.MatrixParam;
 import io.javalin.http.Context;
 
 @Path("test/")
@@ -107,7 +107,7 @@ String testForm(String name, String email, String url) {
   String testFormBean(MyForm form) {
     return form.name + "|" + form.email + "|" + form.url;
   }
-  
+
   @Get("/withMatrixParam/{type-1;category;vendor-34}/{range;style}")
   void neo(
       @MatrixParam("type-1") String type,
@@ -116,6 +116,18 @@ void neo(
       String range,
       String style) {
 
-	System.out.println("Ever have that feeling where you're not sure if you're awake or dreaming?");
+    System.out.println("Ever have that feeling where you're not sure if you're awake or dreaming?");
+  }
+
+  @Post("/outer1/state")
+  List testInnerClass(Outer1.State state) {
+
+    return List.of(state);
+  }
+
+  @Get("/outer2/state")
+  Outer2.State testInnerClass2() {
+
+    return new Outer2.State();
   }
 }

From 3da25aa5af15cfa6ad472c04f032eda3d43b4add Mon Sep 17 00:00:00 2001
From: Josiah Noel <32279667+SentryMan@users.noreply.github.com>
Date: Sun, 29 Jan 2023 15:04:09 -0500
Subject: [PATCH 0559/1323] Revert "[maven-release-plugin] prepare for next
 development iteration"

This reverts commit 09e3c79f19197f939573d1e8a5e1e7253d8423b1.
---
 http-api/pom.xml                 | 4 ++--
 http-client-gson-adapter/pom.xml | 6 +++---
 http-client/pom.xml              | 6 +++---
 http-generator-client/pom.xml    | 2 +-
 http-generator-core/pom.xml      | 4 ++--
 http-generator-helidon/pom.xml   | 2 +-
 http-generator-javalin/pom.xml   | 2 +-
 http-generator-jex/pom.xml       | 2 +-
 http-generator-nima/pom.xml      | 2 +-
 pom.xml                          | 4 ++--
 10 files changed, 17 insertions(+), 17 deletions(-)

diff --git a/http-api/pom.xml b/http-api/pom.xml
index 948b79898..52a9da703 100644
--- a/http-api/pom.xml
+++ b/http-api/pom.xml
@@ -4,7 +4,7 @@
   
     io.avaje
     avaje-http-parent
-    1.24-SNAPSHOT
+    1.23
     ..
   
 
@@ -12,7 +12,7 @@
 
   
     scm:git:git@github.com:avaje/avaje-http.git
-    avaje-http-parent-1.19
+    avaje-http-parent-1.23
   
 
   
diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml
index f9cd26e71..959638ce7 100644
--- a/http-client-gson-adapter/pom.xml
+++ b/http-client-gson-adapter/pom.xml
@@ -4,13 +4,13 @@
   
     io.avaje
     avaje-http-parent
-    1.24-SNAPSHOT
+    1.23
     ..
   
 
   io.avaje
   avaje-http-client-gson
-  1.24-SNAPSHOT
+  1.23
 
   
 
@@ -23,7 +23,7 @@
     
       io.avaje
       avaje-http-client
-      1.24-SNAPSHOT
+      1.23
       provided
     
 
diff --git a/http-client/pom.xml b/http-client/pom.xml
index 9704a96da..b0235a85e 100644
--- a/http-client/pom.xml
+++ b/http-client/pom.xml
@@ -4,17 +4,17 @@
   
     io.avaje
     avaje-http-parent
-    1.24-SNAPSHOT
+    1.23
     ..
   
 
   io.avaje
   avaje-http-client
-  1.24-SNAPSHOT
+  1.23
 
   
     scm:git:git@github.com:avaje/avaje-http-client.git
-    HEAD
+    avaje-http-parent-1.23
   
 
   
diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml
index 0fb4cba5c..e1d0a971b 100644
--- a/http-generator-client/pom.xml
+++ b/http-generator-client/pom.xml
@@ -5,7 +5,7 @@
   
     io.avaje
     avaje-http-parent
-    1.24-SNAPSHOT
+    1.23
     ..
   
 
diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml
index 03db45019..d311c3f5b 100644
--- a/http-generator-core/pom.xml
+++ b/http-generator-core/pom.xml
@@ -7,7 +7,7 @@
   
     io.avaje
     avaje-http-parent
-    1.24-SNAPSHOT
+    1.23
     ..
   
 
@@ -32,7 +32,7 @@
     
       io.avaje
       avaje-http-api
-      1.24-SNAPSHOT
+      1.23
     
 
     
diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml
index c6430fa62..57a39cc3e 100644
--- a/http-generator-helidon/pom.xml
+++ b/http-generator-helidon/pom.xml
@@ -7,7 +7,7 @@
   
     io.avaje
     avaje-http-parent
-    1.24-SNAPSHOT
+    1.23
     ..
   
 
diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml
index 993dff58d..a61ee0e26 100644
--- a/http-generator-javalin/pom.xml
+++ b/http-generator-javalin/pom.xml
@@ -7,7 +7,7 @@
   
     io.avaje
     avaje-http-parent
-    1.24-SNAPSHOT
+    1.23
     ..
   
 
diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml
index 99a94ebbe..d96560b30 100644
--- a/http-generator-jex/pom.xml
+++ b/http-generator-jex/pom.xml
@@ -7,7 +7,7 @@
   
     io.avaje
     avaje-http-parent
-    1.24-SNAPSHOT
+    1.23
     ..
   
 
diff --git a/http-generator-nima/pom.xml b/http-generator-nima/pom.xml
index f46fd4530..6ba4f493f 100644
--- a/http-generator-nima/pom.xml
+++ b/http-generator-nima/pom.xml
@@ -3,7 +3,7 @@
   
     avaje-http-parent
     io.avaje
-    1.24-SNAPSHOT
+    1.23
   
   4.0.0
 
diff --git a/pom.xml b/pom.xml
index d296ed315..cc647b943 100644
--- a/pom.xml
+++ b/pom.xml
@@ -9,12 +9,12 @@
 
   io.avaje
   avaje-http-parent
-  1.24-SNAPSHOT
+  1.23
   pom
 
   
     scm:git:git@github.com:avaje/avaje-http.git
-    avaje-http-parent-1.19
+    avaje-http-parent-1.23
   
 
   

From 6c9a69d401d1fa231d98a1527aacbfad90ba850c Mon Sep 17 00:00:00 2001
From: Josiah Noel <32279667+SentryMan@users.noreply.github.com>
Date: Sun, 29 Jan 2023 15:04:13 -0500
Subject: [PATCH 0560/1323] Revert "[maven-release-plugin] prepare release
 avaje-http-parent-1.23"

This reverts commit 9544536bba136d90985b9696de5ab11d203a9f39.
---
 http-api/pom.xml                 | 4 ++--
 http-client-gson-adapter/pom.xml | 6 +++---
 http-client/pom.xml              | 6 +++---
 http-generator-client/pom.xml    | 2 +-
 http-generator-core/pom.xml      | 4 ++--
 http-generator-helidon/pom.xml   | 2 +-
 http-generator-javalin/pom.xml   | 2 +-
 http-generator-jex/pom.xml       | 2 +-
 http-generator-nima/pom.xml      | 2 +-
 pom.xml                          | 4 ++--
 10 files changed, 17 insertions(+), 17 deletions(-)

diff --git a/http-api/pom.xml b/http-api/pom.xml
index 52a9da703..ebb17cb58 100644
--- a/http-api/pom.xml
+++ b/http-api/pom.xml
@@ -4,7 +4,7 @@
   
     io.avaje
     avaje-http-parent
-    1.23
+    1.23-SNAPSHOT
     ..
   
 
@@ -12,7 +12,7 @@
 
   
     scm:git:git@github.com:avaje/avaje-http.git
-    avaje-http-parent-1.23
+    avaje-http-parent-1.19
   
 
   
diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml
index 959638ce7..30148efcb 100644
--- a/http-client-gson-adapter/pom.xml
+++ b/http-client-gson-adapter/pom.xml
@@ -4,13 +4,13 @@
   
     io.avaje
     avaje-http-parent
-    1.23
+    1.23-SNAPSHOT
     ..
   
 
   io.avaje
   avaje-http-client-gson
-  1.23
+  1.23-SNAPSHOT
 
   
 
@@ -23,7 +23,7 @@
     
       io.avaje
       avaje-http-client
-      1.23
+      1.23-SNAPSHOT
       provided
     
 
diff --git a/http-client/pom.xml b/http-client/pom.xml
index b0235a85e..e21d77dab 100644
--- a/http-client/pom.xml
+++ b/http-client/pom.xml
@@ -4,17 +4,17 @@
   
     io.avaje
     avaje-http-parent
-    1.23
+    1.23-SNAPSHOT
     ..
   
 
   io.avaje
   avaje-http-client
-  1.23
+  1.23-SNAPSHOT
 
   
     scm:git:git@github.com:avaje/avaje-http-client.git
-    avaje-http-parent-1.23
+    HEAD
   
 
   
diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml
index e1d0a971b..0d209d7f5 100644
--- a/http-generator-client/pom.xml
+++ b/http-generator-client/pom.xml
@@ -5,7 +5,7 @@
   
     io.avaje
     avaje-http-parent
-    1.23
+    1.23-SNAPSHOT
     ..
   
 
diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml
index d311c3f5b..88680ff11 100644
--- a/http-generator-core/pom.xml
+++ b/http-generator-core/pom.xml
@@ -7,7 +7,7 @@
   
     io.avaje
     avaje-http-parent
-    1.23
+    1.23-SNAPSHOT
     ..
   
 
@@ -32,7 +32,7 @@
     
       io.avaje
       avaje-http-api
-      1.23
+      1.23-SNAPSHOT
     
 
     
diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml
index 57a39cc3e..dc4237ef9 100644
--- a/http-generator-helidon/pom.xml
+++ b/http-generator-helidon/pom.xml
@@ -7,7 +7,7 @@
   
     io.avaje
     avaje-http-parent
-    1.23
+    1.23-SNAPSHOT
     ..
   
 
diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml
index a61ee0e26..269b5c91e 100644
--- a/http-generator-javalin/pom.xml
+++ b/http-generator-javalin/pom.xml
@@ -7,7 +7,7 @@
   
     io.avaje
     avaje-http-parent
-    1.23
+    1.23-SNAPSHOT
     ..
   
 
diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml
index d96560b30..f90dd1410 100644
--- a/http-generator-jex/pom.xml
+++ b/http-generator-jex/pom.xml
@@ -7,7 +7,7 @@
   
     io.avaje
     avaje-http-parent
-    1.23
+    1.23-SNAPSHOT
     ..
   
 
diff --git a/http-generator-nima/pom.xml b/http-generator-nima/pom.xml
index 6ba4f493f..75339e430 100644
--- a/http-generator-nima/pom.xml
+++ b/http-generator-nima/pom.xml
@@ -3,7 +3,7 @@
   
     avaje-http-parent
     io.avaje
-    1.23
+    1.23-SNAPSHOT
   
   4.0.0
 
diff --git a/pom.xml b/pom.xml
index cc647b943..6dab42685 100644
--- a/pom.xml
+++ b/pom.xml
@@ -9,12 +9,12 @@
 
   io.avaje
   avaje-http-parent
-  1.23
+  1.23-SNAPSHOT
   pom
 
   
     scm:git:git@github.com:avaje/avaje-http.git
-    avaje-http-parent-1.23
+    avaje-http-parent-1.19
   
 
   

From 06afc9e08cc183eecd38aa7ca96c6640b6eb95dd Mon Sep 17 00:00:00 2001
From: Josiah Noel <32279667+SentryMan@users.noreply.github.com>
Date: Sun, 29 Jan 2023 15:17:43 -0500
Subject: [PATCH 0561/1323] produces default status code

---
 .../main/java/io/avaje/http/api/Produces.java | 23 ++++++++++--
 .../http/generator/core/MethodReader.java     | 21 ++++++-----
 .../core/openapi/MethodDocBuilder.java        |  3 +-
 .../myapp/web/test/OpenAPIController.java     | 14 ++++++++
 .../src/test/resources/expectedOpenApi.json   | 35 +++++++++++++++++--
 5 files changed, 81 insertions(+), 15 deletions(-)

diff --git a/http-api/src/main/java/io/avaje/http/api/Produces.java b/http-api/src/main/java/io/avaje/http/api/Produces.java
index 137edadd7..de0aa3bcf 100644
--- a/http-api/src/main/java/io/avaje/http/api/Produces.java
+++ b/http-api/src/main/java/io/avaje/http/api/Produces.java
@@ -24,9 +24,26 @@
  *
  * }
*/ -@Target(value={TYPE, METHOD}) -@Retention(value=RUNTIME) +@Target(value = {TYPE, METHOD}) +@Retention(value = RUNTIME) public @interface Produces { - String value(); + /** + * Specify response media type. + * + *

When not specified the default MediaType is APPLICATION_JSON + */ + String value() default MediaType.APPLICATION_JSON; + + /** + * The default status code of the generated route. + * + *

When not specified, the default status are as follows:
+ * GET(200)
+ * POST(201)
+ * PUT(200, void methods 204)
+ * PATCH(200, void methods 204)
+ * DELETE(200, void methods 204) + */ + int defaultStatus() default 0; } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java index c49348237..be90bf40d 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java @@ -34,7 +34,7 @@ public class MethodReader { * Holds enum Roles that are required for the method. */ private final List methodRoles; - private final String produces; + private final Optional producesAnnotation; private final List apiResponses; private final ExecutableType actualExecutable; private final List actualParams; @@ -54,7 +54,7 @@ public class MethodReader { this.actualParams = (actualExecutable == null) ? null : actualExecutable.getParameterTypes(); this.isVoid = element.getReturnType().getKind() == TypeKind.VOID; this.methodRoles = Util.findRoles(element); - this.produces = produces(bean); + this.producesAnnotation = Optional.ofNullable(findAnnotation(Produces.class)); initWebMethodViaAnnotation(); this.superMethods = ctx.superMethods(element.getEnclosingElement(), element.getSimpleName().toString()); @@ -151,11 +151,6 @@ public Javadoc javadoc() { return javadoc; } - private String produces(ControllerReader bean) { - final var produces = findAnnotation(Produces.class); - return (produces != null) ? produces.value() : bean.produces(); - } - private List buildApiResponses() { final var container = Optional.ofNullable(findAnnotation(OpenAPIResponses.class)).stream() @@ -274,8 +269,12 @@ public boolean isVoid() { return isVoid; } + public boolean hasProducesStatus() { + return producesAnnotation.map(Produces::defaultStatus).filter(s -> s > 0).isPresent(); + } + public String produces() { - return produces; + return producesAnnotation.map(Produces::value).orElseGet(bean::produces); } public List apiResponses() { @@ -290,7 +289,11 @@ public TypeMirror returnType() { } public String statusCode() { - return Integer.toString(webMethod.statusCode(isVoid)); + + return producesAnnotation + .map(Produces::defaultStatus) + .filter(s -> s > 0) + .orElseGet(() -> webMethod.statusCode(isVoid)).toString(); } public PathSegments pathSegments() { diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/MethodDocBuilder.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/MethodDocBuilder.java index 8f13ae663..16ee29c34 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/MethodDocBuilder.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/MethodDocBuilder.java @@ -77,6 +77,7 @@ public void build() { response.setDescription(javadoc.getReturnDescription()); final var produces = methodReader.produces(); + final var hasProducesStatus = methodReader.hasProducesStatus(); final var contentMediaType = (produces == null) ? MediaType.APPLICATION_JSON : produces; if (methodReader.isVoid()) { @@ -99,7 +100,7 @@ public void build() { // if user wants to define their own 2xx status code if (responseAnnotation.responseCode().startsWith("2")) { newResponse.setContent(response.getContent()); - override2xx = true; + override2xx = !hasProducesStatus; } TypeMirror returnType = null; try { diff --git a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/OpenAPIController.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/OpenAPIController.java index 98a89cd12..43ea696d6 100644 --- a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/OpenAPIController.java +++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/OpenAPIController.java @@ -10,6 +10,7 @@ import io.avaje.http.api.Path; import io.avaje.http.api.Post; import io.avaje.http.api.Produces; +import io.avaje.http.api.Put; import io.javalin.http.Context; import io.swagger.v3.oas.annotations.OpenAPIDefinition; import io.swagger.v3.oas.annotations.info.Info; @@ -78,4 +79,17 @@ Person testPostl(List m) { return new Person(0, "baby"); } + + @Put("/put") + @Produces(value = MediaType.TEXT_PLAIN, defaultStatus = 203) + @OpenAPIResponse(responseCode = "204", type = String.class) + String testDefaultStatus(Context ctx) { + + if (ctx.contentType().equals(MediaType.APPLICATION_PDF)) { + ctx.status(204); + return ""; + } + + return "only partial info"; + } } diff --git a/tests/test-javalin-jsonb/src/test/resources/expectedOpenApi.json b/tests/test-javalin-jsonb/src/test/resources/expectedOpenApi.json index 0648f7a2f..14772e3e7 100644 --- a/tests/test-javalin-jsonb/src/test/resources/expectedOpenApi.json +++ b/tests/test-javalin-jsonb/src/test/resources/expectedOpenApi.json @@ -132,8 +132,39 @@ }, "deprecated": true } - } - }, + }, + "/openapi/put" : { + "put" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "responses" : { + "204" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + }, + "203" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + } + }, "components": { "schemas": { "ErrorResponse": { From 0cdf17a71d92e5eefc6cf44df34e6f8a85e55cd5 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Mon, 30 Jan 2023 10:54:08 -0500 Subject: [PATCH 0562/1323] Update pom.xml --- tests/test-javalin-jsonb/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index ba1adaff5..6457fcf85 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -81,7 +81,7 @@ io.avaje avaje-jsonb-generator - 1.1 + 1.2 provided From f87043f8ae6d13ac751f5ab612063cae0a46e538 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Mon, 30 Jan 2023 11:23:39 -0500 Subject: [PATCH 0563/1323] In hindsight this is tested with the nested class tests --- tests/test-javalin-jsonb/pom.xml | 2 +- .../org/example/myapp/web/test/Outer1.java | 26 ------------------- .../org/example/myapp/web/test/Outer2.java | 26 ------------------- .../myapp/web/test/TestController.java | 18 +++---------- 4 files changed, 4 insertions(+), 68 deletions(-) delete mode 100644 tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/Outer1.java delete mode 100644 tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/Outer2.java diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 6457fcf85..ba1adaff5 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -81,7 +81,7 @@ io.avaje avaje-jsonb-generator - 1.2 + 1.1 provided diff --git a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/Outer1.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/Outer1.java deleted file mode 100644 index 76563e50a..000000000 --- a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/Outer1.java +++ /dev/null @@ -1,26 +0,0 @@ -package org.example.myapp.web.test; - -import io.avaje.jsonb.Json; - -public interface Outer1 { - - @Json - class State { - - private String field; - - public State() {} - - public String getField() { - return field; - } - - public void setField(String field) { - this.field = field; - } - - public State(final String field) { - this.field = field; - } - } -} diff --git a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/Outer2.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/Outer2.java deleted file mode 100644 index 42d75abb4..000000000 --- a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/Outer2.java +++ /dev/null @@ -1,26 +0,0 @@ -package org.example.myapp.web.test; - -import io.avaje.jsonb.Json; - -public interface Outer2 { - - @Json - class State { - - private String field; - - public State() {} - - public String getField() { - return field; - } - - public void setField(String field) { - this.field = field; - } - - public State(final String field) { - this.field = field; - } - } -} diff --git a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController.java index 1c99baccb..eec28ffcc 100644 --- a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController.java +++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController.java @@ -8,12 +8,12 @@ import io.avaje.http.api.Form; import io.avaje.http.api.Get; import io.avaje.http.api.Header; -import io.avaje.http.api.MatrixParam; import io.avaje.http.api.MediaType; import io.avaje.http.api.Path; import io.avaje.http.api.Post; import io.avaje.http.api.Produces; import io.avaje.http.api.Put; +import io.avaje.http.api.MatrixParam; import io.javalin.http.Context; @Path("test/") @@ -107,7 +107,7 @@ String testForm(String name, String email, String url) { String testFormBean(MyForm form) { return form.name + "|" + form.email + "|" + form.url; } - + @Get("/withMatrixParam/{type-1;category;vendor-34}/{range;style}") void neo( @MatrixParam("type-1") String type, @@ -116,18 +116,6 @@ void neo( String range, String style) { - System.out.println("Ever have that feeling where you're not sure if you're awake or dreaming?"); - } - - @Post("/outer1/state") - List testInnerClass(Outer1.State state) { - - return List.of(state); - } - - @Get("/outer2/state") - Outer2.State testInnerClass2() { - - return new Outer2.State(); + System.out.println("Ever have that feeling where you're not sure if you're awake or dreaming?"); } } From 17b07235ab26aca94a297bd21b8138afa4857f9d Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Wed, 1 Feb 2023 10:34:28 +1300 Subject: [PATCH 0564/1323] No effective change - tidy UType and MethodReader --- .../http/generator/core/MethodReader.java | 2 -- .../io/avaje/http/generator/core/UType.java | 8 +++-- .../src/main/resources/public/openapi.json | 31 +++++++++++++++++++ 3 files changed, 36 insertions(+), 5 deletions(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java index 793a81d2f..44e2a1291 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java @@ -211,7 +211,6 @@ void read() { if (!methodRoles.isEmpty()) { ctx.platform().methodRoles(methodRoles, bean); } - // non-path parameters default to form or query parameters based on the // existence of @Form annotation on the method ParamType defaultParamType = (formMarker) ? ParamType.FORMPARAM : ParamType.QUERYPARAM; @@ -290,7 +289,6 @@ public TypeMirror returnType() { } public String statusCode() { - return producesAnnotation .map(Produces::defaultStatus) .filter(s -> s > 0) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java index ad822fadd..43b9c4bf1 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java @@ -202,15 +202,17 @@ public Set importTypes() { Set set = new LinkedHashSet<>(); for (String type : allTypes) { if (!type.startsWith("java.lang.") && type.indexOf('.') > -1) { - if (type.startsWith("java")) set.add(type.replace("[]", "")); - else set.add(innerTypesImport(type).replace("[]", "")); + if (type.startsWith("java")) { + set.add(type.replace("[]", "")); + } else { + set.add(innerTypesImport(type).replace("[]", "")); + } } } return set; } public String innerTypesImport(String type) { - final var parts = type.split("\\."); var result = ""; var foundUpper = false; diff --git a/tests/test-javalin-jsonb/src/main/resources/public/openapi.json b/tests/test-javalin-jsonb/src/main/resources/public/openapi.json index 8d00293ff..f783e17ec 100644 --- a/tests/test-javalin-jsonb/src/main/resources/public/openapi.json +++ b/tests/test-javalin-jsonb/src/main/resources/public/openapi.json @@ -924,6 +924,37 @@ "deprecated" : true } }, + "/openapi/put" : { + "put" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "responses" : { + "204" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + }, + "203" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, "/req-scoped" : { "get" : { "tags" : [ From 7ce120480bf5359d58ff99e3087a5375865c5580 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Wed, 1 Feb 2023 10:35:44 +1300 Subject: [PATCH 0565/1323] Bump back up to 1.24-SNAPSHOT --- http-api/pom.xml | 2 +- http-client-gson-adapter/pom.xml | 6 +++--- http-client/pom.xml | 4 ++-- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 4 ++-- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-generator-nima/pom.xml | 2 +- pom.xml | 2 +- tests/test-client-generation/pom.xml | 8 ++++---- tests/test-client/pom.xml | 6 +++--- tests/test-helidon/pom.xml | 8 ++++---- tests/test-javalin-jsonb/pom.xml | 6 +++--- tests/test-javalin/pom.xml | 6 +++--- tests/test-jex/pom.xml | 6 +++--- tests/test-nima-jsonb/.factorypath | 2 +- tests/test-nima-jsonb/pom.xml | 6 +++--- tests/test-nima/pom.xml | 4 ++-- 19 files changed, 40 insertions(+), 40 deletions(-) diff --git a/http-api/pom.xml b/http-api/pom.xml index ebb17cb58..948b79898 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.23-SNAPSHOT + 1.24-SNAPSHOT .. diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index 30148efcb..f9cd26e71 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,13 +4,13 @@ io.avaje avaje-http-parent - 1.23-SNAPSHOT + 1.24-SNAPSHOT .. io.avaje avaje-http-client-gson - 1.23-SNAPSHOT + 1.24-SNAPSHOT @@ -23,7 +23,7 @@ io.avaje avaje-http-client - 1.23-SNAPSHOT + 1.24-SNAPSHOT provided diff --git a/http-client/pom.xml b/http-client/pom.xml index e21d77dab..9704a96da 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,13 +4,13 @@ io.avaje avaje-http-parent - 1.23-SNAPSHOT + 1.24-SNAPSHOT .. io.avaje avaje-http-client - 1.23-SNAPSHOT + 1.24-SNAPSHOT scm:git:git@github.com:avaje/avaje-http-client.git diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index 0d209d7f5..0fb4cba5c 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -5,7 +5,7 @@ io.avaje avaje-http-parent - 1.23-SNAPSHOT + 1.24-SNAPSHOT .. diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 88680ff11..03db45019 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-parent - 1.23-SNAPSHOT + 1.24-SNAPSHOT .. @@ -32,7 +32,7 @@ io.avaje avaje-http-api - 1.23-SNAPSHOT + 1.24-SNAPSHOT diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index dc4237ef9..c6430fa62 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-parent - 1.23-SNAPSHOT + 1.24-SNAPSHOT .. diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index 269b5c91e..993dff58d 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-parent - 1.23-SNAPSHOT + 1.24-SNAPSHOT .. diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index f90dd1410..99a94ebbe 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-parent - 1.23-SNAPSHOT + 1.24-SNAPSHOT .. diff --git a/http-generator-nima/pom.xml b/http-generator-nima/pom.xml index 75339e430..f46fd4530 100644 --- a/http-generator-nima/pom.xml +++ b/http-generator-nima/pom.xml @@ -3,7 +3,7 @@ avaje-http-parent io.avaje - 1.23-SNAPSHOT + 1.24-SNAPSHOT 4.0.0 diff --git a/pom.xml b/pom.xml index 6dab42685..d296ed315 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-parent - 1.23-SNAPSHOT + 1.24-SNAPSHOT pom diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index e24e2565b..57798c659 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -24,13 +24,13 @@ io.avaje avaje-http-client - 1.23-SNAPSHOT + 1.24-SNAPSHOT io.avaje avaje-http-api - 1.23-SNAPSHOT + 1.24-SNAPSHOT @@ -102,12 +102,12 @@ io.avaje avaje-http-client-generator - 1.23-SNAPSHOT + 1.24-SNAPSHOT io.avaje avaje-http-jex-generator - 1.23-SNAPSHOT + 1.24-SNAPSHOT io.avaje diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index 8db7725d5..1541b9da4 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -21,19 +21,19 @@ io.avaje avaje-http-client - 1.23-SNAPSHOT + 1.24-SNAPSHOT io.avaje avaje-http-client-gson - 1.23-SNAPSHOT + 1.24-SNAPSHOT io.avaje avaje-http-api - 1.23-SNAPSHOT + 1.24-SNAPSHOT diff --git a/tests/test-helidon/pom.xml b/tests/test-helidon/pom.xml index b0d9484e8..671b618f8 100644 --- a/tests/test-helidon/pom.xml +++ b/tests/test-helidon/pom.xml @@ -13,7 +13,7 @@ true org.example.Main 2.3.0 - 1.23-SNAPSHOT + 1.24-SNAPSHOT @@ -33,7 +33,7 @@ io.avaje avaje-http-api - 1.23-SNAPSHOT + 1.24-SNAPSHOT io.avaje @@ -50,7 +50,7 @@ io.avaje avaje-http-helidon-generator - 1.23-SNAPSHOT + 1.24-SNAPSHOT provided @@ -112,7 +112,7 @@ io.avaje avaje-http-client - 1.23-SNAPSHOT + 1.24-SNAPSHOT test diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index ba1adaff5..543ac7f35 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -47,7 +47,7 @@ io.avaje avaje-http-api - 1.23-SNAPSHOT + 1.24-SNAPSHOT @@ -74,7 +74,7 @@ io.avaje avaje-http-javalin-generator - 1.23-SNAPSHOT + 1.24-SNAPSHOT provided @@ -103,7 +103,7 @@ io.avaje avaje-http-client - 1.23-SNAPSHOT + 1.24-SNAPSHOT test diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 12176fe4b..7b04bf4b6 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -52,7 +52,7 @@ io.avaje avaje-http-api - 1.23-SNAPSHOT + 1.24-SNAPSHOT @@ -79,7 +79,7 @@ io.avaje avaje-http-javalin-generator - 1.23-SNAPSHOT + 1.24-SNAPSHOT provided @@ -102,7 +102,7 @@ io.avaje avaje-http-client - 1.23-SNAPSHOT + 1.24-SNAPSHOT test diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index a5e7413df..4425dbc4e 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -51,7 +51,7 @@ io.avaje avaje-http-api - 1.23-SNAPSHOT + 1.24-SNAPSHOT @@ -78,7 +78,7 @@ io.avaje avaje-http-jex-generator - 1.23-SNAPSHOT + 1.24-SNAPSHOT provided @@ -94,7 +94,7 @@ io.avaje avaje-http-client - 1.23-SNAPSHOT + 1.24-SNAPSHOT test diff --git a/tests/test-nima-jsonb/.factorypath b/tests/test-nima-jsonb/.factorypath index bf32270c8..38cc3fc7d 100644 --- a/tests/test-nima-jsonb/.factorypath +++ b/tests/test-nima-jsonb/.factorypath @@ -1,7 +1,7 @@ - + diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index c1138991e..f655c4962 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -26,7 +26,7 @@ io.avaje avaje-http-api - 1.23-SNAPSHOT + 1.24-SNAPSHOT io.avaje @@ -46,7 +46,7 @@ io.avaje avaje-http-nima-generator - 1.23-SNAPSHOT + 1.24-SNAPSHOT test @@ -79,7 +79,7 @@ io.avaje avaje-http-nima-generator - 1.23-SNAPSHOT + 1.24-SNAPSHOT io.avaje diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index e22927091..0bd1c062e 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -28,7 +28,7 @@ io.avaje avaje-http-api - 1.23-SNAPSHOT + 1.24-SNAPSHOT io.helidon.nima.webserver @@ -65,7 +65,7 @@ io.avaje avaje-http-nima-generator - 1.23-SNAPSHOT + 1.24-SNAPSHOT io.avaje From b74cc23765429218a7e6b520ce7abdd4672da36c Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Thu, 2 Feb 2023 15:35:27 +1300 Subject: [PATCH 0566/1323] Update HelloController in test-nima with correct path parameter --- .../src/main/java/org/example/HelloController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test-nima-jsonb/src/main/java/org/example/HelloController.java b/tests/test-nima-jsonb/src/main/java/org/example/HelloController.java index 485752448..f58f0ba5b 100644 --- a/tests/test-nima-jsonb/src/main/java/org/example/HelloController.java +++ b/tests/test-nima-jsonb/src/main/java/org/example/HelloController.java @@ -60,7 +60,7 @@ Person person(String name) { return new Person(42, name + " hello"); } - @Get("person/{long}") + @Get("person/{id}") Person testLong(long id) { return new Person(id, "Giorno hello"); } From d1154a0567d16e7702e769d60f9c0bdd7c525c2b Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Thu, 2 Feb 2023 15:36:36 +1300 Subject: [PATCH 0567/1323] [maven-release-plugin] prepare release avaje-http-parent-1.24 --- http-api/pom.xml | 4 ++-- http-client-gson-adapter/pom.xml | 6 +++--- http-client/pom.xml | 6 +++--- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 4 ++-- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-generator-nima/pom.xml | 2 +- pom.xml | 4 ++-- 10 files changed, 17 insertions(+), 17 deletions(-) diff --git a/http-api/pom.xml b/http-api/pom.xml index 948b79898..3a1e0e167 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.24-SNAPSHOT + 1.24 .. @@ -12,7 +12,7 @@ scm:git:git@github.com:avaje/avaje-http.git - avaje-http-parent-1.19 + avaje-http-parent-1.24 diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index f9cd26e71..579ba7f16 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,13 +4,13 @@ io.avaje avaje-http-parent - 1.24-SNAPSHOT + 1.24 .. io.avaje avaje-http-client-gson - 1.24-SNAPSHOT + 1.24 @@ -23,7 +23,7 @@ io.avaje avaje-http-client - 1.24-SNAPSHOT + 1.24 provided diff --git a/http-client/pom.xml b/http-client/pom.xml index 9704a96da..3e0d60372 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,17 +4,17 @@ io.avaje avaje-http-parent - 1.24-SNAPSHOT + 1.24 .. io.avaje avaje-http-client - 1.24-SNAPSHOT + 1.24 scm:git:git@github.com:avaje/avaje-http-client.git - HEAD + avaje-http-parent-1.24 diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index 0fb4cba5c..1502c8522 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -5,7 +5,7 @@ io.avaje avaje-http-parent - 1.24-SNAPSHOT + 1.24 .. diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 03db45019..627119e56 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-parent - 1.24-SNAPSHOT + 1.24 .. @@ -32,7 +32,7 @@ io.avaje avaje-http-api - 1.24-SNAPSHOT + 1.24 diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index c6430fa62..5effea7d0 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-parent - 1.24-SNAPSHOT + 1.24 .. diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index 993dff58d..d2021cabf 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-parent - 1.24-SNAPSHOT + 1.24 .. diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index 99a94ebbe..45bd595ca 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-parent - 1.24-SNAPSHOT + 1.24 .. diff --git a/http-generator-nima/pom.xml b/http-generator-nima/pom.xml index f46fd4530..91f15a8fa 100644 --- a/http-generator-nima/pom.xml +++ b/http-generator-nima/pom.xml @@ -3,7 +3,7 @@ avaje-http-parent io.avaje - 1.24-SNAPSHOT + 1.24 4.0.0 diff --git a/pom.xml b/pom.xml index d296ed315..09af17820 100644 --- a/pom.xml +++ b/pom.xml @@ -9,12 +9,12 @@ io.avaje avaje-http-parent - 1.24-SNAPSHOT + 1.24 pom scm:git:git@github.com:avaje/avaje-http.git - avaje-http-parent-1.19 + avaje-http-parent-1.24 From 6ff5eb6f8e6f0e771057eee1fe9c883a8518356a Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Thu, 2 Feb 2023 15:37:06 +1300 Subject: [PATCH 0568/1323] [maven-release-plugin] prepare for next development iteration --- http-api/pom.xml | 4 ++-- http-client-gson-adapter/pom.xml | 6 +++--- http-client/pom.xml | 6 +++--- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 4 ++-- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-generator-nima/pom.xml | 2 +- pom.xml | 4 ++-- 10 files changed, 17 insertions(+), 17 deletions(-) diff --git a/http-api/pom.xml b/http-api/pom.xml index 3a1e0e167..6ed38e8ff 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.24 + 1.25-SNAPSHOT .. @@ -12,7 +12,7 @@ scm:git:git@github.com:avaje/avaje-http.git - avaje-http-parent-1.24 + avaje-http-parent-1.19 diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index 579ba7f16..5926d053b 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,13 +4,13 @@ io.avaje avaje-http-parent - 1.24 + 1.25-SNAPSHOT .. io.avaje avaje-http-client-gson - 1.24 + 1.25-SNAPSHOT @@ -23,7 +23,7 @@ io.avaje avaje-http-client - 1.24 + 1.25-SNAPSHOT provided diff --git a/http-client/pom.xml b/http-client/pom.xml index 3e0d60372..5e9fdedd2 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,17 +4,17 @@ io.avaje avaje-http-parent - 1.24 + 1.25-SNAPSHOT .. io.avaje avaje-http-client - 1.24 + 1.25-SNAPSHOT scm:git:git@github.com:avaje/avaje-http-client.git - avaje-http-parent-1.24 + HEAD diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index 1502c8522..162ebdb10 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -5,7 +5,7 @@ io.avaje avaje-http-parent - 1.24 + 1.25-SNAPSHOT .. diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 627119e56..d046dfd50 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-parent - 1.24 + 1.25-SNAPSHOT .. @@ -32,7 +32,7 @@ io.avaje avaje-http-api - 1.24 + 1.25-SNAPSHOT diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index 5effea7d0..45356db7b 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-parent - 1.24 + 1.25-SNAPSHOT .. diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index d2021cabf..5bd954899 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-parent - 1.24 + 1.25-SNAPSHOT .. diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index 45bd595ca..4242ddd68 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-parent - 1.24 + 1.25-SNAPSHOT .. diff --git a/http-generator-nima/pom.xml b/http-generator-nima/pom.xml index 91f15a8fa..b468bdc5c 100644 --- a/http-generator-nima/pom.xml +++ b/http-generator-nima/pom.xml @@ -3,7 +3,7 @@ avaje-http-parent io.avaje - 1.24 + 1.25-SNAPSHOT 4.0.0 diff --git a/pom.xml b/pom.xml index 09af17820..8c0f9c939 100644 --- a/pom.xml +++ b/pom.xml @@ -9,12 +9,12 @@ io.avaje avaje-http-parent - 1.24 + 1.25-SNAPSHOT pom scm:git:git@github.com:avaje/avaje-http.git - avaje-http-parent-1.24 + avaje-http-parent-1.19 From a324af1b50f1749c5e56ff3a73d3ad19fd8909f2 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Thu, 2 Feb 2023 15:49:09 +1300 Subject: [PATCH 0569/1323] Bump tests to use 1.25-SNAPSHOT after release --- tests/test-client-generation/pom.xml | 8 ++++---- tests/test-client/pom.xml | 6 +++--- tests/test-helidon/pom.xml | 8 ++++---- tests/test-javalin-jsonb/pom.xml | 6 +++--- tests/test-javalin/pom.xml | 6 +++--- tests/test-jex/pom.xml | 6 +++--- tests/test-nima-jsonb/.factorypath | 2 +- tests/test-nima-jsonb/pom.xml | 6 +++--- tests/test-nima/pom.xml | 4 ++-- 9 files changed, 26 insertions(+), 26 deletions(-) diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index 57798c659..7b279b7a7 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -24,13 +24,13 @@ io.avaje avaje-http-client - 1.24-SNAPSHOT + 1.25-SNAPSHOT io.avaje avaje-http-api - 1.24-SNAPSHOT + 1.25-SNAPSHOT @@ -102,12 +102,12 @@ io.avaje avaje-http-client-generator - 1.24-SNAPSHOT + 1.25-SNAPSHOT io.avaje avaje-http-jex-generator - 1.24-SNAPSHOT + 1.25-SNAPSHOT io.avaje diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index 1541b9da4..b66d722a6 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -21,19 +21,19 @@ io.avaje avaje-http-client - 1.24-SNAPSHOT + 1.25-SNAPSHOT io.avaje avaje-http-client-gson - 1.24-SNAPSHOT + 1.25-SNAPSHOT io.avaje avaje-http-api - 1.24-SNAPSHOT + 1.25-SNAPSHOT diff --git a/tests/test-helidon/pom.xml b/tests/test-helidon/pom.xml index 671b618f8..70b61ef09 100644 --- a/tests/test-helidon/pom.xml +++ b/tests/test-helidon/pom.xml @@ -13,7 +13,7 @@ true org.example.Main 2.3.0 - 1.24-SNAPSHOT + 1.25-SNAPSHOT @@ -33,7 +33,7 @@ io.avaje avaje-http-api - 1.24-SNAPSHOT + 1.25-SNAPSHOT io.avaje @@ -50,7 +50,7 @@ io.avaje avaje-http-helidon-generator - 1.24-SNAPSHOT + 1.25-SNAPSHOT provided @@ -112,7 +112,7 @@ io.avaje avaje-http-client - 1.24-SNAPSHOT + 1.25-SNAPSHOT test diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 543ac7f35..312e06634 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -47,7 +47,7 @@ io.avaje avaje-http-api - 1.24-SNAPSHOT + 1.25-SNAPSHOT @@ -74,7 +74,7 @@ io.avaje avaje-http-javalin-generator - 1.24-SNAPSHOT + 1.25-SNAPSHOT provided @@ -103,7 +103,7 @@ io.avaje avaje-http-client - 1.24-SNAPSHOT + 1.25-SNAPSHOT test diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 7b04bf4b6..8f0d3d3a3 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -52,7 +52,7 @@ io.avaje avaje-http-api - 1.24-SNAPSHOT + 1.25-SNAPSHOT @@ -79,7 +79,7 @@ io.avaje avaje-http-javalin-generator - 1.24-SNAPSHOT + 1.25-SNAPSHOT provided @@ -102,7 +102,7 @@ io.avaje avaje-http-client - 1.24-SNAPSHOT + 1.25-SNAPSHOT test diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 4425dbc4e..10b4a00ff 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -51,7 +51,7 @@ io.avaje avaje-http-api - 1.24-SNAPSHOT + 1.25-SNAPSHOT @@ -78,7 +78,7 @@ io.avaje avaje-http-jex-generator - 1.24-SNAPSHOT + 1.25-SNAPSHOT provided @@ -94,7 +94,7 @@ io.avaje avaje-http-client - 1.24-SNAPSHOT + 1.25-SNAPSHOT test diff --git a/tests/test-nima-jsonb/.factorypath b/tests/test-nima-jsonb/.factorypath index 38cc3fc7d..476af7334 100644 --- a/tests/test-nima-jsonb/.factorypath +++ b/tests/test-nima-jsonb/.factorypath @@ -1,7 +1,7 @@ - + diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index f655c4962..0b7e94ddf 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -26,7 +26,7 @@ io.avaje avaje-http-api - 1.24-SNAPSHOT + 1.25-SNAPSHOT io.avaje @@ -46,7 +46,7 @@ io.avaje avaje-http-nima-generator - 1.24-SNAPSHOT + 1.25-SNAPSHOT test @@ -79,7 +79,7 @@ io.avaje avaje-http-nima-generator - 1.24-SNAPSHOT + 1.25-SNAPSHOT io.avaje diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index 0bd1c062e..b7415ecf2 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -28,7 +28,7 @@ io.avaje avaje-http-api - 1.24-SNAPSHOT + 1.25-SNAPSHOT io.helidon.nima.webserver @@ -65,7 +65,7 @@ io.avaje avaje-http-nima-generator - 1.24-SNAPSHOT + 1.25-SNAPSHOT io.avaje From 52de85fab21ff272713098d500adbe764cec8a17 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Wed, 1 Feb 2023 22:55:02 -0500 Subject: [PATCH 0570/1323] fix role short names --- .../main/java/io/avaje/http/generator/core/Util.java | 4 +++- .../org/example/myapp/web/test/TestController.java | 11 ++++++++--- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/Util.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/Util.java index 0357d0850..c01bc010d 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/Util.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/Util.java @@ -75,7 +75,9 @@ public static String shortName(String fullType) { int p = fullType.lastIndexOf('.'); if (p == -1) { return fullType; - } else if (fullType.startsWith("java")) { + } else if (fullType.startsWith("java") + || fullType.contains("io.javalin.security.RouteRole") + || fullType.contains("io.avaje.jex.Role")) { return fullType.substring(p + 1); } else { var result = ""; diff --git a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController.java index eec28ffcc..fb0e2b8ce 100644 --- a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController.java +++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController.java @@ -4,20 +4,24 @@ import java.util.Map; import java.util.Set; +import org.example.myapp.web.AppRoles; +import org.example.myapp.web.Roles; + import io.avaje.http.api.Controller; import io.avaje.http.api.Form; import io.avaje.http.api.Get; import io.avaje.http.api.Header; +import io.avaje.http.api.MatrixParam; import io.avaje.http.api.MediaType; import io.avaje.http.api.Path; import io.avaje.http.api.Post; import io.avaje.http.api.Produces; import io.avaje.http.api.Put; -import io.avaje.http.api.MatrixParam; import io.javalin.http.Context; @Path("test/") @Controller +@Roles(AppRoles.ANYONE) public class TestController { @Get @@ -107,7 +111,8 @@ String testForm(String name, String email, String url) { String testFormBean(MyForm form) { return form.name + "|" + form.email + "|" + form.url; } - + + @Roles(AppRoles.ADMIN) @Get("/withMatrixParam/{type-1;category;vendor-34}/{range;style}") void neo( @MatrixParam("type-1") String type, @@ -116,6 +121,6 @@ void neo( String range, String style) { - System.out.println("Ever have that feeling where you're not sure if you're awake or dreaming?"); + System.out.println("Ever have that feeling where you're not sure if you're awake or dreaming?"); } } From 90e0907e7bcded48e0defc43563f22e86977725c Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Wed, 1 Feb 2023 23:00:57 -0500 Subject: [PATCH 0571/1323] modify generators --- .../src/main/java/io/avaje/http/generator/core/Util.java | 8 +++++--- .../http/generator/javalin/ControllerMethodWriter.java | 2 +- .../avaje/http/generator/jex/ControllerMethodWriter.java | 2 +- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/Util.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/Util.java index c01bc010d..598312099 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/Util.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/Util.java @@ -72,12 +72,14 @@ static String combinePath(String beanPath, String webMethodPath) { } public static String shortName(String fullType) { + return shortName(fullType, false); + } + + public static String shortName(String fullType, boolean role) { int p = fullType.lastIndexOf('.'); if (p == -1) { return fullType; - } else if (fullType.startsWith("java") - || fullType.contains("io.javalin.security.RouteRole") - || fullType.contains("io.avaje.jex.Role")) { + } else if (fullType.startsWith("java")||role) { return fullType.substring(p + 1); } else { var result = ""; diff --git a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java index 8be565419..2fbc09c64 100644 --- a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java +++ b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java @@ -78,7 +78,7 @@ void write(boolean requestScoped) { if (i > 0) { writer.append(", "); } - writer.append(Util.shortName(roles.get(i))); + writer.append(Util.shortName(roles.get(i), true)); } } writer.append(");").eol().eol(); diff --git a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java index 6c49eef25..0d3d88a43 100644 --- a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java +++ b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java @@ -81,7 +81,7 @@ void write(boolean requestScoped) { if (i > 0) { writer.append(", "); } - writer.append(Util.shortName(roles.get(i))); + writer.append(Util.shortName(roles.get(i), true)); } } writer.append(");").eol().eol(); From 86e9aec8eb676f1667e3622f3cf2260a0cf6da5a Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Fri, 3 Feb 2023 11:17:26 +1300 Subject: [PATCH 0572/1323] No effective change - bump tests to Nima version ALPHA4, inject 8.12-RC3 + tidy --- .../src/main/java/io/avaje/http/generator/core/Util.java | 8 +++++--- tests/pom.xml | 2 +- .../org/example/myapp/web/test/OpenAPIController.java | 5 +---- .../java/org/example/myapp/web/test/TestController.java | 1 - tests/test-nima-jsonb/pom.xml | 4 ++-- tests/test-nima/pom.xml | 5 ++--- 6 files changed, 11 insertions(+), 14 deletions(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/Util.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/Util.java index 598312099..10d8081c5 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/Util.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/Util.java @@ -8,7 +8,9 @@ import javax.lang.model.type.TypeKind; import javax.lang.model.type.TypeMirror; import javax.lang.model.util.SimpleAnnotationValueVisitor8; -import java.util.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; public class Util { @@ -38,7 +40,7 @@ public static String typeDef(TypeMirror typeMirror) { } } - public static String trimAnnotations(String type) { + public static String trimAnnotations(String type) { int pos = type.indexOf("@"); if (pos == -1) { return type; @@ -79,7 +81,7 @@ public static String shortName(String fullType, boolean role) { int p = fullType.lastIndexOf('.'); if (p == -1) { return fullType; - } else if (fullType.startsWith("java")||role) { + } else if (fullType.startsWith("java") || role) { return fullType.substring(p + 1); } else { var result = ""; diff --git a/tests/pom.xml b/tests/pom.xml index 89a3cf415..63a09d2f8 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -19,7 +19,7 @@ 3.24.1 2.14.1 2.5 - 8.12-RC1 + 8.12-RC3 diff --git a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/OpenAPIController.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/OpenAPIController.java index 43ea696d6..7fdfb03c6 100644 --- a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/OpenAPIController.java +++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/OpenAPIController.java @@ -75,8 +75,7 @@ Person testPost(Person b) { description = "Some other Error", type = ErrorResponse.class) }) - Person testPostl(List m) { - + Person testPostList(List m) { return new Person(0, "baby"); } @@ -84,12 +83,10 @@ Person testPostl(List m) { @Produces(value = MediaType.TEXT_PLAIN, defaultStatus = 203) @OpenAPIResponse(responseCode = "204", type = String.class) String testDefaultStatus(Context ctx) { - if (ctx.contentType().equals(MediaType.APPLICATION_PDF)) { ctx.status(204); return ""; } - return "only partial info"; } } diff --git a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController.java index fb0e2b8ce..8f3ce5f72 100644 --- a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController.java +++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController.java @@ -44,7 +44,6 @@ byte[] testBytes() { @Get("/ctx") void testVoid(Context ctx) { - ctx.result("success path:" + ctx.path()); } diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 0b7e94ddf..6d09f4508 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -36,12 +36,12 @@ io.helidon.nima.webserver helidon-nima-webserver - 4.0.0-ALPHA2 + 4.0.0-ALPHA4 io.helidon.nima.http.media helidon-nima-http-media-jsonb - 4.0.0-ALPHA2 + 4.0.0-ALPHA4 io.avaje diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index b7415ecf2..98ea07411 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -17,7 +17,6 @@ UTF-8 - io.avaje @@ -33,12 +32,12 @@ io.helidon.nima.webserver helidon-nima-webserver - 4.0.0-ALPHA2 + 4.0.0-ALPHA4 io.helidon.nima.http.media helidon-nima-http-media-jsonb - 4.0.0-ALPHA2 + 4.0.0-ALPHA4 From 1bdbfe2693b521342754001579a6b5ec4c9096af Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Fri, 3 Feb 2023 11:56:32 +1300 Subject: [PATCH 0573/1323] [maven-release-plugin] prepare release avaje-http-parent-1.25 --- http-api/pom.xml | 4 ++-- http-client-gson-adapter/pom.xml | 6 +++--- http-client/pom.xml | 6 +++--- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 4 ++-- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-generator-nima/pom.xml | 2 +- pom.xml | 4 ++-- 10 files changed, 17 insertions(+), 17 deletions(-) diff --git a/http-api/pom.xml b/http-api/pom.xml index 6ed38e8ff..c7411efb2 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.25-SNAPSHOT + 1.25 .. @@ -12,7 +12,7 @@ scm:git:git@github.com:avaje/avaje-http.git - avaje-http-parent-1.19 + avaje-http-parent-1.25 diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index 5926d053b..77667918a 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,13 +4,13 @@ io.avaje avaje-http-parent - 1.25-SNAPSHOT + 1.25 .. io.avaje avaje-http-client-gson - 1.25-SNAPSHOT + 1.25 @@ -23,7 +23,7 @@ io.avaje avaje-http-client - 1.25-SNAPSHOT + 1.25 provided diff --git a/http-client/pom.xml b/http-client/pom.xml index 5e9fdedd2..823fc49fb 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,17 +4,17 @@ io.avaje avaje-http-parent - 1.25-SNAPSHOT + 1.25 .. io.avaje avaje-http-client - 1.25-SNAPSHOT + 1.25 scm:git:git@github.com:avaje/avaje-http-client.git - HEAD + avaje-http-parent-1.25 diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index 162ebdb10..6ccceb9e0 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -5,7 +5,7 @@ io.avaje avaje-http-parent - 1.25-SNAPSHOT + 1.25 .. diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index d046dfd50..9ef4744bf 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-parent - 1.25-SNAPSHOT + 1.25 .. @@ -32,7 +32,7 @@ io.avaje avaje-http-api - 1.25-SNAPSHOT + 1.25 diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index 45356db7b..ff08c8cad 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-parent - 1.25-SNAPSHOT + 1.25 .. diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index 5bd954899..a37e88e6d 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-parent - 1.25-SNAPSHOT + 1.25 .. diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index 4242ddd68..b35d3491b 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-parent - 1.25-SNAPSHOT + 1.25 .. diff --git a/http-generator-nima/pom.xml b/http-generator-nima/pom.xml index b468bdc5c..60a64a395 100644 --- a/http-generator-nima/pom.xml +++ b/http-generator-nima/pom.xml @@ -3,7 +3,7 @@ avaje-http-parent io.avaje - 1.25-SNAPSHOT + 1.25 4.0.0 diff --git a/pom.xml b/pom.xml index 8c0f9c939..d5e75fd8a 100644 --- a/pom.xml +++ b/pom.xml @@ -9,12 +9,12 @@ io.avaje avaje-http-parent - 1.25-SNAPSHOT + 1.25 pom scm:git:git@github.com:avaje/avaje-http.git - avaje-http-parent-1.19 + avaje-http-parent-1.25 From d35a8d654f3f4fc7f927e7fb65f90253f2b1cad1 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Fri, 3 Feb 2023 11:57:00 +1300 Subject: [PATCH 0574/1323] [maven-release-plugin] prepare for next development iteration --- http-api/pom.xml | 4 ++-- http-client-gson-adapter/pom.xml | 6 +++--- http-client/pom.xml | 6 +++--- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 4 ++-- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-generator-nima/pom.xml | 2 +- pom.xml | 4 ++-- 10 files changed, 17 insertions(+), 17 deletions(-) diff --git a/http-api/pom.xml b/http-api/pom.xml index c7411efb2..d1b40dac6 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.25 + 1.26-SNAPSHOT .. @@ -12,7 +12,7 @@ scm:git:git@github.com:avaje/avaje-http.git - avaje-http-parent-1.25 + avaje-http-parent-1.19 diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index 77667918a..96e4950a4 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,13 +4,13 @@ io.avaje avaje-http-parent - 1.25 + 1.26-SNAPSHOT .. io.avaje avaje-http-client-gson - 1.25 + 1.26-SNAPSHOT @@ -23,7 +23,7 @@ io.avaje avaje-http-client - 1.25 + 1.26-SNAPSHOT provided diff --git a/http-client/pom.xml b/http-client/pom.xml index 823fc49fb..30641e376 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,17 +4,17 @@ io.avaje avaje-http-parent - 1.25 + 1.26-SNAPSHOT .. io.avaje avaje-http-client - 1.25 + 1.26-SNAPSHOT scm:git:git@github.com:avaje/avaje-http-client.git - avaje-http-parent-1.25 + HEAD diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index 6ccceb9e0..eec4d9e56 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -5,7 +5,7 @@ io.avaje avaje-http-parent - 1.25 + 1.26-SNAPSHOT .. diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 9ef4744bf..c138512d1 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-parent - 1.25 + 1.26-SNAPSHOT .. @@ -32,7 +32,7 @@ io.avaje avaje-http-api - 1.25 + 1.26-SNAPSHOT diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index ff08c8cad..06b61a8a1 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-parent - 1.25 + 1.26-SNAPSHOT .. diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index a37e88e6d..c5bf64295 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-parent - 1.25 + 1.26-SNAPSHOT .. diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index b35d3491b..5d49ab318 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-parent - 1.25 + 1.26-SNAPSHOT .. diff --git a/http-generator-nima/pom.xml b/http-generator-nima/pom.xml index 60a64a395..9f9732687 100644 --- a/http-generator-nima/pom.xml +++ b/http-generator-nima/pom.xml @@ -3,7 +3,7 @@ avaje-http-parent io.avaje - 1.25 + 1.26-SNAPSHOT 4.0.0 diff --git a/pom.xml b/pom.xml index d5e75fd8a..3c88fa784 100644 --- a/pom.xml +++ b/pom.xml @@ -9,12 +9,12 @@ io.avaje avaje-http-parent - 1.25 + 1.26-SNAPSHOT pom scm:git:git@github.com:avaje/avaje-http.git - avaje-http-parent-1.25 + avaje-http-parent-1.19 From 3dedf4c543c949841121b574415047149dda93be Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Fri, 3 Feb 2023 12:05:37 +1300 Subject: [PATCH 0575/1323] Bump test modules to use 1.26-SNAPSHOT after release --- tests/test-client-generation/pom.xml | 8 ++++---- tests/test-client/pom.xml | 6 +++--- tests/test-helidon/pom.xml | 8 ++++---- tests/test-javalin-jsonb/pom.xml | 6 +++--- tests/test-javalin/pom.xml | 6 +++--- tests/test-jex/pom.xml | 6 +++--- tests/test-nima-jsonb/.factorypath | 2 +- tests/test-nima-jsonb/pom.xml | 6 +++--- tests/test-nima/pom.xml | 4 ++-- 9 files changed, 26 insertions(+), 26 deletions(-) diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index 7b279b7a7..492ecaa40 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -24,13 +24,13 @@ io.avaje avaje-http-client - 1.25-SNAPSHOT + 1.26-SNAPSHOT io.avaje avaje-http-api - 1.25-SNAPSHOT + 1.26-SNAPSHOT @@ -102,12 +102,12 @@ io.avaje avaje-http-client-generator - 1.25-SNAPSHOT + 1.26-SNAPSHOT io.avaje avaje-http-jex-generator - 1.25-SNAPSHOT + 1.26-SNAPSHOT io.avaje diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index b66d722a6..6b2813bdb 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -21,19 +21,19 @@ io.avaje avaje-http-client - 1.25-SNAPSHOT + 1.26-SNAPSHOT io.avaje avaje-http-client-gson - 1.25-SNAPSHOT + 1.26-SNAPSHOT io.avaje avaje-http-api - 1.25-SNAPSHOT + 1.26-SNAPSHOT diff --git a/tests/test-helidon/pom.xml b/tests/test-helidon/pom.xml index 70b61ef09..5b66ea8e0 100644 --- a/tests/test-helidon/pom.xml +++ b/tests/test-helidon/pom.xml @@ -13,7 +13,7 @@ true org.example.Main 2.3.0 - 1.25-SNAPSHOT + 1.26-SNAPSHOT @@ -33,7 +33,7 @@ io.avaje avaje-http-api - 1.25-SNAPSHOT + 1.26-SNAPSHOT io.avaje @@ -50,7 +50,7 @@ io.avaje avaje-http-helidon-generator - 1.25-SNAPSHOT + 1.26-SNAPSHOT provided @@ -112,7 +112,7 @@ io.avaje avaje-http-client - 1.25-SNAPSHOT + 1.26-SNAPSHOT test diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 312e06634..fd476b0d5 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -47,7 +47,7 @@ io.avaje avaje-http-api - 1.25-SNAPSHOT + 1.26-SNAPSHOT @@ -74,7 +74,7 @@ io.avaje avaje-http-javalin-generator - 1.25-SNAPSHOT + 1.26-SNAPSHOT provided @@ -103,7 +103,7 @@ io.avaje avaje-http-client - 1.25-SNAPSHOT + 1.26-SNAPSHOT test diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 8f0d3d3a3..1c8e2ad48 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -52,7 +52,7 @@ io.avaje avaje-http-api - 1.25-SNAPSHOT + 1.26-SNAPSHOT @@ -79,7 +79,7 @@ io.avaje avaje-http-javalin-generator - 1.25-SNAPSHOT + 1.26-SNAPSHOT provided @@ -102,7 +102,7 @@ io.avaje avaje-http-client - 1.25-SNAPSHOT + 1.26-SNAPSHOT test diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 10b4a00ff..e71f7dae0 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -51,7 +51,7 @@ io.avaje avaje-http-api - 1.25-SNAPSHOT + 1.26-SNAPSHOT @@ -78,7 +78,7 @@ io.avaje avaje-http-jex-generator - 1.25-SNAPSHOT + 1.26-SNAPSHOT provided @@ -94,7 +94,7 @@ io.avaje avaje-http-client - 1.25-SNAPSHOT + 1.26-SNAPSHOT test diff --git a/tests/test-nima-jsonb/.factorypath b/tests/test-nima-jsonb/.factorypath index 476af7334..5443151a3 100644 --- a/tests/test-nima-jsonb/.factorypath +++ b/tests/test-nima-jsonb/.factorypath @@ -1,7 +1,7 @@ - + diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 6d09f4508..1038b54c9 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -26,7 +26,7 @@ io.avaje avaje-http-api - 1.25-SNAPSHOT + 1.26-SNAPSHOT io.avaje @@ -46,7 +46,7 @@ io.avaje avaje-http-nima-generator - 1.25-SNAPSHOT + 1.26-SNAPSHOT test @@ -79,7 +79,7 @@ io.avaje avaje-http-nima-generator - 1.25-SNAPSHOT + 1.26-SNAPSHOT io.avaje diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index 98ea07411..a4b8390bc 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -27,7 +27,7 @@ io.avaje avaje-http-api - 1.25-SNAPSHOT + 1.26-SNAPSHOT io.helidon.nima.webserver @@ -64,7 +64,7 @@ io.avaje avaje-http-nima-generator - 1.25-SNAPSHOT + 1.26-SNAPSHOT io.avaje From dd232d8f0755bec7011992682fac977d5e4d2b4f Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sat, 4 Feb 2023 09:54:18 -0500 Subject: [PATCH 0576/1323] inherit roles and class openAPI --- .../io/avaje/http/api/OpenAPIResponse.java | 5 ++- .../io/avaje/http/api/OpenAPIResponses.java | 5 ++- .../http/generator/core/ControllerReader.java | 44 ++++++++++++++++++- .../http/generator/core/MethodReader.java | 8 +++- .../myapp/web/test/HealthController.java | 5 +++ .../resources/expectedInheritedOpenApi.json | 3 ++ 6 files changed, 63 insertions(+), 7 deletions(-) diff --git a/http-api/src/main/java/io/avaje/http/api/OpenAPIResponse.java b/http-api/src/main/java/io/avaje/http/api/OpenAPIResponse.java index 6bd59c10b..e225503be 100644 --- a/http-api/src/main/java/io/avaje/http/api/OpenAPIResponse.java +++ b/http-api/src/main/java/io/avaje/http/api/OpenAPIResponse.java @@ -1,6 +1,7 @@ package io.avaje.http.api; import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; import java.lang.annotation.Repeatable; @@ -21,8 +22,8 @@ * * }

*/ -@Target(value = METHOD) -@Retention(value = RUNTIME) +@Target({TYPE, METHOD}) +@Retention(RUNTIME) @Repeatable(OpenAPIResponses.class) public @interface OpenAPIResponse { diff --git a/http-api/src/main/java/io/avaje/http/api/OpenAPIResponses.java b/http-api/src/main/java/io/avaje/http/api/OpenAPIResponses.java index cf21e8688..6c11917fb 100644 --- a/http-api/src/main/java/io/avaje/http/api/OpenAPIResponses.java +++ b/http-api/src/main/java/io/avaje/http/api/OpenAPIResponses.java @@ -1,6 +1,7 @@ package io.avaje.http.api; import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; import java.lang.annotation.Retention; @@ -11,8 +12,8 @@ * * @see OpenAPIResponse */ -@Target(value = METHOD) -@Retention(value = RUNTIME) +@Target({TYPE, METHOD}) +@Retention(RUNTIME) public @interface OpenAPIResponses { OpenAPIResponse[] value(); } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java index 5aea90f62..6a5e9b48e 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java @@ -4,6 +4,7 @@ import java.lang.annotation.Annotation; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.Optional; import java.util.Set; @@ -21,6 +22,8 @@ import javax.validation.Valid; import io.avaje.http.api.Controller; +import io.avaje.http.api.OpenAPIResponse; +import io.avaje.http.api.OpenAPIResponses; import io.avaje.http.api.Path; import io.avaje.http.api.Produces; import io.swagger.v3.oas.annotations.Hidden; @@ -38,6 +41,7 @@ public class ControllerReader { private final List methods = new ArrayList<>(); private final Set staticImportTypes = new TreeSet<>(); private final Set importTypes = new TreeSet<>(); + private final List apiResponses; /** * The produces media type for the controller. Null implies JSON. @@ -57,12 +61,46 @@ public ControllerReader(TypeElement beanType, ProcessingContext ctx) { this.ctx = ctx; this.interfaces = initInterfaces(); this.interfaceMethods = initInterfaceMethods(); - this.roles = Util.findRoles(beanType); + this.roles = buildRoles(); if (ctx.isOpenApiAvailable()) { docHidden = initDocHidden(); } this.hasValid = initHasValid(); this.produces = initProduces(); + this.apiResponses = buildApiResponses(); + } + + private List buildApiResponses() { + final var responses = new ArrayList(); + + Optional.ofNullable(beanType.getAnnotation(OpenAPIResponses.class)).stream() + .map(OpenAPIResponses::value) + .flatMap(Arrays::stream) + .forEach(responses::add); + + Arrays.stream(beanType.getAnnotationsByType(OpenAPIResponse.class)).forEach(responses::add); + + for (final Element anInterface : interfaces) { + + Optional.ofNullable(anInterface.getAnnotation(OpenAPIResponses.class)).stream() + .map(OpenAPIResponses::value) + .flatMap(Arrays::stream) + .forEach(responses::add); + + Arrays.stream(anInterface.getAnnotationsByType(OpenAPIResponse.class)) + .forEach(responses::add); + } + + return responses; + } + + private ArrayList buildRoles() { + final var roleList = new ArrayList<>(Util.findRoles(beanType)); + + for (final Element anInterface : interfaces) { + roleList.addAll(Util.findRoles(anInterface)); + } + return roleList; } protected void addImports(boolean withSingleton) { @@ -267,6 +305,10 @@ public List methods() { return methods; } + public List openApiResponses() { + return apiResponses; + } + public String path() { return Optional.ofNullable(findAnnotation(Controller.class)) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java index 44e2a1291..f7048330d 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java @@ -170,8 +170,12 @@ private List buildApiResponses() { .map(OpenAPIResponses::value) .flatMap(Arrays::stream), Arrays.stream(method.getAnnotationsByType(OpenAPIResponse.class)))); - - return Stream.concat(methodResponses, superMethodResponses).collect(Collectors.toList()); + + var responses = + Stream.concat(methodResponses, superMethodResponses).collect(Collectors.toList()); + + responses.addAll(bean.openApiResponses()); + return responses; } public
A findAnnotation(Class type) { diff --git a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/HealthController.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/HealthController.java index 3a62033bd..697c82451 100644 --- a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/HealthController.java +++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/HealthController.java @@ -1,5 +1,8 @@ package org.example.myapp.web.test; +import org.example.myapp.web.AppRoles; +import org.example.myapp.web.Roles; + import io.avaje.http.api.Get; import io.avaje.http.api.MediaType; import io.avaje.http.api.OpenAPIResponse; @@ -10,11 +13,13 @@ import io.swagger.v3.oas.annotations.tags.Tag; @Path("javalin") +@Roles(AppRoles.ANYONE) @OpenAPIDefinition( info = @Info( title = "Example service showing off the Path extension method of controller", description = "")) +@OpenAPIResponse(responseCode = "403", description = "Not Authorized") public interface HealthController { /** * Standard Get diff --git a/tests/test-javalin-jsonb/src/test/resources/expectedInheritedOpenApi.json b/tests/test-javalin-jsonb/src/test/resources/expectedInheritedOpenApi.json index d79d0822f..4b1490dac 100644 --- a/tests/test-javalin-jsonb/src/test/resources/expectedInheritedOpenApi.json +++ b/tests/test-javalin-jsonb/src/test/resources/expectedInheritedOpenApi.json @@ -29,6 +29,9 @@ } } }, + "403" : { + "description" : "Not Authorized" + }, "200" : { "description" : "a health check", "content" : { From 12313240ffe81831392ed02a382e54eb7b2fc10c Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sat, 4 Feb 2023 10:30:47 -0500 Subject: [PATCH 0577/1323] Update OpenAPIResponse.java --- .../java/io/avaje/http/api/OpenAPIResponse.java | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/http-api/src/main/java/io/avaje/http/api/OpenAPIResponse.java b/http-api/src/main/java/io/avaje/http/api/OpenAPIResponse.java index e225503be..fc4bf96c3 100644 --- a/http-api/src/main/java/io/avaje/http/api/OpenAPIResponse.java +++ b/http-api/src/main/java/io/avaje/http/api/OpenAPIResponse.java @@ -12,7 +12,9 @@ * Specify endpoint response status code/description/type. * *

When not specified the default 2xx openAPI generation is based on the javadoc of the method. - *

Will not override the default 2xx generated openapi unless status code is 2xx + * + *

Will not override the default 2xx generated openapi unless status code is 2xx + * *

{@code
  * @Post("/post")
  * @OpenAPIReturns(responseCode = "200", description = "from annotaion")
@@ -21,6 +23,18 @@
  * ResponseModel endpoint() {}
  *
  * }
+ * + *

Can also be placed on a class to add to every method in the controller. + * + *

{@code
+ * @OpenAPIResponse(
+ * responseCode = "403",
+ * description = "Insufficient rights to this resource."
+ * )
+ * public class MyController {
+ * ...
+ * }
+ * }
*/ @Target({TYPE, METHOD}) @Retention(RUNTIME) From 9ae3b6c35dfbf9dd744421252a861e085d23140b Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Mon, 6 Feb 2023 23:14:21 +1300 Subject: [PATCH 0578/1323] Tidy ControllerReader only --- .../http/generator/core/ControllerReader.java | 35 ++++++++----------- .../src/main/resources/public/openapi.json | 3 ++ 2 files changed, 17 insertions(+), 21 deletions(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java index 6a5e9b48e..d8f15a38e 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java @@ -31,7 +31,7 @@ /** * Reads the type information for the Controller (bean). */ -public class ControllerReader { +public final class ControllerReader { private final ProcessingContext ctx; private final TypeElement beanType; @@ -51,7 +51,7 @@ public class ControllerReader { private boolean methodHasValid; /** - * Flag set when the controller is dependant on a request scope type. + * Flag set when the controller is dependent on a request scope type. */ private boolean requestScope; private boolean docHidden; @@ -72,38 +72,31 @@ public ControllerReader(TypeElement beanType, ProcessingContext ctx) { private List buildApiResponses() { final var responses = new ArrayList(); - - Optional.ofNullable(beanType.getAnnotation(OpenAPIResponses.class)).stream() - .map(OpenAPIResponses::value) - .flatMap(Arrays::stream) - .forEach(responses::add); - - Arrays.stream(beanType.getAnnotationsByType(OpenAPIResponse.class)).forEach(responses::add); - + buildApiResponsesFor(beanType, responses); for (final Element anInterface : interfaces) { - - Optional.ofNullable(anInterface.getAnnotation(OpenAPIResponses.class)).stream() - .map(OpenAPIResponses::value) - .flatMap(Arrays::stream) - .forEach(responses::add); - - Arrays.stream(anInterface.getAnnotationsByType(OpenAPIResponse.class)) - .forEach(responses::add); + buildApiResponsesFor(anInterface, responses); } - return responses; } + private void buildApiResponsesFor(Element element, ArrayList responses) { + Optional.ofNullable(element.getAnnotation(OpenAPIResponses.class)).stream() + .map(OpenAPIResponses::value) + .flatMap(Arrays::stream) + .forEach(responses::add); + + Arrays.stream(element.getAnnotationsByType(OpenAPIResponse.class)).forEach(responses::add); + } + private ArrayList buildRoles() { final var roleList = new ArrayList<>(Util.findRoles(beanType)); - for (final Element anInterface : interfaces) { roleList.addAll(Util.findRoles(anInterface)); } return roleList; } - protected void addImports(boolean withSingleton) { + void addImports(boolean withSingleton) { importTypes.add(Constants.IMPORT_HTTP_API); importTypes.add(beanType.getQualifiedName().toString()); if (hasValid || methodHasValid) { diff --git a/tests/test-javalin-jsonb/src/main/resources/public/openapi.json b/tests/test-javalin-jsonb/src/main/resources/public/openapi.json index f783e17ec..4ebdf89b1 100644 --- a/tests/test-javalin-jsonb/src/main/resources/public/openapi.json +++ b/tests/test-javalin-jsonb/src/main/resources/public/openapi.json @@ -786,6 +786,9 @@ } } }, + "403" : { + "description" : "Not Authorized" + }, "200" : { "description" : "a health check", "content" : { From 6a900511c4c621f78929b58401c39f94b3e7c830 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Mon, 6 Feb 2023 14:00:10 -0500 Subject: [PATCH 0579/1323] test versions pom --- tests/pom.xml | 1 + tests/test-client-generation/pom.xml | 8 ++++---- tests/test-client/pom.xml | 6 +++--- tests/test-helidon/pom.xml | 7 +++---- tests/test-javalin-jsonb/pom.xml | 6 +++--- tests/test-javalin/pom.xml | 6 +++--- tests/test-jex/pom.xml | 6 +++--- tests/test-nima-jsonb/pom.xml | 6 +++--- tests/test-nima/pom.xml | 4 ++-- 9 files changed, 25 insertions(+), 25 deletions(-) diff --git a/tests/pom.xml b/tests/pom.xml index 63a09d2f8..63ac48bff 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -20,6 +20,7 @@ 2.14.1 2.5 8.12-RC3 + 1.26-SNAPSHOT diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index 492ecaa40..14e31a579 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -24,13 +24,13 @@ io.avaje avaje-http-client - 1.26-SNAPSHOT + ${avaje-http-version} io.avaje avaje-http-api - 1.26-SNAPSHOT + ${avaje-http-version} @@ -102,12 +102,12 @@ io.avaje avaje-http-client-generator - 1.26-SNAPSHOT + ${avaje-http-version} io.avaje avaje-http-jex-generator - 1.26-SNAPSHOT + ${avaje-http-version} io.avaje diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index 6b2813bdb..d19e6f84d 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -21,19 +21,19 @@ io.avaje avaje-http-client - 1.26-SNAPSHOT + ${avaje-http-version} io.avaje avaje-http-client-gson - 1.26-SNAPSHOT + ${avaje-http-version} io.avaje avaje-http-api - 1.26-SNAPSHOT + ${avaje-http-version} diff --git a/tests/test-helidon/pom.xml b/tests/test-helidon/pom.xml index 5b66ea8e0..85632e7a3 100644 --- a/tests/test-helidon/pom.xml +++ b/tests/test-helidon/pom.xml @@ -13,7 +13,6 @@ true org.example.Main 2.3.0 - 1.26-SNAPSHOT @@ -33,7 +32,7 @@ io.avaje avaje-http-api - 1.26-SNAPSHOT + ${avaje-http-version} io.avaje @@ -50,7 +49,7 @@ io.avaje avaje-http-helidon-generator - 1.26-SNAPSHOT + ${avaje-http-version} provided @@ -112,7 +111,7 @@ io.avaje avaje-http-client - 1.26-SNAPSHOT + ${avaje-http-version} test diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index fd476b0d5..ce4784588 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -47,7 +47,7 @@ io.avaje avaje-http-api - 1.26-SNAPSHOT + ${avaje-http-version} @@ -74,7 +74,7 @@ io.avaje avaje-http-javalin-generator - 1.26-SNAPSHOT + ${avaje-http-version} provided @@ -103,7 +103,7 @@ io.avaje avaje-http-client - 1.26-SNAPSHOT + ${avaje-http-version} test diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 1c8e2ad48..4e3c3de35 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -52,7 +52,7 @@ io.avaje avaje-http-api - 1.26-SNAPSHOT + ${avaje-http-version} @@ -79,7 +79,7 @@ io.avaje avaje-http-javalin-generator - 1.26-SNAPSHOT + ${avaje-http-version} provided @@ -102,7 +102,7 @@ io.avaje avaje-http-client - 1.26-SNAPSHOT + ${avaje-http-version} test diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index e71f7dae0..ff7bd7c44 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -51,7 +51,7 @@ io.avaje avaje-http-api - 1.26-SNAPSHOT + ${avaje-http-version} @@ -78,7 +78,7 @@ io.avaje avaje-http-jex-generator - 1.26-SNAPSHOT + ${avaje-http-version} provided @@ -94,7 +94,7 @@ io.avaje avaje-http-client - 1.26-SNAPSHOT + ${avaje-http-version} test diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 1038b54c9..8e8944f22 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -26,7 +26,7 @@ io.avaje avaje-http-api - 1.26-SNAPSHOT + ${avaje-http-version} io.avaje @@ -46,7 +46,7 @@ io.avaje avaje-http-nima-generator - 1.26-SNAPSHOT + ${avaje-http-version} test @@ -79,7 +79,7 @@ io.avaje avaje-http-nima-generator - 1.26-SNAPSHOT + ${avaje-http-version} io.avaje diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index a4b8390bc..2c7e3c451 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -27,7 +27,7 @@ io.avaje avaje-http-api - 1.26-SNAPSHOT + ${avaje-http-version} io.helidon.nima.webserver @@ -64,7 +64,7 @@ io.avaje avaje-http-nima-generator - 1.26-SNAPSHOT + ${avaje-http-version} io.avaje From 0bc554db2091cb62c322387cf98387bf47496a15 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Thu, 9 Feb 2023 20:58:38 -0500 Subject: [PATCH 0580/1323] core --- http-generator-client/pom.xml | 2 +- .../generator/client/ClientProcessor.java | 49 ++--- .../src/main/java/module-info.java | 1 + http-generator-core/pom.xml | 44 +++- .../http/generator/core/BaseProcessor.java | 53 ++--- .../http/generator/core/ControllerReader.java | 133 +++++------- .../http/generator/core/ElementReader.java | 122 ++++++----- .../http/generator/core/JavaxInjectPrism.java | 152 ++++++++++++++ .../http/generator/core/MethodReader.java | 190 +++++++++--------- .../generator/core/openapi/DocContext.java | 84 ++++---- .../generator/core/openapi/MediaType.java | 27 +++ .../core/openapi/MethodDocBuilder.java | 32 ++- .../http/generator/core/package-info.java | 32 +++ .../src/main/java/module-info.java | 13 +- .../dependency-reduced-pom.xml | 67 ++++++ http-generator-javalin/pom.xml | 82 ++++---- .../javalin/ControllerMethodWriter.java | 17 +- .../generator/jex/ControllerMethodWriter.java | 34 ++-- .../helidon/nima/ControllerMethodWriter.java | 16 +- pom.xml | 2 + .../src/main/resources/public/openapi.json | 6 +- 21 files changed, 711 insertions(+), 447 deletions(-) create mode 100644 http-generator-core/src/main/java/io/avaje/http/generator/core/JavaxInjectPrism.java create mode 100644 http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/MediaType.java create mode 100644 http-generator-core/src/main/java/io/avaje/http/generator/core/package-info.java create mode 100644 http-generator-javalin/dependency-reduced-pom.xml diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index eec4d9e56..e2852aba2 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -20,7 +20,7 @@ io.avaje avaje-http-generator-core - ${project.version} + 1.26-SNAPSHOT diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java index 49aba1265..dd391ea31 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java @@ -1,9 +1,9 @@ package io.avaje.http.generator.client; -import io.avaje.http.api.Client; -import io.avaje.http.generator.core.ControllerReader; -import io.avaje.http.generator.core.JsonBUtil; -import io.avaje.http.generator.core.ProcessingContext; +import java.io.IOException; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; import javax.annotation.processing.AbstractProcessor; import javax.annotation.processing.ProcessingEnvironment; @@ -13,13 +13,14 @@ import javax.lang.model.element.AnnotationValue; import javax.lang.model.element.Element; import javax.lang.model.element.TypeElement; -import javax.tools.FileObject; -import java.io.IOException; -import java.io.Writer; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Set; +import io.avaje.http.api.Client; +import io.avaje.http.generator.core.ControllerReader; +import io.avaje.http.generator.core.JsonBUtil; +import io.avaje.http.generator.core.ProcessingContext; +import io.avaje.prism.GeneratePrism; + +@GeneratePrism(Client.class) public class ClientProcessor extends AbstractProcessor { private static final String METAINF_SERVICES_PROVIDER = "META-INF/services/io.avaje.http.client.HttpApiProvider"; @@ -45,7 +46,7 @@ public SourceVersion getSupportedSourceVersion() { @Override public Set getSupportedAnnotationTypes() { - Set annotations = new LinkedHashSet<>(); + final Set annotations = new LinkedHashSet<>(); annotations.add(Client.class.getCanonicalName()); annotations.add(Client.Import.class.getCanonicalName()); return annotations; @@ -60,10 +61,10 @@ public synchronized void init(ProcessingEnvironment processingEnv) { @Override public boolean process(Set annotations, RoundEnvironment round) { - for (Element controller : round.getElementsAnnotatedWith(Client.class)) { + for (final Element controller : round.getElementsAnnotatedWith(Client.class)) { writeClient(controller); } - for (Element importedElement : round.getElementsAnnotatedWith(Client.Import.class)) { + for (final Element importedElement : round.getElementsAnnotatedWith(Client.Import.class)) { writeForImported(importedElement); } if (round.processingOver()) { @@ -74,21 +75,21 @@ public boolean process(Set annotations, RoundEnvironment private void writeServicesFile() { try { - final FileObject metaInfWriter = ctx.createMetaInfWriter(METAINF_SERVICES_PROVIDER); - final Writer writer = metaInfWriter.openWriter(); - for (String generatedClient : generatedClients) { + final var metaInfWriter = ctx.createMetaInfWriter(METAINF_SERVICES_PROVIDER); + final var writer = metaInfWriter.openWriter(); + for (final String generatedClient : generatedClients) { writer.append(generatedClient).append("$Provider\n"); } writer.close(); - } catch (IOException e) { + } catch (final IOException e) { ctx.logError(null, "Error writing services file " + e, e); } } private void writeForImported(Element importedElement) { - for (AnnotationMirror annotationMirror : importedElement.getAnnotationMirrors()) { - for (AnnotationValue value : annotationMirror.getElementValues().values()) { - for (Object apiClassDef : (List) value.getValue()) { + for (final AnnotationMirror annotationMirror : importedElement.getAnnotationMirrors()) { + for (final AnnotationValue value : annotationMirror.getElementValues().values()) { + for (final Object apiClassDef : (List) value.getValue()) { writeImported(apiClassDef.toString()); } } @@ -97,8 +98,8 @@ private void writeForImported(Element importedElement) { private void writeImported(String fullName) { // trim .class suffix - String apiClassName = fullName.substring(0, fullName.length() - 6); - TypeElement typeElement = ctx.typeElement(apiClassName); + final var apiClassName = fullName.substring(0, fullName.length() - 6); + final var typeElement = ctx.typeElement(apiClassName); if (typeElement != null) { writeClient(typeElement); } @@ -106,11 +107,11 @@ private void writeImported(String fullName) { private void writeClient(Element controller) { if (controller instanceof TypeElement) { - ControllerReader reader = new ControllerReader((TypeElement) controller, ctx); + final var reader = new ControllerReader((TypeElement) controller, ctx); reader.read(false); try { generatedClients.add(writeClientAdapter(ctx, reader)); - } catch (Throwable e) { + } catch (final Throwable e) { e.printStackTrace(); ctx.logError(reader.beanType(), "Failed to write client class " + e); } diff --git a/http-generator-client/src/main/java/module-info.java b/http-generator-client/src/main/java/module-info.java index 857d62a9c..0b820ff84 100644 --- a/http-generator-client/src/main/java/module-info.java +++ b/http-generator-client/src/main/java/module-info.java @@ -3,5 +3,6 @@ provides javax.annotation.processing.Processor with io.avaje.http.generator.client.ClientProcessor; requires transitive io.avaje.http.generator.core; + requires java.compiler; } diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index c138512d1..9489d0859 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -17,34 +17,58 @@ - - jakarta.inject - jakarta.inject-api - 2.0.0 + + + io.avaje + avaje-prisms + 1.3-SNAPSHOT + provided + + jakarta.validation + jakarta.validation-api + 3.0.2 + true + provided + javax.validation validation-api 2.0.1.Final + true + provided + + jakarta.inject + jakarta.inject-api + 2.0.1 + true + provided + + io.avaje avaje-http-api 1.26-SNAPSHOT + provided io.swagger.core.v3 swagger-models ${swagger.version} + true + provided io.swagger.core.v3 swagger-annotations ${swagger.version} + true + provided @@ -54,12 +78,14 @@ org.apache.maven.plugins maven-compiler-plugin - 3.10.1 - 11 - 11 - - -proc:none + + + io.avaje + avaje-prisms + 1.3-SNAPSHOT + + diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java index 4a01b96a6..c5891d471 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java @@ -1,23 +1,19 @@ package io.avaje.http.generator.core; import java.io.IOException; -import java.util.LinkedHashSet; import java.util.Set; import javax.annotation.processing.AbstractProcessor; import javax.annotation.processing.ProcessingEnvironment; import javax.annotation.processing.RoundEnvironment; +import javax.annotation.processing.SupportedAnnotationTypes; import javax.annotation.processing.SupportedOptions; import javax.lang.model.SourceVersion; import javax.lang.model.element.Element; import javax.lang.model.element.TypeElement; -import io.avaje.http.api.Controller; -import io.swagger.v3.oas.annotations.OpenAPIDefinition; -import io.swagger.v3.oas.annotations.tags.Tag; -import io.swagger.v3.oas.annotations.tags.Tags; - -@SupportedOptions({"useJavax","useSingleton"}) +@SupportedOptions({"useJavax", "useSingleton"}) +@SupportedAnnotationTypes({ControllerPrism.PRISM_TYPE, OpenAPIDefinitionPrism.PRISM_TYPE}) public abstract class BaseProcessor extends AbstractProcessor { protected ProcessingContext ctx; @@ -27,23 +23,13 @@ public SourceVersion getSupportedSourceVersion() { return SourceVersion.latest(); } - @Override - public Set getSupportedAnnotationTypes() { - Set annotations = new LinkedHashSet<>(); - annotations.add(Controller.class.getCanonicalName()); - annotations.add(OpenAPIDefinition.class.getCanonicalName()); - return annotations; - } - @Override public synchronized void init(ProcessingEnvironment processingEnv) { super.init(processingEnv); this.ctx = new ProcessingContext(processingEnv, providePlatformAdapter()); } - /** - * Provide the platform specific adapter to use for Javalin, Helidon etc. - */ + /** Provide the platform specific adapter to use for Javalin, Helidon etc. */ protected abstract PlatformAdapter providePlatformAdapter(); @Override @@ -54,8 +40,9 @@ public boolean process(Set annotations, RoundEnvironment readTagDefinitions(round); } - Set controllers = round.getElementsAnnotatedWith(Controller.class); - for (Element controller : controllers) { + final Set controllers = + round.getElementsAnnotatedWith(ctx.typeElement(ControllerPrism.PRISM_TYPE)); + for (final Element controller : controllers) { writeControllerAdapter(controller); } @@ -66,20 +53,22 @@ public boolean process(Set annotations, RoundEnvironment } private void readOpenApiDefinition(RoundEnvironment round) { - Set elements = round.getElementsAnnotatedWith(OpenAPIDefinition.class); - for (Element element : elements) { + final Set elements = + round.getElementsAnnotatedWith(ctx.typeElement(OpenAPIDefinitionPrism.PRISM_TYPE)); + for (final Element element : elements) { ctx.doc().readApiDefinition(element); } } private void readTagDefinitions(RoundEnvironment round) { - Set elements = round.getElementsAnnotatedWith(Tag.class); - for (Element element : elements) { + Set elements = + round.getElementsAnnotatedWith(ctx.typeElement(TagPrism.PRISM_TYPE)); + for (final Element element : elements) { ctx.doc().addTagDefinition(element); } - elements = round.getElementsAnnotatedWith(Tags.class); - for (Element element : elements) { + elements = round.getElementsAnnotatedWith(ctx.typeElement(TagsPrism.PRISM_TYPE)); + for (final Element element : elements) { ctx.doc().addTagsDefinition(element); } } @@ -90,20 +79,18 @@ private void writeOpenAPI() { private void writeControllerAdapter(Element controller) { if (controller instanceof TypeElement) { - ControllerReader reader = new ControllerReader((TypeElement) controller, ctx); + final var reader = new ControllerReader((TypeElement) controller, ctx); reader.read(true); try { writeControllerAdapter(ctx, reader); - } catch (Throwable e) { + } catch (final Throwable e) { e.printStackTrace(); ctx.logError(reader.beanType(), "Failed to write $Route class " + e); } } } - /** - * Write the adapter code for the given controller. - */ - public abstract void writeControllerAdapter(ProcessingContext ctx, ControllerReader reader) throws IOException; - + /** Write the adapter code for the given controller. */ + public abstract void writeControllerAdapter(ProcessingContext ctx, ControllerReader reader) + throws IOException; } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java index d8f15a38e..544f16c6c 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java @@ -2,13 +2,12 @@ import static java.util.function.Predicate.not; -import java.lang.annotation.Annotation; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; import java.util.Optional; import java.util.Set; import java.util.TreeSet; +import java.util.function.Function; import javax.lang.model.element.Element; import javax.lang.model.element.ElementKind; @@ -19,18 +18,8 @@ import javax.lang.model.type.TypeKind; import javax.lang.model.type.TypeMirror; import javax.lang.model.util.ElementFilter; -import javax.validation.Valid; - -import io.avaje.http.api.Controller; -import io.avaje.http.api.OpenAPIResponse; -import io.avaje.http.api.OpenAPIResponses; -import io.avaje.http.api.Path; -import io.avaje.http.api.Produces; -import io.swagger.v3.oas.annotations.Hidden; - -/** - * Reads the type information for the Controller (bean). - */ + +/** Reads the type information for the Controller (bean). */ public final class ControllerReader { private final ProcessingContext ctx; @@ -41,19 +30,17 @@ public final class ControllerReader { private final List methods = new ArrayList<>(); private final Set staticImportTypes = new TreeSet<>(); private final Set importTypes = new TreeSet<>(); - private final List apiResponses; + private final List apiResponses; + + /** The producesPrism media type for the controller. Null implies JSON. */ + private final String producesPrism; - /** - * The produces media type for the controller. Null implies JSON. - */ - private final String produces; private final boolean hasValid; private boolean methodHasValid; - /** - * Flag set when the controller is dependent on a request scope type. - */ + /** Flag set when the controller is dependent on a request scope type. */ private boolean requestScope; + private boolean docHidden; public ControllerReader(TypeElement beanType, ProcessingContext ctx) { @@ -66,12 +53,12 @@ public ControllerReader(TypeElement beanType, ProcessingContext ctx) { docHidden = initDocHidden(); } this.hasValid = initHasValid(); - this.produces = initProduces(); + this.producesPrism = initProduces(); this.apiResponses = buildApiResponses(); } - private List buildApiResponses() { - final var responses = new ArrayList(); + private List buildApiResponses() { + final var responses = new ArrayList(); buildApiResponsesFor(beanType, responses); for (final Element anInterface : interfaces) { buildApiResponsesFor(anInterface, responses); @@ -79,13 +66,13 @@ private List buildApiResponses() { return responses; } - private void buildApiResponsesFor(Element element, ArrayList responses) { - Optional.ofNullable(element.getAnnotation(OpenAPIResponses.class)).stream() - .map(OpenAPIResponses::value) - .flatMap(Arrays::stream) - .forEach(responses::add); + private void buildApiResponsesFor(Element element, ArrayList responses) { + Optional.ofNullable(OpenAPIResponsesPrism.getInstanceOn(element)).stream() + .map(OpenAPIResponsesPrism::value) + .flatMap(List::stream) + .forEach(responses::add); - Arrays.stream(element.getAnnotationsByType(OpenAPIResponse.class)).forEach(responses::add); + responses.addAll(OpenAPIResponsePrism.getAllInstancesOn(element)); } private ArrayList buildRoles() { @@ -112,12 +99,12 @@ void addImports(boolean withSingleton) { } private List initInterfaces() { - List interfaces = new ArrayList<>(); - for (TypeMirror anInterface : beanType.getInterfaces()) { - final Element ifaceElement = ctx.asElement(anInterface); - var controller = ifaceElement.getAnnotation(Controller.class); + final List interfaces = new ArrayList<>(); + for (final TypeMirror anInterface : beanType.getInterfaces()) { + final var ifaceElement = ctx.asElement(anInterface); + final var controller = ControllerPrism.getInstanceOn(ifaceElement); if (controller != null && !controller.value().isBlank() - || ifaceElement.getAnnotation(Path.class) != null) { + || PathPrism.getInstanceOn(ifaceElement) != null) { interfaces.add(ifaceElement); } } @@ -125,20 +112,20 @@ private List initInterfaces() { } private List initInterfaceMethods() { - List ifaceMethods = new ArrayList<>(); - for (Element anInterface : interfaces) { + final List ifaceMethods = new ArrayList<>(); + for (final Element anInterface : interfaces) { ifaceMethods.addAll(ElementFilter.methodsIn(anInterface.getEnclosedElements())); } return ifaceMethods; } - private
A findAnnotation(Class type) { - A annotation = beanType.getAnnotation(type); + private A findAnnotation(Function func) { + var annotation = func.apply(beanType); if (annotation != null) { return annotation; } - for (Element anInterface : interfaces) { - annotation = anInterface.getAnnotation(type); + for (final Element anInterface : interfaces) { + annotation = func.apply(anInterface); if (annotation != null) { return annotation; } @@ -146,10 +133,10 @@ private A findAnnotation(Class type) { return null; } - A findMethodAnnotation(Class type, ExecutableElement element) { - for (ExecutableElement interfaceMethod : interfaceMethods) { + A findMethodAnnotation(Function func, ExecutableElement element) { + for (final ExecutableElement interfaceMethod : interfaceMethods) { if (matchMethod(interfaceMethod, element)) { - final A annotation = interfaceMethod.getAnnotation(type); + final var annotation = func.apply(interfaceMethod); if (annotation != null) { return annotation; } @@ -163,31 +150,22 @@ private boolean matchMethod(ExecutableElement interfaceMethod, ExecutableElement } private String initProduces() { - final Produces produces = findAnnotation(Produces.class); + final var produces = findAnnotation(ProducesPrism::getInstanceOn); return (produces == null) ? null : produces.value(); } private boolean initDocHidden() { - return findAnnotation(Hidden.class) != null; + return findAnnotation(HiddenPrism::getInstanceOn) != null; } private boolean initHasValid() { - Annotation jakartaValidAnnotation = null; - try { - jakartaValidAnnotation = findAnnotation(jakarataValidAnnotation()); - } catch (final ClassNotFoundException e) { - // ignore - } - return findAnnotation(Valid.class) != null || jakartaValidAnnotation != null; - } - @SuppressWarnings("unchecked") - private static Class jakarataValidAnnotation() throws ClassNotFoundException { - return (Class)Class.forName(Valid.class.getCanonicalName().replace("javax", "jakarta")); + return findAnnotation(JavaxValidPrism::getInstanceOn) != null + || findAnnotation(ValidPrism::getInstanceOn) != null; } String produces() { - return produces; + return producesPrism; } public TypeElement beanType() { @@ -207,8 +185,8 @@ public boolean hasValid() { } /** - * Return true if the controller has request scoped dependencies. - * In that case a BeanFactory will have been generated. + * Return true if the controller has request scoped dependencies. In that case a BeanFactory will + * have been generated. */ boolean isRequestScoped() { return requestScope; @@ -218,7 +196,7 @@ public void read(boolean withSingleton) { if (!roles.isEmpty()) { ctx.platform().controllerRoles(roles, this); } - for (Element element : beanType.getEnclosedElements()) { + for (final Element element : beanType.getEnclosedElements()) { if (element.getKind() == ElementKind.METHOD) { readMethod((ExecutableElement) element); } else if (element.getKind() == ElementKind.FIELD) { @@ -235,7 +213,7 @@ private void deriveIncludeValidation() { } private boolean methodHasValid() { - for (MethodReader method : methods) { + for (final MethodReader method : methods) { if (method.hasValid()) { return true; } @@ -245,21 +223,19 @@ private boolean methodHasValid() { private void readField(Element element) { if (!requestScope) { - final String rawType = element.asType().toString(); + final var rawType = element.asType().toString(); requestScope = RequestScopeTypes.isRequestType(rawType); } } - /** - * Read methods from superclasses taking into account generics. - */ + /** Read methods from superclasses taking into account generics. */ private void readSuper(TypeElement beanType) { - TypeMirror superclass = beanType.getSuperclass(); + final var superclass = beanType.getSuperclass(); if (superclass.getKind() != TypeKind.NONE) { - DeclaredType declaredType = (DeclaredType) superclass; - final Element superElement = ctx.asElement(superclass); + final var declaredType = (DeclaredType) superclass; + final var superElement = ctx.asElement(superclass); if (!"java.lang.Object".equals(superElement.toString())) { - for (Element element : superElement.getEnclosedElements()) { + for (final Element element : superElement.getEnclosedElements()) { if (element.getKind() == ElementKind.METHOD) { readMethod((ExecutableElement) element, declaredType); } else if (element.getKind() == ElementKind.FIELD) { @@ -283,7 +259,7 @@ private void readMethod(ExecutableElement method, DeclaredType declaredType) { // actual taking into account generics actualExecutable = (ExecutableType) ctx.asMemberOf(declaredType, method); } - MethodReader methodReader = new MethodReader(this, method, actualExecutable, ctx); + final var methodReader = new MethodReader(this, method, actualExecutable, ctx); if (methodReader.isWebMethod()) { methodReader.read(); methods.add(methodReader); @@ -298,16 +274,18 @@ public List methods() { return methods; } - public List openApiResponses() { + public List openApiResponses() { return apiResponses; } public String path() { - return Optional.ofNullable(findAnnotation(Controller.class)) - .map(Controller::value) + return Optional.ofNullable(findAnnotation(ControllerPrism::getInstanceOn)) + .map(ControllerPrism::value) .filter(not(String::isBlank)) - .or(() -> Optional.ofNullable(findAnnotation(Path.class)).map(Path::value)) + .or( + () -> + Optional.ofNullable(findAnnotation(PathPrism::getInstanceOn)).map(PathPrism::value)) .map(Util::trimPath) .orElse(null); } @@ -319,7 +297,7 @@ public void addImportType(String rawType) { } public void addImportTypes(Set types) { - for (String type : types) { + for (final String type : types) { addImportType(type); } } @@ -335,5 +313,4 @@ public Set staticImportTypes() { public Set importTypes() { return importTypes; } - } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java index 9a583dd82..80084b33e 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java @@ -1,14 +1,11 @@ package io.avaje.http.generator.core; -import io.avaje.http.api.*; -import io.avaje.http.generator.core.openapi.MethodDocBuilder; -import io.avaje.http.generator.core.openapi.MethodParamDocBuilder; +import static io.avaje.http.generator.core.ParamType.RESPONSE_HANDLER; import javax.lang.model.element.Element; -import javax.lang.model.element.TypeElement; -import javax.validation.Valid; -import static io.avaje.http.generator.core.ParamType.RESPONSE_HANDLER; +import io.avaje.http.generator.core.openapi.MethodDocBuilder; +import io.avaje.http.generator.core.openapi.MethodParamDocBuilder; public class ElementReader { @@ -31,13 +28,19 @@ public class ElementReader { private String paramDefault; private boolean notNullKotlin; - //private boolean notNullJavax; + // private boolean notNullJavax; ElementReader(Element element, ProcessingContext ctx, ParamType defaultType, boolean formMarker) { this(element, null, Util.typeDef(element.asType()), ctx, defaultType, formMarker); } - ElementReader(Element element, UType type, String rawType, ProcessingContext ctx, ParamType defaultType, boolean formMarker) { + ElementReader( + Element element, + UType type, + String rawType, + ProcessingContext ctx, + ParamType defaultType, + boolean formMarker) { this.ctx = ctx; this.element = element; this.type = type; @@ -62,67 +65,65 @@ private boolean useValidation() { if (typeHandler != null) { return false; } - TypeElement elementType = ctx.typeElement(rawType); - var elementRawType = element.asType().toString(); + final var elementType = ctx.typeElement(rawType); return elementType != null - && (elementType.getAnnotation(Valid.class) != null - || (elementRawType.contains("@") && elementRawType.contains("validation"))); + && (ValidPrism.getInstanceOn(elementType) != null + || JavaxValidPrism.getInstanceOn(elementType) != null); } private void readAnnotations(Element element, ParamType defaultType) { - notNullKotlin = (element.getAnnotation(org.jetbrains.annotations.NotNull.class) != null); - //notNullJavax = (element.getAnnotation(javax.validation.constraints.NotNull.class) != null); + notNullKotlin = NotNullPrism.getInstanceOn(element) != null; - Default defaultVal = element.getAnnotation(Default.class); + final var defaultVal = DefaultPrism.getInstanceOn(element); if (defaultVal != null) { this.paramDefault = defaultVal.value(); } - Form form = element.getAnnotation(Form.class); + final var form = FormPrism.getInstanceOn(element); if (form != null) { this.paramType = ParamType.FORM; return; } - BeanParam beanParam = element.getAnnotation(BeanParam.class); + final var beanParam = BeanParamPrism.getInstanceOn(element); if (beanParam != null) { this.paramType = ParamType.BEANPARAM; return; } - QueryParam queryParam = element.getAnnotation(QueryParam.class); + final var queryParam = QueryParamPrism.getInstanceOn(element); if (queryParam != null) { this.paramName = nameFrom(queryParam.value(), varName); this.paramType = ParamType.QUERYPARAM; return; } - FormParam formParam = element.getAnnotation(FormParam.class); + final var formParam = FormParamPrism.getInstanceOn(element); if (formParam != null) { this.paramName = nameFrom(formParam.value(), varName); this.paramType = ParamType.FORMPARAM; return; } - Cookie cookieParam = element.getAnnotation(Cookie.class); + final var cookieParam = CookiePrism.getInstanceOn(element); if (cookieParam != null) { this.paramName = nameFrom(cookieParam.value(), varName); this.paramType = ParamType.COOKIE; this.paramDefault = null; return; } - Header headerParam = element.getAnnotation(Header.class); + final var headerParam = HeaderPrism.getInstanceOn(element); if (headerParam != null) { this.paramName = nameFrom(headerParam.value(), Util.initcapSnake(snakeName)); this.paramType = ParamType.HEADER; this.paramDefault = null; return; } - - MatrixParam matrixParam = element.getAnnotation(MatrixParam.class); + + final var matrixParam = MatrixParamPrism.getInstanceOn(element); if (matrixParam != null) { this.matrixParamName = nameFrom(matrixParam.value(), varName); this.paramType = defaultType; this.impliedParamType = true; return; } - + if (paramType == null) { this.impliedParamType = true; if (typeHandler != null) { @@ -172,7 +173,7 @@ private String handlerShortType() { void addImports(ControllerReader bean) { if (typeHandler != null) { - String importType = typeHandler.importType(); + final var importType = typeHandler.importType(); if (importType != null) { bean.addImportType(rawType); } @@ -189,9 +190,7 @@ void writeParamName(Append writer) { } } - /** - * Build the OpenAPI documentation for this parameter. - */ + /** Build the OpenAPI documentation for this parameter. */ void buildApiDocumentation(MethodDocBuilder methodDoc) { if (!isPlatformContext()) { new MethodParamDocBuilder(methodDoc, this).build(); @@ -210,15 +209,12 @@ void writeValidate(Append writer) { } void writeCtxGet(Append writer, PathSegments segments) { - if (isPlatformContext()) { - // no conversion for this parameter - return; - } - if (paramType == ParamType.BODY && ctx.platform().isBodyMethodParam()) { + if (isPlatformContext() + || (paramType == ParamType.BODY && ctx.platform().isBodyMethodParam())) { // body passed as method parameter (Helidon) return; } - String shortType = handlerShortType(); + final var shortType = handlerShortType(); writer.append("%s var %s = ", ctx.platform().indent(), varName); if (setValue(writer, segments, shortType)) { writer.append(";").eol(); @@ -230,15 +226,15 @@ void setValue(Append writer) { } private boolean setValue(Append writer, PathSegments segments, String shortType) { -// if (formMarker && impliedParamType && typeHandler == null) { -// if (ParamType.FORM != paramType) { -// throw new IllegalStateException("Don't get here?"); -// } -//// // @Form on method and this type is a "bean" so treat is as a form bean -//// writeForm(writer, shortType, varName, ParamType.FORMPARAM); -//// paramType = ParamType.FORM; -//// return false; -// } + // if (formMarker && impliedParamType && typeHandler == null) { + // if (ParamType.FORM != paramType) { + // throw new IllegalStateException("Don't get here?"); + // } + //// // @Form on method and this type is a "bean" so treat is as a form bean + //// writeForm(writer, shortType, varName, ParamType.FORMPARAM); + //// paramType = ParamType.FORM; + //// return false; + // } if (ParamType.FORM == paramType) { writeForm(writer, shortType, varName, ParamType.FORMPARAM); return false; @@ -248,12 +244,12 @@ private boolean setValue(Append writer, PathSegments segments, String shortType) return false; } if (impliedParamType) { - var name = matrixParamName != null ? matrixParamName : varName; - PathSegments.Segment segment = segments.segment(name); + final var name = matrixParamName != null ? matrixParamName : varName; + final var segment = segments.segment(name); if (segment != null) { // path or matrix parameter - boolean requiredParam = segment.isRequired(varName); - String asMethod = + final var requiredParam = segment.isRequired(varName); + final var asMethod = (typeHandler == null) ? null : (requiredParam) ? typeHandler.asMethod() : typeHandler.toMethod(); @@ -269,7 +265,7 @@ private boolean setValue(Append writer, PathSegments segments, String shortType) } } - String asMethod = (typeHandler == null) ? null : typeHandler.toMethod(); + final var asMethod = (typeHandler == null) ? null : typeHandler.toMethod(); if (asMethod != null) { writer.append(asMethod); } @@ -278,19 +274,18 @@ private boolean setValue(Append writer, PathSegments segments, String shortType) // this is a body (POST, PATCH) writer.append(ctx.platform().bodyAsClass(type)); + } else if (hasParamDefault()) { + ctx.platform().writeReadParameter(writer, paramType, paramName, paramDefault); } else { - if (hasParamDefault()) { - ctx.platform().writeReadParameter(writer, paramType, paramName, paramDefault); - } else { - boolean checkNull = notNullKotlin || (paramType == ParamType.FORMPARAM && typeHandler.isPrimitive()); - if (checkNull) { - writer.append("checkNull("); - } - ctx.platform().writeReadParameter(writer, paramType, paramName); - //writer.append("ctx.%s(\"%s\")", paramType, paramName); - if (checkNull) { - writer.append(", \"%s\")", paramName); - } + final var checkNull = + notNullKotlin || (paramType == ParamType.FORMPARAM && typeHandler.isPrimitive()); + if (checkNull) { + writer.append("checkNull("); + } + ctx.platform().writeReadParameter(writer, paramType, paramName); + // writer.append("ctx.%s(\"%s\")", paramType, paramName); + if (checkNull) { + writer.append(", \"%s\")", paramName); } } @@ -300,9 +295,10 @@ private boolean setValue(Append writer, PathSegments segments, String shortType) return true; } - private void writeForm(Append writer, String shortType, String varName, ParamType defaultParamType) { - TypeElement formBeanType = ctx.typeElement(rawType); - BeanParamReader form = new BeanParamReader(ctx, formBeanType, varName, shortType, defaultParamType); + private void writeForm( + Append writer, String shortType, String varName, ParamType defaultParamType) { + final var formBeanType = ctx.typeElement(rawType); + final var form = new BeanParamReader(ctx, formBeanType, varName, shortType, defaultParamType); form.write(writer); } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/JavaxInjectPrism.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/JavaxInjectPrism.java new file mode 100644 index 000000000..e53d28fa4 --- /dev/null +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/JavaxInjectPrism.java @@ -0,0 +1,152 @@ +package io.avaje.http.generator.core; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.lang.model.element.AnnotationMirror; +import javax.lang.model.element.AnnotationValue; +import javax.lang.model.element.Element; +import javax.lang.model.element.ExecutableElement; +import javax.lang.model.element.TypeElement; +import javax.lang.model.util.ElementFilter; + +/** + * A Prism representing an {@code @javax.inject.Inject} annotation.
+ * Added manually because we can't have both javax and jakarta as dependecies + */ +public class JavaxInjectPrism { + public static final String PRISM_TYPE = "javax.inject.Inject"; + + /** + * An instance of the Values inner class whose methods return the AnnotationValues used to build + * this prism. Primarily intended to support using Messager. + */ + final Values values; + /** + * Return a prism representing the {@code @javax.inject.Inject} annotation on 'e'. similar to + * {@code e.getAnnotation(javax.inject.Inject.class)} except that an instance of this class rather + * than an instance of {@code javax.inject.Inject} is returned. + */ + static JavaxInjectPrism getInstanceOn(Element e) { + final var m = getMirror(PRISM_TYPE, e); + if (m == null) return null; + return getInstance(m); + } + + /** Return a prism of the {@code @javax.inject.Inject} annotation whose mirror is mirror. */ + static JavaxInjectPrism getInstance(AnnotationMirror mirror) { + if (mirror == null || !PRISM_TYPE.equals(mirror.getAnnotationType().toString())) return null; + + return new JavaxInjectPrism(mirror); + } + + private JavaxInjectPrism(AnnotationMirror mirror) { + for (final ExecutableElement key : mirror.getElementValues().keySet()) { + memberValues.put(key.getSimpleName().toString(), mirror.getElementValues().get(key)); + } + for (final ExecutableElement member : + ElementFilter.methodsIn(mirror.getAnnotationType().asElement().getEnclosedElements())) { + defaults.put(member.getSimpleName().toString(), member.getDefaultValue()); + } + this.values = new Values(memberValues); + this.mirror = mirror; + this.isValid = valid; + } + + /** + * Determine whether the underlying AnnotationMirror has no errors. True if the underlying + * AnnotationMirror has no errors. When true is returned, none of the methods will return null. + * When false is returned, a least one member will either return null, or another prism that is + * not valid. + */ + final boolean isValid; + + /** + * The underlying AnnotationMirror of the annotation represented by this Prism. Primarily intended + * to support using Messager. + */ + final AnnotationMirror mirror; + /** + * A class whose members corespond to those of javax.inject.Inject but which each return the + * AnnotationValue corresponding to that member in the model of the annotations. Returns null for + * defaulted members. Used for Messager, so default values are not useful. + */ + static class Values { + private final Map values; + + private Values(Map values) { + this.values = values; + } + } + + private final Map defaults = new HashMap<>(10); + private final Map memberValues = new HashMap<>(10); + private boolean valid = true; + + private T getValue(String name, Class clazz) { + final var result = JavaxInjectPrism.getValue(memberValues, defaults, name, clazz); + if (result == null) valid = false; + return result; + } + + private List getArrayValues(String name, final Class clazz) { + final List result = JavaxInjectPrism.getArrayValues(memberValues, defaults, name, clazz); + if (result == null) valid = false; + return result; + } + + private static AnnotationMirror getMirror(String fqn, Element target) { + for (final AnnotationMirror m : target.getAnnotationMirrors()) { + final CharSequence mfqn = + ((TypeElement) m.getAnnotationType().asElement()).getQualifiedName(); + if (fqn.contentEquals(mfqn)) return m; + } + return null; + } + + private static T getValue( + Map memberValues, + Map defaults, + String name, + Class clazz) { + var av = memberValues.get(name); + if (av == null) av = defaults.get(name); + if (av == null) { + return null; + } + if (clazz.isInstance(av.getValue())) return clazz.cast(av.getValue()); + return null; + } + + private static List getArrayValues( + Map memberValues, + Map defaults, + String name, + final Class clazz) { + var av = memberValues.get(name); + if (av == null) av = defaults.get(name); + if (av == null) { + return java.util.Collections.EMPTY_LIST; + } + if (av.getValue() instanceof List) { + final List result = new ArrayList<>(); + for (final AnnotationValue v : getValueAsList(av)) { + if (clazz.isInstance(v.getValue())) { + result.add(clazz.cast(v.getValue())); + } else { + return java.util.Collections.EMPTY_LIST; + } + } + return result; + } else { + return java.util.Collections.EMPTY_LIST; + } + } + + @SuppressWarnings("unchecked") + private static List getValueAsList(AnnotationValue av) { + return (List) av.getValue(); + } +} diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java index f7048330d..cc52542d4 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java @@ -1,10 +1,12 @@ package io.avaje.http.generator.core; -import io.avaje.http.api.*; -import io.avaje.http.generator.core.javadoc.Javadoc; -import io.avaje.http.generator.core.openapi.MethodDocBuilder; -import io.swagger.v3.oas.annotations.tags.Tag; -import io.swagger.v3.oas.annotations.tags.Tags; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.function.Function; +import java.util.function.Predicate; +import java.util.stream.Collectors; +import java.util.stream.Stream; import javax.lang.model.element.Element; import javax.lang.model.element.ExecutableElement; @@ -12,15 +14,9 @@ import javax.lang.model.type.ExecutableType; import javax.lang.model.type.TypeKind; import javax.lang.model.type.TypeMirror; -import javax.validation.Valid; -import java.lang.annotation.Annotation; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Optional; -import java.util.function.Predicate; -import java.util.stream.Collectors; -import java.util.stream.Stream; + +import io.avaje.http.generator.core.javadoc.Javadoc; +import io.avaje.http.generator.core.openapi.MethodDocBuilder; public class MethodReader { @@ -30,12 +26,11 @@ public class MethodReader { private final boolean isVoid; private final List params = new ArrayList<>(); private final Javadoc javadoc; - /** - * Holds enum Roles that are required for the method. - */ + /** Holds enum Roles that are required for the method. */ private final List methodRoles; - private final Optional producesAnnotation; - private final List apiResponses; + + private final Optional producesAnnotation; + private final List apiResponses; private final ExecutableType actualExecutable; private final List actualParams; private final PathSegments pathSegments; @@ -46,7 +41,11 @@ public class MethodReader { private String webMethodPath; private boolean formMarker; - MethodReader(ControllerReader bean, ExecutableElement element, ExecutableType actualExecutable, ProcessingContext ctx) { + MethodReader( + ControllerReader bean, + ExecutableElement element, + ExecutableType actualExecutable, + ProcessingContext ctx) { this.ctx = ctx; this.bean = bean; this.element = element; @@ -54,23 +53,18 @@ public class MethodReader { this.actualParams = (actualExecutable == null) ? null : actualExecutable.getParameterTypes(); this.isVoid = element.getReturnType().getKind() == TypeKind.VOID; this.methodRoles = Util.findRoles(element); - this.producesAnnotation = Optional.ofNullable(findAnnotation(Produces.class)); + this.producesAnnotation = Optional.ofNullable(findAnnotation(ProducesPrism::getInstanceOn)); initWebMethodViaAnnotation(); - this.superMethods = ctx.superMethods(element.getEnclosingElement(), element.getSimpleName().toString()); + this.superMethods = + ctx.superMethods(element.getEnclosingElement(), element.getSimpleName().toString()); superMethods.forEach(m -> methodRoles.addAll(Util.findRoles(m))); this.apiResponses = buildApiResponses(); this.javadoc = buildJavadoc(element, ctx); if (isWebMethod()) { - Class jakartaValidAnnotation; - try { - jakartaValidAnnotation = jakartaValidAnnotation(); - } catch (final ClassNotFoundException e) { - jakartaValidAnnotation = null; - } - this.hasValid = hasValid(jakartaValidAnnotation); + this.hasValid = initValid(); this.pathSegments = PathSegments.parse(Util.combinePath(bean.path(), webMethodPath)); } else { this.hasValid = false; @@ -80,30 +74,28 @@ public class MethodReader { private Javadoc buildJavadoc(ExecutableElement element, ProcessingContext ctx) { return Optional.of(Javadoc.parse(ctx.docComment(element))) - .filter(Predicate.not(Javadoc::isEmpty)) - .orElseGet(() -> superMethods.stream() - .map(e -> Javadoc.parse(ctx.docComment(e))) .filter(Predicate.not(Javadoc::isEmpty)) - .findFirst() - .orElse(Javadoc.parse(""))); + .orElseGet( + () -> + superMethods.stream() + .map(e -> Javadoc.parse(ctx.docComment(e))) + .filter(Predicate.not(Javadoc::isEmpty)) + .findFirst() + .orElse(Javadoc.parse(""))); } - private boolean hasValid(Class jakartaValidAnnotation) { - return findAnnotation(Valid.class) != null - || (jakartaValidAnnotation != null && findAnnotation(jakartaValidAnnotation) != null) - || superMethodHasValid(jakartaValidAnnotation); + private boolean initValid() { + return findAnnotation(ValidPrism::getInstanceOn) != null + || findAnnotation(JavaxValidPrism::getInstanceOn) != null + || superMethodHasValid(); } - private boolean superMethodHasValid(Class jakartaAnnotation) { + private boolean superMethodHasValid() { return superMethods.stream() - .anyMatch(e -> - findAnnotation(Valid.class, e) != null - || (jakartaAnnotation != null && findAnnotation(jakartaAnnotation, e) != null)); - } - - @SuppressWarnings("unchecked") - private static Class jakartaValidAnnotation() throws ClassNotFoundException { - return (Class) Class.forName(Valid.class.getCanonicalName().replace("javax", "jakarta")); + .anyMatch( + e -> + findAnnotation(ValidPrism::getInstanceOn) != null + || findAnnotation(JavaxValidPrism::getInstanceOn) != null); } @Override @@ -112,31 +104,31 @@ public String toString() { } private void initWebMethodViaAnnotation() { - Form form = findAnnotation(Form.class); + final var form = findAnnotation(FormPrism::getInstanceOn); if (form != null) { this.formMarker = true; } - Get get = findAnnotation(Get.class); + final var get = findAnnotation(GetPrism::getInstanceOn); if (get != null) { initSetWebMethod(WebMethod.GET, get.value()); return; } - Put put = findAnnotation(Put.class); + final var put = findAnnotation(PutPrism::getInstanceOn); if (put != null) { initSetWebMethod(WebMethod.PUT, put.value()); return; } - Post post = findAnnotation(Post.class); + final var post = findAnnotation(PostPrism::getInstanceOn); if (post != null) { initSetWebMethod(WebMethod.POST, post.value()); return; } - Patch patch = findAnnotation(Patch.class); + final var patch = findAnnotation(PatchPrism::getInstanceOn); if (patch != null) { initSetWebMethod(WebMethod.PATCH, patch.value()); return; } - Delete delete = findAnnotation(Delete.class); + final var delete = findAnnotation(DeletePrism::getInstanceOn); if (delete != null) { initSetWebMethod(WebMethod.DELETE, delete.value()); } @@ -151,54 +143,57 @@ public Javadoc javadoc() { return javadoc; } - private List buildApiResponses() { + private List buildApiResponses() { final var container = - Optional.ofNullable(findAnnotation(OpenAPIResponses.class)).stream() - .map(OpenAPIResponses::value) - .flatMap(Arrays::stream); + Optional.ofNullable(findAnnotation(OpenAPIResponsesPrism::getInstanceOn)).stream() + .map(OpenAPIResponsesPrism::value) + .flatMap(List::stream); final var methodResponses = - Stream.concat( - container, Arrays.stream(element.getAnnotationsByType(OpenAPIResponse.class))); + Stream.concat(container, OpenAPIResponsePrism.getAllInstancesOn(element).stream()); final var superMethodResponses = - superMethods.stream() - .flatMap( - method -> - Stream.concat( - Optional.ofNullable(findAnnotation(OpenAPIResponses.class, method)).stream() - .map(OpenAPIResponses::value) - .flatMap(Arrays::stream), - Arrays.stream(method.getAnnotationsByType(OpenAPIResponse.class)))); - - var responses = + superMethods.stream() + .flatMap( + method -> + Stream.concat( + Optional.ofNullable( + findAnnotation(OpenAPIResponsesPrism::getInstanceOn, method)) + .stream() + .map(OpenAPIResponsesPrism::value) + .flatMap(List::stream), + OpenAPIResponsePrism.getAllInstancesOn(method).stream())); + + final var responses = Stream.concat(methodResponses, superMethodResponses).collect(Collectors.toList()); - + responses.addAll(bean.openApiResponses()); return responses; } - public
A findAnnotation(Class type) { - return findAnnotation(type, element); + public A findAnnotation(Function prismFunc) { + return findAnnotation(prismFunc, element); } - public A findAnnotation(Class type, ExecutableElement elem) { - final var annotation = elem.getAnnotation(type); + public A findAnnotation(Function prismFunc, ExecutableElement elem) { + final var annotation = prismFunc.apply(elem); if (annotation != null) { return annotation; } - return bean.findMethodAnnotation(type, elem); + return bean.findMethodAnnotation(prismFunc, elem); } private List addTagsToList(Element element, List list) { if (element == null) { return list; } - if (element.getAnnotation(Tag.class) != null) { - list.add(element.getAnnotation(Tag.class).name()); - } - if (element.getAnnotation(Tags.class) != null) { - for (Tag tag : element.getAnnotation(Tags.class).value()) { + + TagPrism.getAllInstancesOn(element).forEach(t -> list.add(t.name())); + + final var tags = TagsPrism.getInstanceOn(element); + + if (tags != null) { + for (final var tag : tags.value()) { list.add(tag.name()); } } @@ -217,20 +212,20 @@ void read() { } // non-path parameters default to form or query parameters based on the // existence of @Form annotation on the method - ParamType defaultParamType = (formMarker) ? ParamType.FORMPARAM : ParamType.QUERYPARAM; + final var defaultParamType = (formMarker) ? ParamType.FORMPARAM : ParamType.QUERYPARAM; final List parameters = element.getParameters(); - for (int i = 0; i < parameters.size(); i++) { - VariableElement p = parameters.get(i); + for (var i = 0; i < parameters.size(); i++) { + final VariableElement p = parameters.get(i); TypeMirror typeMirror; if (actualParams != null) { typeMirror = actualParams.get(i); } else { typeMirror = p.asType(); } - String rawType = Util.typeDef(typeMirror); - UType type = Util.parse(typeMirror.toString()); - MethodParam param = new MethodParam(p, type, rawType, ctx, defaultParamType, formMarker); + final var rawType = Util.typeDef(typeMirror); + final var type = Util.parse(typeMirror.toString()); + final var param = new MethodParam(p, type, rawType, ctx, defaultParamType, formMarker); params.add(param); param.addImports(bean); } @@ -240,15 +235,13 @@ public void buildApiDoc() { buildApiDocumentation(ctx); } - /** - * Build the OpenAPI documentation for the method / operation. - */ + /** Build the OpenAPI documentation for the method / operation. */ public void buildApiDocumentation(ProcessingContext ctx) { new MethodDocBuilder(this, ctx.doc()).build(); } public List roles() { - var roles = new ArrayList<>(methodRoles); + final var roles = new ArrayList<>(methodRoles); roles.addAll(bean.roles()); return roles; } @@ -274,14 +267,14 @@ public boolean isVoid() { } public boolean hasProducesStatus() { - return producesAnnotation.map(Produces::defaultStatus).filter(s -> s > 0).isPresent(); + return producesAnnotation.map(ProducesPrism::defaultStatus).filter(s -> s > 0).isPresent(); } public String produces() { - return producesAnnotation.map(Produces::value).orElseGet(bean::produces); + return producesAnnotation.map(ProducesPrism::value).orElseGet(bean::produces); } - public List apiResponses() { + public List apiResponses() { return apiResponses; } @@ -294,9 +287,10 @@ public TypeMirror returnType() { public String statusCode() { return producesAnnotation - .map(Produces::defaultStatus) + .map(ProducesPrism::defaultStatus) .filter(s -> s > 0) - .orElseGet(() -> webMethod.statusCode(isVoid)).toString(); + .orElseGet(() -> webMethod.statusCode(isVoid)) + .toString(); } public PathSegments pathSegments() { @@ -320,7 +314,7 @@ public String simpleName() { } public boolean isFormBody() { - for (MethodParam param : params) { + for (final MethodParam param : params) { if (param.isForm()) { return true; } @@ -329,7 +323,7 @@ public boolean isFormBody() { } public String bodyType() { - for (MethodParam param : params) { + for (final MethodParam param : params) { if (param.isBody()) { return param.shortType(); } @@ -338,7 +332,7 @@ public String bodyType() { } public String bodyName() { - for (MethodParam param : params) { + for (final MethodParam param : params) { if (param.isBody()) { return param.name(); } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/DocContext.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/DocContext.java index 0ba24b9c8..2f26605b1 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/DocContext.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/DocContext.java @@ -1,35 +1,33 @@ package io.avaje.http.generator.core.openapi; -import io.swagger.v3.oas.annotations.OpenAPIDefinition; -import io.swagger.v3.oas.annotations.tags.Tag; -import io.swagger.v3.oas.annotations.tags.Tags; -import io.swagger.v3.oas.models.Components; -import io.swagger.v3.oas.models.OpenAPI; -import io.swagger.v3.oas.models.Operation; -import io.swagger.v3.oas.models.PathItem; -import io.swagger.v3.oas.models.Paths; -import io.swagger.v3.oas.models.info.Info; -import io.swagger.v3.oas.models.media.Content; -import io.swagger.v3.oas.models.media.Schema; +import java.io.IOException; +import java.io.Writer; +import java.util.Map; +import java.util.TreeMap; import javax.annotation.processing.Filer; import javax.annotation.processing.Messager; import javax.annotation.processing.ProcessingEnvironment; import javax.lang.model.element.Element; -import javax.lang.model.element.TypeElement; import javax.lang.model.type.TypeMirror; import javax.lang.model.util.Elements; import javax.tools.Diagnostic; -import javax.tools.FileObject; import javax.tools.StandardLocation; -import java.io.IOException; -import java.io.Writer; -import java.util.Map; -import java.util.TreeMap; -/** - * Context for building the OpenAPI documentation. - */ +import io.avaje.http.generator.core.OpenAPIDefinitionPrism; +import io.avaje.http.generator.core.TagPrism; +import io.avaje.http.generator.core.TagsPrism; +import io.swagger.v3.oas.models.Components; +import io.swagger.v3.oas.models.OpenAPI; +import io.swagger.v3.oas.models.Operation; +import io.swagger.v3.oas.models.PathItem; +import io.swagger.v3.oas.models.Paths; +import io.swagger.v3.oas.models.info.Info; +import io.swagger.v3.oas.models.media.Content; +import io.swagger.v3.oas.models.media.Schema; +import io.swagger.v3.oas.models.tags.Tag; + +/** Context for building the OpenAPI documentation. */ public class DocContext { private final boolean openApiAvailable; @@ -61,10 +59,10 @@ public boolean isOpenApiAvailable() { private OpenAPI initOpenAPI() { - OpenAPI openAPI = new OpenAPI(); + final var openAPI = new OpenAPI(); openAPI.setPaths(new Paths()); - Info info = new Info(); + final var info = new Info(); info.setTitle(""); info.setVersion(""); openAPI.setInfo(info); @@ -73,7 +71,7 @@ private OpenAPI initOpenAPI() { } Schema toSchema(String rawType, Element element) { - TypeElement typeElement = elements.getTypeElement(rawType); + final var typeElement = elements.getTypeElement(rawType); if (typeElement == null) { // primitive types etc return schemaBuilder.toSchema(element.asType()); @@ -98,18 +96,16 @@ void addRequestBody(Operation operation, Schema schema, boolean asForm, String d schemaBuilder.addRequestBody(operation, schema, asForm, description); } - /** - * Return the OpenAPI adding the paths and schemas. - */ + /** Return the OpenAPI adding the paths and schemas. */ private OpenAPI getApiForWriting() { - Paths paths = openAPI.getPaths(); + var paths = openAPI.getPaths(); if (paths == null) { paths = new Paths(); openAPI.setPaths(paths); } // add paths by natural order - for (Map.Entry entry : pathMap.entrySet()) { + for (final Map.Entry entry : pathMap.entrySet()) { paths.addPathItem(entry.getKey(), entry.getValue()); } @@ -117,11 +113,9 @@ private OpenAPI getApiForWriting() { return openAPI; } - /** - * Return the components creating if needed. - */ + /** Return the components creating if needed. */ private Components components() { - Components components = openAPI.getComponents(); + var components = openAPI.getComponents(); if (components == null) { components = new Components(); openAPI.setComponents(components); @@ -129,8 +123,8 @@ private Components components() { return components; } - private io.swagger.v3.oas.models.tags.Tag createTagItem(Tag tag){ - io.swagger.v3.oas.models.tags.Tag tagsItem = new io.swagger.v3.oas.models.tags.Tag(); + private Tag createTagItem(TagPrism tag) { + final var tagsItem = new Tag(); tagsItem.setName(tag.name()); tagsItem.setDescription(tag.description()); // tagsItem.setExtensions(tag.extensions()); # Not sure about the extensions @@ -139,27 +133,25 @@ private io.swagger.v3.oas.models.tags.Tag createTagItem(Tag tag){ } public void addTagsDefinition(Element element) { - Tags tags = element.getAnnotation(Tags.class); - if(tags == null) - return; + final var tags = TagsPrism.getInstanceOn(element); + if (tags == null) return; - for(Tag tag: tags.value()){ + for (final var tag : tags.value()) { openAPI.addTagsItem(createTagItem(tag)); } } - public void addTagDefinition(Element element){ - Tag tag = element.getAnnotation(Tag.class); - if(tag == null) - return; + public void addTagDefinition(Element element) { + final var tag = TagPrism.getInstanceOn(element); + if (tag == null) return; openAPI.addTagsItem(createTagItem(tag)); } public void readApiDefinition(Element element) { - OpenAPIDefinition openApi = element.getAnnotation(OpenAPIDefinition.class); - io.swagger.v3.oas.annotations.info.Info info = openApi.info(); + final var openApi = OpenAPIDefinitionPrism.getInstanceOn(element); + final var info = openApi.info(); if (!info.title().isEmpty()) { openAPI.getInfo().setTitle(info.title()); } @@ -169,7 +161,6 @@ public void readApiDefinition(Element element) { if (!info.version().isEmpty()) { openAPI.getInfo().setVersion(info.version()); } - } public void writeApi() { @@ -187,12 +178,11 @@ public void writeApi() { } private Writer createMetaWriter() throws IOException { - FileObject writer = filer.createResource(StandardLocation.CLASS_OUTPUT, "meta", "openapi.json"); + final var writer = filer.createResource(StandardLocation.CLASS_OUTPUT, "meta", "openapi.json"); return writer.openWriter(); } private void logError(Element e, String msg, Object... args) { messager.printMessage(Diagnostic.Kind.ERROR, String.format(msg, args), e); } - } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/MediaType.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/MediaType.java new file mode 100644 index 000000000..331488cfa --- /dev/null +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/MediaType.java @@ -0,0 +1,27 @@ +package io.avaje.http.generator.core.openapi; + +public enum MediaType { + APPLICATION_JSON("application/json"), + TEXT_PLAIN("text/plain"), + TEXT_HTML("text/html"), + UNKNOWN(""); + + private final String value; + + MediaType(String value) { + this.value = value; + } + + public String getValue() { + return value; + } + + public static MediaType parse(String s) { + for (final MediaType mediaType : values()) { + if (mediaType.getValue().equalsIgnoreCase(s)) { + return mediaType; + } + } + return UNKNOWN; + } +} diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/MethodDocBuilder.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/MethodDocBuilder.java index 16ee29c34..47f3124ac 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/MethodDocBuilder.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/MethodDocBuilder.java @@ -3,19 +3,17 @@ import javax.lang.model.type.MirroredTypeException; import javax.lang.model.type.TypeMirror; -import io.avaje.http.api.MediaType; +import io.avaje.http.generator.core.HiddenPrism; import io.avaje.http.generator.core.MethodParam; import io.avaje.http.generator.core.MethodReader; import io.avaje.http.generator.core.javadoc.Javadoc; -import io.swagger.v3.oas.annotations.Hidden; +import io.avaje.prism.GeneratePrism; import io.swagger.v3.oas.models.Operation; -import io.swagger.v3.oas.models.PathItem; import io.swagger.v3.oas.models.responses.ApiResponse; import io.swagger.v3.oas.models.responses.ApiResponses; -/** - * Build the OpenAPI documentation for a method. - */ +/** Build the OpenAPI documentation for a method. */ +@GeneratePrism(Deprecated.class) public class MethodDocBuilder { private final Javadoc javadoc; @@ -32,22 +30,22 @@ public MethodDocBuilder(MethodReader methodReader, DocContext ctx) { public void build() { - if (ctx.isOpenApiAvailable() && methodReader.findAnnotation(Hidden.class) != null) { + if (ctx.isOpenApiAvailable() + && methodReader.findAnnotation(HiddenPrism::getInstanceOn) != null) { return; } - //operation.setOperationId(); + // operation.setOperationId(); operation.setSummary(javadoc.getSummary()); operation.setDescription(javadoc.getDescription()); operation.setTags(methodReader.tags()); - if (javadoc.isDeprecated()) { - operation.setDeprecated(true); - } else if (methodReader.findAnnotation(Deprecated.class) != null) { + if (javadoc.isDeprecated() + || (methodReader.findAnnotation(DeprecatedPrism::getInstanceOn) != null)) { operation.setDeprecated(true); } - PathItem pathItem = ctx.pathItem(methodReader.fullPath()); + final var pathItem = ctx.pathItem(methodReader.fullPath()); switch (methodReader.webMethod()) { case GET: pathItem.setGet(operation); @@ -66,26 +64,26 @@ public void build() { break; } - for (MethodParam param : methodReader.params()) { + for (final MethodParam param : methodReader.params()) { param.buildApiDocumentation(this); } - ApiResponses responses = new ApiResponses(); + final var responses = new ApiResponses(); operation.setResponses(responses); - ApiResponse response = new ApiResponse(); + final var response = new ApiResponse(); response.setDescription(javadoc.getReturnDescription()); final var produces = methodReader.produces(); final var hasProducesStatus = methodReader.hasProducesStatus(); - final var contentMediaType = (produces == null) ? MediaType.APPLICATION_JSON : produces; + final var contentMediaType = (produces == null) ? "application/json" : produces; if (methodReader.isVoid()) { if (isEmpty(response.getDescription())) { response.setDescription("No content"); } } else { - response.setContent(ctx.createContent(methodReader.returnType(), contentMediaType)); + response.setContent(ctx.createContent(methodReader.returnType(), contentMediaType)); } var override2xx = false; for (final var responseAnnotation : methodReader.apiResponses()) { diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/package-info.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/package-info.java new file mode 100644 index 000000000..8568feb1f --- /dev/null +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/package-info.java @@ -0,0 +1,32 @@ +/** Generate the prisms to access annotation info */ +@GeneratePrism(value = io.avaje.http.api.Controller.class, publicAccess = true) +@GeneratePrism(value = io.avaje.http.api.BeanParam.class, publicAccess = true) +@GeneratePrism(value = io.avaje.http.api.QueryParam.class, publicAccess = true) +@GeneratePrism(value = io.avaje.http.api.Client.class, publicAccess = true) +@GeneratePrism(value = io.avaje.http.api.Cookie.class, publicAccess = true) +@GeneratePrism(value = io.avaje.http.api.Default.class, publicAccess = true) +@GeneratePrism(value = io.avaje.http.api.Delete.class, publicAccess = true) +@GeneratePrism(value = io.avaje.http.api.Form.class, publicAccess = true) +@GeneratePrism(value = io.avaje.http.api.FormParam.class, publicAccess = true) +@GeneratePrism(value = io.avaje.http.api.Get.class, publicAccess = true) +@GeneratePrism(value = io.avaje.http.api.Header.class, publicAccess = true) +@GeneratePrism(value = io.avaje.http.api.MatrixParam.class, publicAccess = true) +@GeneratePrism(value = io.avaje.http.api.Patch.class, publicAccess = true) +@GeneratePrism(value = io.avaje.http.api.Path.class, publicAccess = true) +@GeneratePrism(value = io.avaje.http.api.Post.class, publicAccess = true) +@GeneratePrism(value = io.avaje.http.api.Produces.class, publicAccess = true) +@GeneratePrism(value = io.avaje.http.api.Put.class, publicAccess = true) +@GeneratePrism(value = jakarta.inject.Inject.class) +@GeneratePrism(value = io.swagger.v3.oas.annotations.OpenAPIDefinition.class, publicAccess = true) +@GeneratePrism(value = io.swagger.v3.oas.annotations.tags.Tag.class, publicAccess = true) +@GeneratePrism(value = io.swagger.v3.oas.annotations.tags.Tags.class, publicAccess = true) +@GeneratePrism(value = io.avaje.http.api.OpenAPIResponse.class, publicAccess = true) +@GeneratePrism(value = io.avaje.http.api.OpenAPIResponses.class, publicAccess = true) +@GeneratePrism(value = io.swagger.v3.oas.annotations.Hidden.class, publicAccess = true) +@GeneratePrism(value = javax.validation.Valid.class, name = "JavaxValidPrism", publicAccess = true) +@GeneratePrism(value = jakarta.validation.Valid.class, publicAccess = true) +@GeneratePrism(value = org.jetbrains.annotations.NotNull.class, publicAccess = true) + +package io.avaje.http.generator.core; + +import io.avaje.prism.GeneratePrism; diff --git a/http-generator-core/src/main/java/module-info.java b/http-generator-core/src/main/java/module-info.java index 327dfaf65..c9db3e787 100644 --- a/http-generator-core/src/main/java/module-info.java +++ b/http-generator-core/src/main/java/module-info.java @@ -6,9 +6,12 @@ requires java.sql; requires java.compiler; - requires transitive io.avaje.http.api; - requires transitive io.swagger.v3.oas.models; - requires transitive io.swagger.v3.oas.annotations; - requires transitive com.fasterxml.jackson.annotation; - requires transitive java.validation; + requires static transitive io.avaje.prism; + requires static transitive io.avaje.http.api; + requires static transitive io.swagger.v3.oas.models; + requires static transitive io.swagger.v3.oas.annotations; + requires static transitive com.fasterxml.jackson.annotation; + requires static transitive java.validation; + requires static transitive jakarta.inject; + requires static transitive jakarta.validation; } diff --git a/http-generator-javalin/dependency-reduced-pom.xml b/http-generator-javalin/dependency-reduced-pom.xml new file mode 100644 index 000000000..e84b1a938 --- /dev/null +++ b/http-generator-javalin/dependency-reduced-pom.xml @@ -0,0 +1,67 @@ + + + + avaje-http-parent + io.avaje + 1.26-SNAPSHOT + + 4.0.0 + avaje-http-javalin-generator + + + + maven-compiler-plugin + 3.10.1 + + 11 + 11 + -proc:none + + + + maven-shade-plugin + 3.4.1 + + + package + + shade + + + + + + + + + io.avaje + avaje-prisms + 1.3-SNAPSHOT + provided + + + io.avaje + junit + 1.1 + test + + + junit-jupiter-api + org.junit.jupiter + + + junit-jupiter-engine + org.junit.jupiter + + + assertj-core + org.assertj + + + mockito-core + org.mockito + + + + + diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index c5bf64295..061b7cb37 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -1,42 +1,46 @@ - 4.0.0 - - avaje-http-javalin-generator - - - io.avaje - avaje-http-parent - 1.26-SNAPSHOT - .. - - - - - - io.avaje - avaje-http-generator-core - ${project.version} - - - - - - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.10.1 - - 11 - 11 - - -proc:none - - - - - - + 4.0.0 + avaje-http-javalin-generator + + io.avaje + avaje-http-parent + 1.26-SNAPSHOT + .. + + + + io.avaje + avaje-http-generator-core + ${project.version} + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.10.1 + + 11 + 11 + + -proc:none + + + + org.apache.maven.plugins + maven-shade-plugin + 3.4.1 + + + package + + shade + + + + + + diff --git a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java index 2fbc09c64..838e1ac6b 100644 --- a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java +++ b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java @@ -1,7 +1,14 @@ package io.avaje.http.generator.javalin; -import io.avaje.http.api.MediaType; -import io.avaje.http.generator.core.*; +import io.avaje.http.generator.core.Append; +import io.avaje.http.generator.core.MethodParam; +import io.avaje.http.generator.core.MethodReader; +import io.avaje.http.generator.core.PathSegments; +import io.avaje.http.generator.core.ProcessingContext; +import io.avaje.http.generator.core.UType; +import io.avaje.http.generator.core.Util; +import io.avaje.http.generator.core.WebMethod; +import io.avaje.http.generator.core.openapi.MediaType; /** * Write code to register Web route for a given controller method. @@ -86,16 +93,16 @@ void write(boolean requestScoped) { private void writeContextReturn() { final var produces = method.produces(); - if (produces == null || MediaType.APPLICATION_JSON.equalsIgnoreCase(produces)) { + if (produces == null || MediaType.APPLICATION_JSON.getValue().equalsIgnoreCase(produces)) { if (useJsonB) { final var uType = UType.parse(method.returnType()); writer.append(" %sJsonType.toJson(result, ctx.contentType(\"application/json\").outputStream());", uType.shortName()); } else { writer.append(" ctx.json(result);"); } - } else if (MediaType.TEXT_HTML.equalsIgnoreCase(produces)) { + } else if (MediaType.TEXT_HTML.getValue().equalsIgnoreCase(produces)) { writer.append(" ctx.html(result);"); - } else if (MediaType.TEXT_PLAIN.equalsIgnoreCase(produces)) { + } else if (MediaType.TEXT_PLAIN.getValue().equalsIgnoreCase(produces)) { writer.append(" ctx.contentType(\"text/plain\").result(result);"); } else { writer.append(" ctx.contentType(\"%s\").result(result);", produces); diff --git a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java index 0d3d88a43..3f794b2cb 100644 --- a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java +++ b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java @@ -1,6 +1,7 @@ package io.avaje.http.generator.jex; -import io.avaje.http.api.MediaType; +import java.util.List; + import io.avaje.http.generator.core.Append; import io.avaje.http.generator.core.MethodParam; import io.avaje.http.generator.core.MethodReader; @@ -8,8 +9,7 @@ import io.avaje.http.generator.core.ProcessingContext; import io.avaje.http.generator.core.Util; import io.avaje.http.generator.core.WebMethod; - -import java.util.List; +import io.avaje.http.generator.core.openapi.MediaType; /** * Write code to register Web route for a given controller method. @@ -30,24 +30,24 @@ class ControllerMethodWriter { void write(boolean requestScoped) { - final PathSegments segments = method.pathSegments(); - final String fullPath = segments.fullPath(); + final var segments = method.pathSegments(); + final var fullPath = segments.fullPath(); writer.append(" routing.%s(\"%s\", ctx -> {", webMethod.name().toLowerCase(), fullPath).eol(); writer.append(" ctx.status(%s);", method.statusCode()).eol(); - List matrixSegments = segments.matrixSegments(); - for (PathSegments.Segment matrixSegment : matrixSegments) { + final var matrixSegments = segments.matrixSegments(); + for (final PathSegments.Segment matrixSegment : matrixSegments) { matrixSegment.writeCreateSegment(writer, ctx.platform()); } - final List params = method.params(); - for (MethodParam param : params) { + final var params = method.params(); + for (final MethodParam param : params) { param.writeCtxGet(writer, segments); } writer.append(" "); if (method.includeValidate()) { - for (MethodParam param : params) { + for (final MethodParam param : params) { param.writeValidate(writer); } } @@ -61,7 +61,7 @@ void write(boolean requestScoped) { writer.append("controller."); } writer.append(method.simpleName()).append("("); - for (int i = 0; i < params.size(); i++) { + for (var i = 0; i < params.size(); i++) { if (i > 0) { writer.append(", "); } @@ -74,10 +74,10 @@ void write(boolean requestScoped) { writer.append(";").eol(); writer.append(" }"); - List roles = method.roles(); + final var roles = method.roles(); if (!roles.isEmpty()) { writer.append(").withRoles("); - for (int i = 0; i < roles.size(); i++) { + for (var i = 0; i < roles.size(); i++) { if (i > 0) { writer.append(", "); } @@ -88,12 +88,12 @@ void write(boolean requestScoped) { } private void writeContextReturn() { - final String produces = method.produces(); - if (produces == null || produces.equalsIgnoreCase(MediaType.APPLICATION_JSON)) { + final var produces = method.produces(); + if (produces == null || produces.equalsIgnoreCase(MediaType.APPLICATION_JSON.getValue())) { writer.append("ctx.json("); - } else if (produces.equalsIgnoreCase(MediaType.TEXT_HTML)) { + } else if (produces.equalsIgnoreCase(MediaType.TEXT_HTML.getValue())) { writer.append("ctx.html("); - } else if (produces.equalsIgnoreCase(MediaType.TEXT_PLAIN)) { + } else if (produces.equalsIgnoreCase(MediaType.TEXT_PLAIN.getValue())) { writer.append("ctx.text("); } else { writer.append("ctx.contentType(\"%s\").write(", produces); diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java index 668837ffc..9eb3a73e4 100644 --- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java +++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java @@ -3,7 +3,6 @@ import java.util.List; import java.util.Optional; -import io.avaje.http.api.MediaType; import io.avaje.http.generator.core.Append; import io.avaje.http.generator.core.MethodParam; import io.avaje.http.generator.core.MethodReader; @@ -12,6 +11,7 @@ import io.avaje.http.generator.core.ProcessingContext; import io.avaje.http.generator.core.UType; import io.avaje.http.generator.core.WebMethod; +import io.avaje.http.generator.core.openapi.MediaType; /** * Write code to register Web route for a given controller method. @@ -113,7 +113,7 @@ void writeHandler(boolean requestScoped) { if (!method.isVoid()) { writeContextReturn(); if (producesJson()) { - final UType uType = UType.parse(method.returnType()); + final var uType = UType.parse(method.returnType()); writer.append(" %sJsonType.toJson(result, res.outputStream());", uType.shortName()).eol(); } else { writer.append(" res.send(result);").eol(); @@ -142,13 +142,13 @@ private void writeContextReturn() { return; } - final var produces = producesOp.orElse(MediaType.APPLICATION_JSON); + final var produces = producesOp.map(MediaType::parse).orElse(MediaType.APPLICATION_JSON); final var contentTypeString = " res.headers().contentType(HttpMediaType."; - switch (produces.toLowerCase()) { - case MediaType.APPLICATION_JSON -> writer.append(contentTypeString + "APPLICATION_JSON);").eol(); - case MediaType.TEXT_HTML -> writer.append(contentTypeString + "TEXT_HTML);").eol(); - case MediaType.TEXT_PLAIN -> writer.append(contentTypeString + "TEXT_PLAIN);").eol(); - default -> writer.append(contentTypeString + "create(\"%s\"));", produces).eol(); + switch (produces) { + case APPLICATION_JSON -> writer.append(contentTypeString + "APPLICATION_JSON);").eol(); + case TEXT_HTML -> writer.append(contentTypeString + "TEXT_HTML);").eol(); + case TEXT_PLAIN -> writer.append(contentTypeString + "TEXT_PLAIN);").eol(); + case UNKNOWN -> writer.append(contentTypeString + "create(\"%s\"));", produces).eol(); } } diff --git a/pom.xml b/pom.xml index 3c88fa784..429a40921 100644 --- a/pom.xml +++ b/pom.xml @@ -19,9 +19,11 @@ true + 1.1-SNAPSHOT + io.avaje junit diff --git a/tests/test-javalin-jsonb/src/main/resources/public/openapi.json b/tests/test-javalin-jsonb/src/main/resources/public/openapi.json index 4ebdf89b1..bd9768ec5 100644 --- a/tests/test-javalin-jsonb/src/main/resources/public/openapi.json +++ b/tests/test-javalin-jsonb/src/main/resources/public/openapi.json @@ -1,18 +1,18 @@ { "openapi" : "3.0.1", "info" : { - "title" : "Example service showing off the Path extension method of controller", + "title" : "Example service", "description" : "Example Javalin controllers with Java and Maven", "version" : "" }, "tags" : [ { "name" : "tag1", - "description" : "this is added to openapi tags" + "description" : "it's somethin" }, { "name" : "tag1", - "description" : "it's somethin" + "description" : "this is added to openapi tags" } ], "paths" : { From 23369d0d4a64ae35ae1fa7ec714971fe2beb1b9d Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Fri, 10 Feb 2023 15:23:55 -0500 Subject: [PATCH 0581/1323] Working --- .github/workflows/build.yml | 4 +- .github/workflows/jdk-ea.yml | 2 +- http-api/pom.xml | 11 -- .../dependency-reduced-pom.xml | 52 ++++++ .../src/etc/activate-shade-module | 1 + .../generator/client/ClientProcessor.java | 28 ++- .../src/main/java/module-info.java | 4 +- .../dependency-reduced-pom.xml | 97 ++++++++++ http-generator-core/pom.xml | 40 ++-- .../src/etc/activate-shade-module | 1 + .../http/generator/core/BaseProcessor.java | 5 + .../http/generator/core/ControllerReader.java | 3 +- .../core/openapi/MethodDocBuilder.java | 11 +- .../core/openapi/SchemaDocBuilder.java | 171 +++++++++--------- .../http/generator/core/package-info.java | 3 +- .../src/main/java/module-info.java | 5 +- .../dependency-reduced-pom.xml | 49 +++++ .../src/etc/activate-shade-module | 1 + .../helidon/ControllerMethodWriter.java | 12 +- .../src/main/java/module-info.java | 4 +- .../dependency-reduced-pom.xml | 20 -- http-generator-javalin/pom.xml | 15 -- .../src/etc/activate-shade-module | 1 + .../src/main/java/module-info.java | 4 +- http-generator-jex/dependency-reduced-pom.xml | 49 +++++ .../src/etc/activate-shade-module | 1 + .../src/main/java/module-info.java | 4 +- .../src/main/java/module-info.java | 4 +- pom.xml | 97 +++++++++- 29 files changed, 505 insertions(+), 194 deletions(-) create mode 100644 http-generator-client/dependency-reduced-pom.xml create mode 100644 http-generator-client/src/etc/activate-shade-module create mode 100644 http-generator-core/dependency-reduced-pom.xml create mode 100644 http-generator-core/src/etc/activate-shade-module create mode 100644 http-generator-helidon/dependency-reduced-pom.xml create mode 100644 http-generator-helidon/src/etc/activate-shade-module create mode 100644 http-generator-javalin/src/etc/activate-shade-module create mode 100644 http-generator-jex/dependency-reduced-pom.xml create mode 100644 http-generator-jex/src/etc/activate-shade-module diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 92cd6b1b7..de6874a55 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -35,7 +35,7 @@ jobs: run: | if (( JAVA_VERSION < 19 )); then - mvn clean test -pl "!:avaje-http-nima-generator" + mvn clean package -pl "!:avaje-http-nima-generator" else - mvn clean test + mvn clean package fi diff --git a/.github/workflows/jdk-ea.yml b/.github/workflows/jdk-ea.yml index 9d02b3776..d93f51958 100644 --- a/.github/workflows/jdk-ea.yml +++ b/.github/workflows/jdk-ea.yml @@ -37,5 +37,5 @@ jobs: - name: Maven version run: mvn --version - name: Build with Maven - run: mvn clean verify + run: mvn clean verify package diff --git a/http-api/pom.xml b/http-api/pom.xml index d1b40dac6..10f142510 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -15,15 +15,4 @@ avaje-http-parent-1.19 - - - - io.avaje - junit - 1.1 - test - - - - diff --git a/http-generator-client/dependency-reduced-pom.xml b/http-generator-client/dependency-reduced-pom.xml new file mode 100644 index 000000000..5a970065b --- /dev/null +++ b/http-generator-client/dependency-reduced-pom.xml @@ -0,0 +1,52 @@ + + + + avaje-http-parent + io.avaje + 1.26-SNAPSHOT + + 4.0.0 + avaje-http-client-generator + + + + maven-compiler-plugin + 3.10.1 + + 11 + 11 + -proc:none + + + + + + + io.avaje + junit + 1.1 + test + + + junit-jupiter-api + org.junit.jupiter + + + junit-jupiter-engine + org.junit.jupiter + + + assertj-core + org.assertj + + + mockito-core + org.mockito + + + + + + 11 + + diff --git a/http-generator-client/src/etc/activate-shade-module b/http-generator-client/src/etc/activate-shade-module new file mode 100644 index 000000000..949f3d244 --- /dev/null +++ b/http-generator-client/src/etc/activate-shade-module @@ -0,0 +1 @@ +Remove from module-info all content after: // SHADED: diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java index dd391ea31..ec4256524 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java @@ -8,22 +8,24 @@ import javax.annotation.processing.AbstractProcessor; import javax.annotation.processing.ProcessingEnvironment; import javax.annotation.processing.RoundEnvironment; +import javax.annotation.processing.SupportedAnnotationTypes; import javax.lang.model.SourceVersion; import javax.lang.model.element.AnnotationMirror; import javax.lang.model.element.AnnotationValue; import javax.lang.model.element.Element; import javax.lang.model.element.TypeElement; -import io.avaje.http.api.Client; +import io.avaje.http.generator.core.ClientPrism; import io.avaje.http.generator.core.ControllerReader; +import io.avaje.http.generator.core.ImportPrism; import io.avaje.http.generator.core.JsonBUtil; import io.avaje.http.generator.core.ProcessingContext; -import io.avaje.prism.GeneratePrism; -@GeneratePrism(Client.class) +@SupportedAnnotationTypes({ClientPrism.PRISM_TYPE, ImportPrism.PRISM_TYPE}) public class ClientProcessor extends AbstractProcessor { - private static final String METAINF_SERVICES_PROVIDER = "META-INF/services/io.avaje.http.client.HttpApiProvider"; + private static final String METAINF_SERVICES_PROVIDER = + "META-INF/services/io.avaje.http.client.HttpApiProvider"; private final Set generatedClients = new LinkedHashSet<>(); @@ -44,14 +46,6 @@ public SourceVersion getSupportedSourceVersion() { return SourceVersion.latest(); } - @Override - public Set getSupportedAnnotationTypes() { - final Set annotations = new LinkedHashSet<>(); - annotations.add(Client.class.getCanonicalName()); - annotations.add(Client.Import.class.getCanonicalName()); - return annotations; - } - @Override public synchronized void init(ProcessingEnvironment processingEnv) { super.init(processingEnv); @@ -61,10 +55,12 @@ public synchronized void init(ProcessingEnvironment processingEnv) { @Override public boolean process(Set annotations, RoundEnvironment round) { - for (final Element controller : round.getElementsAnnotatedWith(Client.class)) { + for (final Element controller : + round.getElementsAnnotatedWith(ctx.typeElement(ClientPrism.PRISM_TYPE))) { writeClient(controller); } - for (final Element importedElement : round.getElementsAnnotatedWith(Client.Import.class)) { + for (final Element importedElement : + round.getElementsAnnotatedWith(ctx.typeElement(ImportPrism.PRISM_TYPE))) { writeForImported(importedElement); } if (round.processingOver()) { @@ -118,8 +114,8 @@ private void writeClient(Element controller) { } } - protected String writeClientAdapter(ProcessingContext ctx, ControllerReader reader) throws IOException { + protected String writeClientAdapter(ProcessingContext ctx, ControllerReader reader) + throws IOException { return new ClientWriter(reader, ctx, useJsonB).write(); } - } diff --git a/http-generator-client/src/main/java/module-info.java b/http-generator-client/src/main/java/module-info.java index 0b820ff84..9779dd07e 100644 --- a/http-generator-client/src/main/java/module-info.java +++ b/http-generator-client/src/main/java/module-info.java @@ -2,7 +2,9 @@ provides javax.annotation.processing.Processor with io.avaje.http.generator.client.ClientProcessor; + requires java.compiler; + + // SHADED: All content after this line will be removed at package time requires transitive io.avaje.http.generator.core; - requires java.compiler; } diff --git a/http-generator-core/dependency-reduced-pom.xml b/http-generator-core/dependency-reduced-pom.xml new file mode 100644 index 000000000..91ac82e0b --- /dev/null +++ b/http-generator-core/dependency-reduced-pom.xml @@ -0,0 +1,97 @@ + + + + avaje-http-parent + io.avaje + 1.26-SNAPSHOT + + 4.0.0 + avaje-http-generator-core + + + + maven-compiler-plugin + + + + io.avaje + avaje-prisms + 1.3-SNAPSHOT + + + + + + + + + io.avaje + avaje-prisms + 1.3-SNAPSHOT + provided + true + + + io.avaje + avaje-http-api + 1.26-SNAPSHOT + provided + true + + + jakarta.validation + jakarta.validation-api + 3.0.2 + provided + true + + + javax.validation + validation-api + 2.0.1.Final + provided + true + + + jakarta.inject + jakarta.inject-api + 2.0.1 + provided + true + + + io.swagger.core.v3 + swagger-annotations + 2.0.8 + provided + true + + + io.avaje + junit + 1.1 + test + + + junit-jupiter-api + org.junit.jupiter + + + junit-jupiter-engine + org.junit.jupiter + + + assertj-core + org.assertj + + + mockito-core + org.mockito + + + + + + 2.0.8 + + diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 9489d0859..239917e5e 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -18,12 +18,34 @@ - + io.avaje avaje-prisms 1.3-SNAPSHOT + true provided + + + io.avaje + avaje-http-api + 1.26-SNAPSHOT + true + provided + + + + io.swagger.core.v3 + swagger-models + ${swagger.version} + + + com.fasterxml.jackson.core + jackson-annotations + + + + jakarta.validation jakarta.validation-api @@ -48,20 +70,6 @@ provided - - io.avaje - avaje-http-api - 1.26-SNAPSHOT - provided - - - - io.swagger.core.v3 - swagger-models - ${swagger.version} - true - provided - io.swagger.core.v3 @@ -75,6 +83,7 @@ + org.apache.maven.plugins maven-compiler-plugin @@ -91,5 +100,4 @@ - diff --git a/http-generator-core/src/etc/activate-shade-module b/http-generator-core/src/etc/activate-shade-module new file mode 100644 index 000000000..949f3d244 --- /dev/null +++ b/http-generator-core/src/etc/activate-shade-module @@ -0,0 +1 @@ +Remove from module-info all content after: // SHADED: diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java index c5891d471..7ad8cbc38 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java @@ -23,6 +23,11 @@ public SourceVersion getSupportedSourceVersion() { return SourceVersion.latest(); } + @Override + public Set getSupportedAnnotationTypes() { + return Set.of(ControllerPrism.PRISM_TYPE, OpenAPIDefinitionPrism.PRISM_TYPE); + } + @Override public synchronized void init(ProcessingEnvironment processingEnv) { super.init(processingEnv); diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java index 544f16c6c..a430205d9 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java @@ -67,7 +67,8 @@ private List buildApiResponses() { } private void buildApiResponsesFor(Element element, ArrayList responses) { - Optional.ofNullable(OpenAPIResponsesPrism.getInstanceOn(element)).stream() + + OpenAPIResponsesPrism.getOptionalOn(element).stream() .map(OpenAPIResponsesPrism::value) .flatMap(List::stream) .forEach(responses::add); diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/MethodDocBuilder.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/MethodDocBuilder.java index 47f3124ac..af9016b0b 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/MethodDocBuilder.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/MethodDocBuilder.java @@ -1,8 +1,5 @@ package io.avaje.http.generator.core.openapi; -import javax.lang.model.type.MirroredTypeException; -import javax.lang.model.type.TypeMirror; - import io.avaje.http.generator.core.HiddenPrism; import io.avaje.http.generator.core.MethodParam; import io.avaje.http.generator.core.MethodReader; @@ -100,13 +97,7 @@ public void build() { newResponse.setContent(response.getContent()); override2xx = !hasProducesStatus; } - TypeMirror returnType = null; - try { - // this will always throw - responseAnnotation.type(); - } catch (final MirroredTypeException mte) { - returnType = mte.getTypeMirror(); - } + final var returnType = responseAnnotation.type(); if (!"java.lang.Void".equals(returnType.toString())) { newResponse.setContent(ctx.createContent(returnType, contentMediaType)); diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/SchemaDocBuilder.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/SchemaDocBuilder.java index 5d3f2061f..5c26f5445 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/SchemaDocBuilder.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/SchemaDocBuilder.java @@ -1,15 +1,11 @@ package io.avaje.http.generator.core.openapi; -import io.avaje.http.generator.core.Util; -import io.swagger.v3.oas.annotations.Hidden; -import io.swagger.v3.oas.models.Operation; -import io.swagger.v3.oas.models.media.ArraySchema; -import io.swagger.v3.oas.models.media.Content; -import io.swagger.v3.oas.models.media.MapSchema; -import io.swagger.v3.oas.models.media.MediaType; -import io.swagger.v3.oas.models.media.ObjectSchema; -import io.swagger.v3.oas.models.media.Schema; -import io.swagger.v3.oas.models.parameters.RequestBody; +import static io.avaje.http.generator.core.Util.typeDef; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; import javax.lang.model.element.AnnotationMirror; import javax.lang.model.element.Element; @@ -23,19 +19,24 @@ import javax.lang.model.util.ElementFilter; import javax.lang.model.util.Elements; import javax.lang.model.util.Types; -import javax.validation.constraints.Email; -import javax.validation.constraints.Size; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.TreeMap; -import static io.avaje.http.generator.core.Util.typeDef; +import io.avaje.http.generator.core.HiddenPrism; +import io.avaje.http.generator.core.Util; +import io.avaje.prism.GeneratePrism; +import io.swagger.v3.oas.models.Operation; +import io.swagger.v3.oas.models.media.ArraySchema; +import io.swagger.v3.oas.models.media.Content; +import io.swagger.v3.oas.models.media.MapSchema; +import io.swagger.v3.oas.models.media.MediaType; +import io.swagger.v3.oas.models.media.ObjectSchema; +import io.swagger.v3.oas.models.media.Schema; +import io.swagger.v3.oas.models.parameters.RequestBody; -/** - * Help build OpenAPI Schema objects. - */ +/** Help build OpenAPI Schema objects. */ +@GeneratePrism(value = jakarta.validation.constraints.Size.class) +@GeneratePrism(value = jakarta.validation.constraints.Email.class) +@GeneratePrism(value = javax.validation.constraints.Size.class, name = "JavaxSizePrism") +@GeneratePrism(value = javax.validation.constraints.Email.class, name = "JavaxEmailPrism") class SchemaDocBuilder { private static final String APP_FORM = "application/x-www-form-urlencoded"; @@ -60,26 +61,24 @@ Map getSchemas() { } Content createContent(TypeMirror returnType, String mediaType) { - MediaType mt = new MediaType(); + final var mt = new MediaType(); mt.setSchema(toSchema(returnType)); - Content content = new Content(); + final var content = new Content(); content.addMediaType(mediaType, mt); return content; } - /** - * Add parameter as a form parameter. - */ + /** Add parameter as a form parameter. */ void addFormParam(Operation operation, String varName, Schema schema) { - RequestBody body = requestBody(operation); - Schema formSchema = requestFormParamSchema(body); + final var body = requestBody(operation); + final var formSchema = requestFormParamSchema(body); formSchema.addProperties(varName, schema); } private Schema requestFormParamSchema(RequestBody body) { - final Content content = body.getContent(); - MediaType mediaType = content.get(APP_FORM); + final var content = body.getContent(); + var mediaType = content.get(APP_FORM); Schema schema; if (mediaType != null) { @@ -94,28 +93,26 @@ private Schema requestFormParamSchema(RequestBody body) { return schema; } - /** - * Add as request body. - */ + /** Add as request body. */ void addRequestBody(Operation operation, Schema schema, boolean asForm, String description) { - RequestBody body = requestBody(operation); + final var body = requestBody(operation); body.setDescription(description); - MediaType mt = new MediaType(); + final var mt = new MediaType(); mt.schema(schema); - String mime = asForm ? APP_FORM : APP_JSON; + final var mime = asForm ? APP_FORM : APP_JSON; body.getContent().addMediaType(mime, mt); } private RequestBody requestBody(Operation operation) { - RequestBody body = operation.getRequestBody(); + var body = operation.getRequestBody(); if (body == null) { body = new RequestBody(); body.setRequired(true); - Content content = new Content(); + final var content = new Content(); body.setContent(content); operation.setRequestBody(body); } @@ -124,7 +121,7 @@ private RequestBody requestBody(Operation operation) { Schema toSchema(TypeMirror type) { - Schema schema = knownTypes.createSchema(typeDef(type)); + final Schema schema = knownTypes.createSchema(typeDef(type)); if (schema != null) { return schema; } @@ -145,9 +142,9 @@ Schema toSchema(TypeMirror type) { private Schema buildObjectSchema(TypeMirror type) { - String objectSchemaKey = getObjectSchemaName(type); + final var objectSchemaKey = getObjectSchemaName(type); - Schema objectSchema = schemas.get(objectSchemaKey); + var objectSchema = schemas.get(objectSchemaKey); if (objectSchema == null) { // Put first to resolve recursive stack overflow objectSchema = new ObjectSchema(); @@ -155,7 +152,7 @@ private Schema buildObjectSchema(TypeMirror type) { populateObjectSchema(type, objectSchema); } - Schema ref = new Schema(); + final var ref = new Schema(); ref.$ref("#/components/schemas/" + objectSchemaKey); return ref; } @@ -165,23 +162,23 @@ private Schema buildIterableSchema(TypeMirror type) { Schema itemSchema = new ObjectSchema().format("unknownIterableType"); if (type.getKind() == TypeKind.DECLARED) { - List typeArguments = ((DeclaredType) type).getTypeArguments(); + final List typeArguments = ((DeclaredType) type).getTypeArguments(); if (typeArguments.size() == 1) { itemSchema = toSchema(typeArguments.get(0)); } } - ArraySchema arraySchema = new ArraySchema(); + final var arraySchema = new ArraySchema(); arraySchema.setItems(itemSchema); return arraySchema; } private Schema buildArraySchema(TypeMirror type) { - ArrayType arrayType = (ArrayType) type; - Schema itemSchema = toSchema(arrayType.getComponentType()); + final var arrayType = (ArrayType) type; + final Schema itemSchema = toSchema(arrayType.getComponentType()); - ArraySchema arraySchema = new ArraySchema(); + final var arraySchema = new ArraySchema(); arraySchema.setItems(itemSchema); return arraySchema; } @@ -191,14 +188,14 @@ private Schema buildMapSchema(TypeMirror type) { Schema valueSchema = new ObjectSchema().format("unknownMapValueType"); if (type.getKind() == TypeKind.DECLARED) { - DeclaredType declaredType = (DeclaredType) type; - List typeArguments = declaredType.getTypeArguments(); + final var declaredType = (DeclaredType) type; + final List typeArguments = declaredType.getTypeArguments(); if (typeArguments.size() == 2) { valueSchema = toSchema(typeArguments.get(1)); } } - MapSchema mapSchema = new MapSchema(); + final var mapSchema = new MapSchema(); mapSchema.setAdditionalProperties(valueSchema); return mapSchema; } @@ -214,9 +211,9 @@ private String getObjectSchemaName(TypeMirror type) { } private void populateObjectSchema(TypeMirror objectType, Schema objectSchema) { - Element element = types.asElement(objectType); - for (VariableElement field : allFields(element)) { - Schema propSchema = toSchema(field.asType()); + final var element = types.asElement(objectType); + for (final VariableElement field : allFields(element)) { + final Schema propSchema = toSchema(field.asType()); if (isNotNullable(field)) { propSchema.setNullable(Boolean.FALSE); } @@ -227,52 +224,62 @@ private void populateObjectSchema(TypeMirror objectType, Schema objectSch } private void setFormatFromValidation(Element element, Schema propSchema) { - if (element.getAnnotation(Email.class) != null) { + if (EmailPrism.getOptionalOn(element).isPresent() + || JavaxEmailPrism.getOptionalOn(element).isPresent()) { propSchema.setFormat("email"); } } private void setLengthMinMax(Element element, Schema propSchema) { - final Size size = element.getAnnotation(Size.class); - if (size != null) { - if (size.min() > 0) { - propSchema.setMinLength(size.min()); - } - if (size.max() > 0) { - propSchema.setMaxLength(size.max()); - } - } + + SizePrism.getOptionalOn(element) + .ifPresent( + size -> { + if (size.min() > 0) { + propSchema.setMinLength(size.min()); + } + if (size.max() > 0) { + propSchema.setMaxLength(size.max()); + } + }); + + JavaxSizePrism.getOptionalOn(element) + .ifPresent( + size -> { + if (size.min() > 0) { + propSchema.setMinLength(size.min()); + } + if (size.max() > 0) { + propSchema.setMaxLength(size.max()); + } + }); } private boolean isNotNullable(Element element) { - return element.getAnnotation(org.jetbrains.annotations.NotNull.class) != null - || element.getAnnotation(javax.validation.constraints.NotNull.class) != null; + return element.getAnnotationMirrors().stream() + .anyMatch(m -> m.toString().contains("@") && m.toString().contains("NotNull")); } - /** - * Gather all the fields (properties) for the given bean element. - */ + /** Gather all the fields (properties) for the given bean element. */ private List allFields(Element element) { - List list = new ArrayList<>(); + final List list = new ArrayList<>(); gatherProperties(list, element); return list; } - /** - * Recursively gather all the fields (properties) for the given bean element. - */ + /** Recursively gather all the fields (properties) for the given bean element. */ private void gatherProperties(List fields, Element element) { if (element == null) { return; } if (element instanceof TypeElement) { - Element mappedSuper = types.asElement(((TypeElement) element).getSuperclass()); + final var mappedSuper = types.asElement(((TypeElement) element).getSuperclass()); if (mappedSuper != null && !"java.lang.Object".equals(mappedSuper.toString())) { gatherProperties(fields, mappedSuper); } - for (VariableElement field : ElementFilter.fieldsIn(element.getEnclosedElements())) { + for (final VariableElement field : ElementFilter.fieldsIn(element.getEnclosedElements())) { if (!ignoreField(field)) { fields.add(field); } @@ -280,21 +287,20 @@ private void gatherProperties(List fields, Element element) { } } - /** - * Ignore static or transient fields. - */ + /** Ignore static or transient fields. */ private boolean ignoreField(VariableElement field) { return isStaticOrTransient(field) || isHiddenField(field); } private boolean isHiddenField(VariableElement field) { - Hidden hidden = field.getAnnotation(Hidden.class); - if (hidden != null) { + if (HiddenPrism.getOptionalOn(field).isPresent()) { return true; } - for (AnnotationMirror annotationMirror : field.getAnnotationMirrors()) { - String simpleName = annotationMirror.getAnnotationType().asElement().getSimpleName().toString(); + + for (final AnnotationMirror annotationMirror : field.getAnnotationMirrors()) { + final var simpleName = + annotationMirror.getAnnotationType().asElement().getSimpleName().toString(); if ("JsonIgnore".equals(simpleName)) { return true; } @@ -303,8 +309,7 @@ private boolean isHiddenField(VariableElement field) { } private boolean isStaticOrTransient(VariableElement field) { - Set modifiers = field.getModifiers(); + final var modifiers = field.getModifiers(); return (modifiers.contains(Modifier.STATIC) || modifiers.contains(Modifier.TRANSIENT)); } - } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/package-info.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/package-info.java index 8568feb1f..18896ff2e 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/package-info.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/package-info.java @@ -26,7 +26,8 @@ @GeneratePrism(value = javax.validation.Valid.class, name = "JavaxValidPrism", publicAccess = true) @GeneratePrism(value = jakarta.validation.Valid.class, publicAccess = true) @GeneratePrism(value = org.jetbrains.annotations.NotNull.class, publicAccess = true) - +@GeneratePrism(value = io.avaje.http.api.Client.class, publicAccess = true) +@GeneratePrism(value = io.avaje.http.api.Client.Import.class, publicAccess = true) package io.avaje.http.generator.core; import io.avaje.prism.GeneratePrism; diff --git a/http-generator-core/src/main/java/module-info.java b/http-generator-core/src/main/java/module-info.java index c9db3e787..9e895411f 100644 --- a/http-generator-core/src/main/java/module-info.java +++ b/http-generator-core/src/main/java/module-info.java @@ -6,11 +6,12 @@ requires java.sql; requires java.compiler; - requires static transitive io.avaje.prism; + + // SHADED: All content after this line will be removed at package time + requires static io.avaje.prism; requires static transitive io.avaje.http.api; requires static transitive io.swagger.v3.oas.models; requires static transitive io.swagger.v3.oas.annotations; - requires static transitive com.fasterxml.jackson.annotation; requires static transitive java.validation; requires static transitive jakarta.inject; requires static transitive jakarta.validation; diff --git a/http-generator-helidon/dependency-reduced-pom.xml b/http-generator-helidon/dependency-reduced-pom.xml new file mode 100644 index 000000000..6a78840d8 --- /dev/null +++ b/http-generator-helidon/dependency-reduced-pom.xml @@ -0,0 +1,49 @@ + + + + avaje-http-parent + io.avaje + 1.26-SNAPSHOT + + 4.0.0 + avaje-http-helidon-generator + + + + maven-compiler-plugin + 3.10.1 + + 11 + 11 + -proc:none + + + + + + + io.avaje + junit + 1.1 + test + + + junit-jupiter-api + org.junit.jupiter + + + junit-jupiter-engine + org.junit.jupiter + + + assertj-core + org.assertj + + + mockito-core + org.mockito + + + + + diff --git a/http-generator-helidon/src/etc/activate-shade-module b/http-generator-helidon/src/etc/activate-shade-module new file mode 100644 index 000000000..949f3d244 --- /dev/null +++ b/http-generator-helidon/src/etc/activate-shade-module @@ -0,0 +1 @@ +Remove from module-info all content after: // SHADED: diff --git a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/ControllerMethodWriter.java b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/ControllerMethodWriter.java index a43192644..87f62cf48 100644 --- a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/ControllerMethodWriter.java +++ b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/ControllerMethodWriter.java @@ -1,14 +1,14 @@ package io.avaje.http.generator.helidon; -import io.avaje.http.api.MediaType; +import java.util.List; + import io.avaje.http.generator.core.Append; import io.avaje.http.generator.core.MethodParam; import io.avaje.http.generator.core.MethodReader; import io.avaje.http.generator.core.PathSegments; import io.avaje.http.generator.core.ProcessingContext; import io.avaje.http.generator.core.WebMethod; - -import java.util.List; +import io.avaje.http.generator.core.openapi.MediaType; /** * Write code to register Web route for a given controller method. @@ -96,11 +96,11 @@ private void writeContextReturn() { final String produces = method.produces(); if (produces == null) { // let it be automatically set - } else if (MediaType.APPLICATION_JSON.equalsIgnoreCase(produces)) { + } else if (MediaType.APPLICATION_JSON.getValue().equalsIgnoreCase(produces)) { writer.append(" res.writerContext().contentType(io.helidon.common.http.MediaType.APPLICATION_JSON);").eol(); - } else if (MediaType.TEXT_HTML.equalsIgnoreCase(produces)) { + } else if (MediaType.TEXT_HTML.getValue().equalsIgnoreCase(produces)) { writer.append(" res.writerContext().contentType(io.helidon.common.http.MediaType.TEXT_HTML);").eol(); - } else if (MediaType.TEXT_PLAIN.equalsIgnoreCase(produces)) { + } else if (MediaType.TEXT_PLAIN.getValue().equalsIgnoreCase(produces)) { writer.append(" res.writerContext().contentType(io.helidon.common.http.MediaType.TEXT_PLAIN);").eol(); } else { writer.append(" res.writerContext().contentType(io.helidon.common.http.MediaType.parse(\"%s\"));", produces).eol(); diff --git a/http-generator-helidon/src/main/java/module-info.java b/http-generator-helidon/src/main/java/module-info.java index fce86d176..4b99fdca1 100644 --- a/http-generator-helidon/src/main/java/module-info.java +++ b/http-generator-helidon/src/main/java/module-info.java @@ -2,6 +2,8 @@ provides javax.annotation.processing.Processor with io.avaje.http.generator.helidon.HelidonProcessor; - requires transitive io.avaje.http.generator.core; requires java.compiler; + + // SHADED: All content after this line will be removed at package time + requires transitive io.avaje.http.generator.core; } diff --git a/http-generator-javalin/dependency-reduced-pom.xml b/http-generator-javalin/dependency-reduced-pom.xml index e84b1a938..18b9d7822 100644 --- a/http-generator-javalin/dependency-reduced-pom.xml +++ b/http-generator-javalin/dependency-reduced-pom.xml @@ -13,32 +13,12 @@ maven-compiler-plugin 3.10.1 - 11 - 11 -proc:none - - maven-shade-plugin - 3.4.1 - - - package - - shade - - - - - - io.avaje - avaje-prisms - 1.3-SNAPSHOT - provided - io.avaje junit diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index 061b7cb37..d6b72bdbf 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -22,25 +22,10 @@ maven-compiler-plugin 3.10.1 - 11 - 11 -proc:none - - org.apache.maven.plugins - maven-shade-plugin - 3.4.1 - - - package - - shade - - - - diff --git a/http-generator-javalin/src/etc/activate-shade-module b/http-generator-javalin/src/etc/activate-shade-module new file mode 100644 index 000000000..949f3d244 --- /dev/null +++ b/http-generator-javalin/src/etc/activate-shade-module @@ -0,0 +1 @@ +Remove from module-info all content after: // SHADED: diff --git a/http-generator-javalin/src/main/java/module-info.java b/http-generator-javalin/src/main/java/module-info.java index 86ac9f204..8394c4933 100644 --- a/http-generator-javalin/src/main/java/module-info.java +++ b/http-generator-javalin/src/main/java/module-info.java @@ -2,6 +2,8 @@ provides javax.annotation.processing.Processor with io.avaje.http.generator.javalin.JavalinProcessor; - requires transitive io.avaje.http.generator.core; requires java.compiler; + + // SHADED: All content after this line will be removed at package time + requires transitive io.avaje.http.generator.core; } diff --git a/http-generator-jex/dependency-reduced-pom.xml b/http-generator-jex/dependency-reduced-pom.xml new file mode 100644 index 000000000..bf7b29d36 --- /dev/null +++ b/http-generator-jex/dependency-reduced-pom.xml @@ -0,0 +1,49 @@ + + + + avaje-http-parent + io.avaje + 1.26-SNAPSHOT + + 4.0.0 + avaje-http-jex-generator + + + + maven-compiler-plugin + 3.10.1 + + 11 + 11 + -proc:none + + + + + + + io.avaje + junit + 1.1 + test + + + junit-jupiter-api + org.junit.jupiter + + + junit-jupiter-engine + org.junit.jupiter + + + assertj-core + org.assertj + + + mockito-core + org.mockito + + + + + diff --git a/http-generator-jex/src/etc/activate-shade-module b/http-generator-jex/src/etc/activate-shade-module new file mode 100644 index 000000000..949f3d244 --- /dev/null +++ b/http-generator-jex/src/etc/activate-shade-module @@ -0,0 +1 @@ +Remove from module-info all content after: // SHADED: diff --git a/http-generator-jex/src/main/java/module-info.java b/http-generator-jex/src/main/java/module-info.java index 6f00d4094..56d367564 100644 --- a/http-generator-jex/src/main/java/module-info.java +++ b/http-generator-jex/src/main/java/module-info.java @@ -2,6 +2,8 @@ provides javax.annotation.processing.Processor with io.avaje.http.generator.jex.JexProcessor; - requires transitive io.avaje.http.generator.core; requires java.compiler; + + // SHADED: All content after this line will be removed at package time + requires transitive io.avaje.http.generator.core; } diff --git a/http-generator-nima/src/main/java/module-info.java b/http-generator-nima/src/main/java/module-info.java index 9a1c8873a..a17a78106 100644 --- a/http-generator-nima/src/main/java/module-info.java +++ b/http-generator-nima/src/main/java/module-info.java @@ -2,6 +2,8 @@ provides javax.annotation.processing.Processor with io.avaje.http.generator.helidon.nima.NimaProcessor; - requires transitive io.avaje.http.generator.core; requires java.compiler; + + // SHADED: All content after this line will be removed at package time + requires transitive io.avaje.http.generator.core; } diff --git a/pom.xml b/pom.xml index 429a40921..f6390b136 100644 --- a/pom.xml +++ b/pom.xml @@ -1,5 +1,7 @@ - + 4.0.0 org.avaje @@ -19,11 +21,12 @@ true - 1.1-SNAPSHOT + 2.0.8 + ${project.build.directory}${file.separator}module-info.shade - + io.avaje junit @@ -32,7 +35,6 @@ - http-api http-client @@ -58,7 +60,92 @@ tests + + + + module-info.shade + + + src/etc/activate-shade-module + + + + + + maven-antrun-plugin + 1.7 + + + process-resources + + + + + + + + + run + + + + + + org.apache.maven.plugins + maven-shade-plugin + + + + module-info.java + + + + + io.swagger.core.v3:swagger-models + + io/swagger/v3/oas/models/callbacks/** + io/swagger/v3/oas/models/examples/** + io/swagger/v3/oas/models/security/** + io/swagger/v3/oas/models/servers/** + + + + + + + package + + shade + + + + + + + org.moditect + moditect-maven-plugin + + + add-module-infos + package + + add-module-info + + + true + + ${module-info.shade} + + + + + + + + - + From 32849cd41d417206d6cb138f95bb159372b0c28a Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Fri, 10 Feb 2023 16:05:25 -0500 Subject: [PATCH 0582/1323] Create activate-shade-module --- http-generator-nima/src/etc/activate-shade-module | 1 + 1 file changed, 1 insertion(+) create mode 100644 http-generator-nima/src/etc/activate-shade-module diff --git a/http-generator-nima/src/etc/activate-shade-module b/http-generator-nima/src/etc/activate-shade-module new file mode 100644 index 000000000..949f3d244 --- /dev/null +++ b/http-generator-nima/src/etc/activate-shade-module @@ -0,0 +1 @@ +Remove from module-info all content after: // SHADED: From 7874f661ee08f42c4e195c486e226fe7eadc2a96 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Fri, 10 Feb 2023 16:11:46 -0500 Subject: [PATCH 0583/1323] optional perhaps I like optional too much --- http-generator-client/pom.xml | 2 +- .../dependency-reduced-pom.xml | 4 +- http-generator-core/pom.xml | 4 +- .../http/generator/core/BaseProcessor.java | 1 - .../http/generator/core/ControllerReader.java | 27 ++++---- .../http/generator/core/MethodReader.java | 67 ++++++++----------- .../core/openapi/MethodDocBuilder.java | 4 +- .../dependency-reduced-pom.xml | 55 +++++++++++++++ 8 files changed, 104 insertions(+), 60 deletions(-) create mode 100644 http-generator-nima/dependency-reduced-pom.xml diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index e2852aba2..eec4d9e56 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -20,7 +20,7 @@ io.avaje avaje-http-generator-core - 1.26-SNAPSHOT + ${project.version} diff --git a/http-generator-core/dependency-reduced-pom.xml b/http-generator-core/dependency-reduced-pom.xml index 91ac82e0b..05c14c0fd 100644 --- a/http-generator-core/dependency-reduced-pom.xml +++ b/http-generator-core/dependency-reduced-pom.xml @@ -16,7 +16,7 @@ io.avaje avaje-prisms - 1.3-SNAPSHOT + 1.3 @@ -27,7 +27,7 @@ io.avaje avaje-prisms - 1.3-SNAPSHOT + 1.3 provided true diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 239917e5e..fd23f4db7 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -21,7 +21,7 @@ io.avaje avaje-prisms - 1.3-SNAPSHOT + 1.3 true provided @@ -92,7 +92,7 @@ io.avaje avaje-prisms - 1.3-SNAPSHOT + 1.3 diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java index 7ad8cbc38..735ffc215 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java @@ -13,7 +13,6 @@ import javax.lang.model.element.TypeElement; @SupportedOptions({"useJavax", "useSingleton"}) -@SupportedAnnotationTypes({ControllerPrism.PRISM_TYPE, OpenAPIDefinitionPrism.PRISM_TYPE}) public abstract class BaseProcessor extends AbstractProcessor { protected ProcessingContext ctx; diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java index a430205d9..2493b6274 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java @@ -120,30 +120,30 @@ private List initInterfaceMethods() { return ifaceMethods; } - private A findAnnotation(Function func) { + private Optional findAnnotation(Function> func) { var annotation = func.apply(beanType); - if (annotation != null) { + if (annotation.isPresent()) { return annotation; } for (final Element anInterface : interfaces) { annotation = func.apply(anInterface); - if (annotation != null) { + if (annotation.isPresent()) { return annotation; } } - return null; + return Optional.empty(); } - A findMethodAnnotation(Function func, ExecutableElement element) { + Optional findMethodAnnotation(Function> func, ExecutableElement element) { for (final ExecutableElement interfaceMethod : interfaceMethods) { if (matchMethod(interfaceMethod, element)) { final var annotation = func.apply(interfaceMethod); - if (annotation != null) { + if (annotation.isPresent()) { return annotation; } } } - return null; + return Optional.empty(); } private boolean matchMethod(ExecutableElement interfaceMethod, ExecutableElement element) { @@ -151,18 +151,17 @@ private boolean matchMethod(ExecutableElement interfaceMethod, ExecutableElement } private String initProduces() { - final var produces = findAnnotation(ProducesPrism::getInstanceOn); - return (produces == null) ? null : produces.value(); + return findAnnotation(ProducesPrism::getOptionalOn).map(ProducesPrism::value).orElse(null); } private boolean initDocHidden() { - return findAnnotation(HiddenPrism::getInstanceOn) != null; + return findAnnotation(HiddenPrism::getOptionalOn).isPresent(); } private boolean initHasValid() { - return findAnnotation(JavaxValidPrism::getInstanceOn) != null - || findAnnotation(ValidPrism::getInstanceOn) != null; + return findAnnotation(JavaxValidPrism::getOptionalOn).isPresent() + || findAnnotation(ValidPrism::getOptionalOn).isPresent(); } String produces() { @@ -281,12 +280,12 @@ public List openApiResponses() { public String path() { - return Optional.ofNullable(findAnnotation(ControllerPrism::getInstanceOn)) + return findAnnotation(ControllerPrism::getOptionalOn) .map(ControllerPrism::value) .filter(not(String::isBlank)) .or( () -> - Optional.ofNullable(findAnnotation(PathPrism::getInstanceOn)).map(PathPrism::value)) + findAnnotation(PathPrism::getOptionalOn).map(PathPrism::value)) .map(Util::trimPath) .orElse(null); } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java index cc52542d4..321274da1 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java @@ -53,7 +53,7 @@ public class MethodReader { this.actualParams = (actualExecutable == null) ? null : actualExecutable.getParameterTypes(); this.isVoid = element.getReturnType().getKind() == TypeKind.VOID; this.methodRoles = Util.findRoles(element); - this.producesAnnotation = Optional.ofNullable(findAnnotation(ProducesPrism::getInstanceOn)); + this.producesAnnotation = findAnnotation(ProducesPrism::getOptionalOn); initWebMethodViaAnnotation(); this.superMethods = @@ -85,8 +85,8 @@ private Javadoc buildJavadoc(ExecutableElement element, ProcessingContext ctx) { } private boolean initValid() { - return findAnnotation(ValidPrism::getInstanceOn) != null - || findAnnotation(JavaxValidPrism::getInstanceOn) != null + return findAnnotation(ValidPrism::getOptionalOn).isPresent() + || findAnnotation(JavaxValidPrism::getOptionalOn).isPresent() || superMethodHasValid(); } @@ -94,8 +94,8 @@ private boolean superMethodHasValid() { return superMethods.stream() .anyMatch( e -> - findAnnotation(ValidPrism::getInstanceOn) != null - || findAnnotation(JavaxValidPrism::getInstanceOn) != null); + findAnnotation(ValidPrism::getOptionalOn).isPresent() + || findAnnotation(JavaxValidPrism::getOptionalOn).isPresent()); } @Override @@ -104,34 +104,24 @@ public String toString() { } private void initWebMethodViaAnnotation() { - final var form = findAnnotation(FormPrism::getInstanceOn); - if (form != null) { + + if (findAnnotation(FormPrism::getOptionalOn).isPresent()) { this.formMarker = true; } - final var get = findAnnotation(GetPrism::getInstanceOn); - if (get != null) { - initSetWebMethod(WebMethod.GET, get.value()); - return; - } - final var put = findAnnotation(PutPrism::getInstanceOn); - if (put != null) { - initSetWebMethod(WebMethod.PUT, put.value()); - return; - } - final var post = findAnnotation(PostPrism::getInstanceOn); - if (post != null) { - initSetWebMethod(WebMethod.POST, post.value()); - return; - } - final var patch = findAnnotation(PatchPrism::getInstanceOn); - if (patch != null) { - initSetWebMethod(WebMethod.PATCH, patch.value()); - return; - } - final var delete = findAnnotation(DeletePrism::getInstanceOn); - if (delete != null) { - initSetWebMethod(WebMethod.DELETE, delete.value()); - } + + findAnnotation(GetPrism::getOptionalOn) + .ifPresent(get -> initSetWebMethod(WebMethod.GET, get.value())); + + findAnnotation(PutPrism::getOptionalOn) + .ifPresent(put -> initSetWebMethod(WebMethod.PUT, put.value())); + + findAnnotation(PostPrism::getOptionalOn) + .ifPresent(post -> initSetWebMethod(WebMethod.POST, post.value())); + + findAnnotation(PatchPrism::getOptionalOn) + .ifPresent(patch -> initSetWebMethod(WebMethod.PATCH, patch.value())); + findAnnotation(DeletePrism::getOptionalOn) + .ifPresent(delete -> initSetWebMethod(WebMethod.DELETE, delete.value())); } private void initSetWebMethod(WebMethod webMethod, String value) { @@ -144,8 +134,9 @@ public Javadoc javadoc() { } private List buildApiResponses() { + final var container = - Optional.ofNullable(findAnnotation(OpenAPIResponsesPrism::getInstanceOn)).stream() + findAnnotation(OpenAPIResponsesPrism::getOptionalOn).stream() .map(OpenAPIResponsesPrism::value) .flatMap(List::stream); @@ -157,9 +148,7 @@ private List buildApiResponses() { .flatMap( method -> Stream.concat( - Optional.ofNullable( - findAnnotation(OpenAPIResponsesPrism::getInstanceOn, method)) - .stream() + findAnnotation(OpenAPIResponsesPrism::getOptionalOn, method).stream() .map(OpenAPIResponsesPrism::value) .flatMap(List::stream), OpenAPIResponsePrism.getAllInstancesOn(method).stream())); @@ -168,16 +157,18 @@ private List buildApiResponses() { Stream.concat(methodResponses, superMethodResponses).collect(Collectors.toList()); responses.addAll(bean.openApiResponses()); + return responses; } - public A findAnnotation(Function prismFunc) { + public Optional findAnnotation(Function> prismFunc) { return findAnnotation(prismFunc, element); } - public A findAnnotation(Function prismFunc, ExecutableElement elem) { + public Optional findAnnotation( + Function> prismFunc, ExecutableElement elem) { final var annotation = prismFunc.apply(elem); - if (annotation != null) { + if (annotation.isPresent()) { return annotation; } return bean.findMethodAnnotation(prismFunc, elem); diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/MethodDocBuilder.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/MethodDocBuilder.java index af9016b0b..5ee08005e 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/MethodDocBuilder.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/MethodDocBuilder.java @@ -28,7 +28,7 @@ public MethodDocBuilder(MethodReader methodReader, DocContext ctx) { public void build() { if (ctx.isOpenApiAvailable() - && methodReader.findAnnotation(HiddenPrism::getInstanceOn) != null) { + && methodReader.findAnnotation(HiddenPrism::getOptionalOn).isPresent()) { return; } @@ -38,7 +38,7 @@ public void build() { operation.setTags(methodReader.tags()); if (javadoc.isDeprecated() - || (methodReader.findAnnotation(DeprecatedPrism::getInstanceOn) != null)) { + || methodReader.findAnnotation(DeprecatedPrism::getOptionalOn).isPresent()) { operation.setDeprecated(true); } diff --git a/http-generator-nima/dependency-reduced-pom.xml b/http-generator-nima/dependency-reduced-pom.xml new file mode 100644 index 000000000..0e7245453 --- /dev/null +++ b/http-generator-nima/dependency-reduced-pom.xml @@ -0,0 +1,55 @@ + + + + avaje-http-parent + io.avaje + 1.26-SNAPSHOT + + 4.0.0 + avaje-http-nima-generator + + + + maven-compiler-plugin + 3.10.1 + + 19 + 19 + -proc:none + + + + + + + io.avaje + junit + 1.1 + test + + + junit-jupiter-api + org.junit.jupiter + + + junit-jupiter-engine + org.junit.jupiter + + + assertj-core + org.assertj + + + mockito-core + org.mockito + + + + + + 19 + 19 + UTF-8 + 19 + + From eca86ac68c85cb7d0b3003c76ee229b76d93fb6a Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Fri, 10 Feb 2023 16:13:41 -0500 Subject: [PATCH 0584/1323] Update pom.xml --- http-generator-core/pom.xml | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index fd23f4db7..25dd84c30 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -39,20 +39,20 @@ swagger-models ${swagger.version} - - com.fasterxml.jackson.core - jackson-annotations - + + com.fasterxml.jackson.core + jackson-annotations + - - jakarta.validation - jakarta.validation-api - 3.0.2 - true - provided - + + jakarta.validation + jakarta.validation-api + 3.0.2 + true + provided + javax.validation @@ -62,13 +62,13 @@ provided - - jakarta.inject - jakarta.inject-api - 2.0.1 + + jakarta.inject + jakarta.inject-api + 2.0.1 true provided - + From 59f5c8743a362e7683b75fb01b165289a02b91da Mon Sep 17 00:00:00 2001 From: Haydon Perrin Date: Fri, 10 Feb 2023 23:32:16 +0000 Subject: [PATCH 0585/1323] Added CompletableFuture return type support for Javalin using `Context#future(...)`. --- .../avaje/http/generator/core/JsonBUtil.java | 6 ++++ .../javalin/ControllerMethodWriter.java | 35 +++++++++++++++---- .../generator/javalin/ControllerWriter.java | 8 ++++- 3 files changed, 42 insertions(+), 7 deletions(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java index 1b007f693..d3afdd1d6 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java @@ -50,6 +50,12 @@ private static void addJsonBodyType(MethodReader methodReader, Consumer a } public static void writeJsonbType(UType type, Append writer) { + // Support for CompletableFuture's. + if (type.isGeneric() && type.mainType().equals("java.util.concurrent.CompletableFuture")) { + writeJsonbType(type.paramRaw(), writer); + return; + } + writer.append(" this.%sJsonType = jsonB.type(", type.shortName()); if (!type.isGeneric()) { writer.append("%s.class)", Util.shortName(PrimitiveUtil.wrap(type.full()))); diff --git a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java index 2fbc09c64..0fdd9e68b 100644 --- a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java +++ b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java @@ -85,20 +85,43 @@ void write(boolean requestScoped) { } private void writeContextReturn() { + // Support for CompletableFuture's. + final UType type = UType.parse(method.returnType()); + if (type.isGeneric() && type.mainType().equals("java.util.concurrent.CompletableFuture")) { + final String returnVariableName = "futureResult"; + + writer.append(" ctx.future(() -> {").eol(); + writer.append(" return result.thenAccept(%s -> {", returnVariableName).eol(); + writer.append(" "); + this.writeContextReturn(returnVariableName); + writer.eol().append(" });").eol(); + writer.append(" });").eol(); + return; + } + + // Everything else + this.writeContextReturn("result"); + } + + private void writeContextReturn(final String returnVariableName) { final var produces = method.produces(); if (produces == null || MediaType.APPLICATION_JSON.equalsIgnoreCase(produces)) { if (useJsonB) { - final var uType = UType.parse(method.returnType()); - writer.append(" %sJsonType.toJson(result, ctx.contentType(\"application/json\").outputStream());", uType.shortName()); + var uType = UType.parse(method.returnType()); + if (uType.isGeneric() && uType.mainType().equals("java.util.concurrent.CompletableFuture")) { + uType = uType.paramRaw(); + } + + writer.append(" %sJsonType.toJson(%s, ctx.contentType(\"application/json\").outputStream());", uType.shortName(), returnVariableName); } else { - writer.append(" ctx.json(result);"); + writer.append(" ctx.json(%s);", returnVariableName); } } else if (MediaType.TEXT_HTML.equalsIgnoreCase(produces)) { - writer.append(" ctx.html(result);"); + writer.append(" ctx.html(%s);", returnVariableName); } else if (MediaType.TEXT_PLAIN.equalsIgnoreCase(produces)) { - writer.append(" ctx.contentType(\"text/plain\").result(result);"); + writer.append(" ctx.contentType(\"text/plain\").result(%s);", returnVariableName); } else { - writer.append(" ctx.contentType(\"%s\").result(result);", produces); + writer.append(" ctx.contentType(\"%s\").result(%s);", produces, returnVariableName); } } } diff --git a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java index 09448fc74..e39aa0959 100644 --- a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java +++ b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java @@ -87,7 +87,13 @@ private void writeClassStart() { writer.append(" private final Validator validator;").eol(); } - for (final UType type : jsonTypes.values()) { + for (UType type : jsonTypes.values()) { + // Support for CompletableFuture's. + if (type.isGeneric() && type.mainType().equals("java.util.concurrent.CompletableFuture")) { + type = type.paramRaw(); + } + + // Everything else final var typeString = PrimitiveUtil.wrap(type.shortType()).replace(",", ", "); writer.append(" private final JsonType<%s> %sJsonType;", typeString, type.shortName()).eol(); } From 6e800a0e7e38293d5382c43964842e98769af9f5 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sat, 11 Feb 2023 00:58:13 -0500 Subject: [PATCH 0586/1323] format --- .../dependency-reduced-pom.xml | 52 ---------- .../generator/client/ClientProcessor.java | 33 ++++--- .../dependency-reduced-pom.xml | 97 ------------------- .../http/generator/core/BaseProcessor.java | 23 ++--- .../http/generator/core/ControllerReader.java | 46 +++++---- .../http/generator/core/ElementReader.java | 77 +++++++-------- .../http/generator/core/MethodReader.java | 45 ++++----- .../generator/core/openapi/DocContext.java | 27 ++++-- .../generator/core/openapi/KnownTypes.java | 18 ++-- .../core/openapi/MethodDocBuilder.java | 13 +-- .../core/openapi/SchemaDocBuilder.java | 92 ++++++++++-------- .../dependency-reduced-pom.xml | 49 ---------- .../dependency-reduced-pom.xml | 47 --------- http-generator-javalin/pom.xml | 67 +++++++------ http-generator-jex/dependency-reduced-pom.xml | 49 ---------- .../generator/jex/ControllerMethodWriter.java | 20 ++-- .../dependency-reduced-pom.xml | 55 ----------- .../helidon/nima/ControllerMethodWriter.java | 2 +- pom.xml | 6 +- 19 files changed, 247 insertions(+), 571 deletions(-) delete mode 100644 http-generator-client/dependency-reduced-pom.xml delete mode 100644 http-generator-core/dependency-reduced-pom.xml delete mode 100644 http-generator-helidon/dependency-reduced-pom.xml delete mode 100644 http-generator-javalin/dependency-reduced-pom.xml delete mode 100644 http-generator-jex/dependency-reduced-pom.xml delete mode 100644 http-generator-nima/dependency-reduced-pom.xml diff --git a/http-generator-client/dependency-reduced-pom.xml b/http-generator-client/dependency-reduced-pom.xml deleted file mode 100644 index 5a970065b..000000000 --- a/http-generator-client/dependency-reduced-pom.xml +++ /dev/null @@ -1,52 +0,0 @@ - - - - avaje-http-parent - io.avaje - 1.26-SNAPSHOT - - 4.0.0 - avaje-http-client-generator - - - - maven-compiler-plugin - 3.10.1 - - 11 - 11 - -proc:none - - - - - - - io.avaje - junit - 1.1 - test - - - junit-jupiter-api - org.junit.jupiter - - - junit-jupiter-engine - org.junit.jupiter - - - assertj-core - org.assertj - - - mockito-core - org.mockito - - - - - - 11 - - diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java index ec4256524..bbdd20e7f 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java @@ -1,6 +1,7 @@ package io.avaje.http.generator.client; import java.io.IOException; +import java.io.Writer; import java.util.LinkedHashSet; import java.util.List; import java.util.Set; @@ -14,6 +15,7 @@ import javax.lang.model.element.AnnotationValue; import javax.lang.model.element.Element; import javax.lang.model.element.TypeElement; +import javax.tools.FileObject; import io.avaje.http.generator.core.ClientPrism; import io.avaje.http.generator.core.ControllerReader; @@ -24,8 +26,7 @@ @SupportedAnnotationTypes({ClientPrism.PRISM_TYPE, ImportPrism.PRISM_TYPE}) public class ClientProcessor extends AbstractProcessor { - private static final String METAINF_SERVICES_PROVIDER = - "META-INF/services/io.avaje.http.client.HttpApiProvider"; + private static final String METAINF_SERVICES_PROVIDER = "META-INF/services/io.avaje.http.client.HttpApiProvider"; private final Set generatedClients = new LinkedHashSet<>(); @@ -68,24 +69,24 @@ public boolean process(Set annotations, RoundEnvironment } return false; } - + private void writeServicesFile() { try { - final var metaInfWriter = ctx.createMetaInfWriter(METAINF_SERVICES_PROVIDER); - final var writer = metaInfWriter.openWriter(); - for (final String generatedClient : generatedClients) { + final FileObject metaInfWriter = ctx.createMetaInfWriter(METAINF_SERVICES_PROVIDER); + final Writer writer = metaInfWriter.openWriter(); + for (String generatedClient : generatedClients) { writer.append(generatedClient).append("$Provider\n"); } writer.close(); - } catch (final IOException e) { + } catch (IOException e) { ctx.logError(null, "Error writing services file " + e, e); } } private void writeForImported(Element importedElement) { - for (final AnnotationMirror annotationMirror : importedElement.getAnnotationMirrors()) { - for (final AnnotationValue value : annotationMirror.getElementValues().values()) { - for (final Object apiClassDef : (List) value.getValue()) { + for (AnnotationMirror annotationMirror : importedElement.getAnnotationMirrors()) { + for (AnnotationValue value : annotationMirror.getElementValues().values()) { + for (Object apiClassDef : (List) value.getValue()) { writeImported(apiClassDef.toString()); } } @@ -94,8 +95,8 @@ private void writeForImported(Element importedElement) { private void writeImported(String fullName) { // trim .class suffix - final var apiClassName = fullName.substring(0, fullName.length() - 6); - final var typeElement = ctx.typeElement(apiClassName); + String apiClassName = fullName.substring(0, fullName.length() - 6); + TypeElement typeElement = ctx.typeElement(apiClassName); if (typeElement != null) { writeClient(typeElement); } @@ -103,19 +104,19 @@ private void writeImported(String fullName) { private void writeClient(Element controller) { if (controller instanceof TypeElement) { - final var reader = new ControllerReader((TypeElement) controller, ctx); + ControllerReader reader = new ControllerReader((TypeElement) controller, ctx); reader.read(false); try { generatedClients.add(writeClientAdapter(ctx, reader)); - } catch (final Throwable e) { + } catch (Throwable e) { e.printStackTrace(); ctx.logError(reader.beanType(), "Failed to write client class " + e); } } } - protected String writeClientAdapter(ProcessingContext ctx, ControllerReader reader) - throws IOException { + protected String writeClientAdapter(ProcessingContext ctx, ControllerReader reader) throws IOException { return new ClientWriter(reader, ctx, useJsonB).write(); } + } diff --git a/http-generator-core/dependency-reduced-pom.xml b/http-generator-core/dependency-reduced-pom.xml deleted file mode 100644 index 05c14c0fd..000000000 --- a/http-generator-core/dependency-reduced-pom.xml +++ /dev/null @@ -1,97 +0,0 @@ - - - - avaje-http-parent - io.avaje - 1.26-SNAPSHOT - - 4.0.0 - avaje-http-generator-core - - - - maven-compiler-plugin - - - - io.avaje - avaje-prisms - 1.3 - - - - - - - - - io.avaje - avaje-prisms - 1.3 - provided - true - - - io.avaje - avaje-http-api - 1.26-SNAPSHOT - provided - true - - - jakarta.validation - jakarta.validation-api - 3.0.2 - provided - true - - - javax.validation - validation-api - 2.0.1.Final - provided - true - - - jakarta.inject - jakarta.inject-api - 2.0.1 - provided - true - - - io.swagger.core.v3 - swagger-annotations - 2.0.8 - provided - true - - - io.avaje - junit - 1.1 - test - - - junit-jupiter-api - org.junit.jupiter - - - junit-jupiter-engine - org.junit.jupiter - - - assertj-core - org.assertj - - - mockito-core - org.mockito - - - - - - 2.0.8 - - diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java index 735ffc215..bc4fe60d6 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java @@ -6,7 +6,6 @@ import javax.annotation.processing.AbstractProcessor; import javax.annotation.processing.ProcessingEnvironment; import javax.annotation.processing.RoundEnvironment; -import javax.annotation.processing.SupportedAnnotationTypes; import javax.annotation.processing.SupportedOptions; import javax.lang.model.SourceVersion; import javax.lang.model.element.Element; @@ -46,7 +45,7 @@ public boolean process(Set annotations, RoundEnvironment final Set controllers = round.getElementsAnnotatedWith(ctx.typeElement(ControllerPrism.PRISM_TYPE)); - for (final Element controller : controllers) { + for (Element controller : controllers) { writeControllerAdapter(controller); } @@ -59,7 +58,7 @@ public boolean process(Set annotations, RoundEnvironment private void readOpenApiDefinition(RoundEnvironment round) { final Set elements = round.getElementsAnnotatedWith(ctx.typeElement(OpenAPIDefinitionPrism.PRISM_TYPE)); - for (final Element element : elements) { + for (Element element : elements) { ctx.doc().readApiDefinition(element); } } @@ -67,34 +66,36 @@ private void readOpenApiDefinition(RoundEnvironment round) { private void readTagDefinitions(RoundEnvironment round) { Set elements = round.getElementsAnnotatedWith(ctx.typeElement(TagPrism.PRISM_TYPE)); - for (final Element element : elements) { + for (Element element : elements) { ctx.doc().addTagDefinition(element); } elements = round.getElementsAnnotatedWith(ctx.typeElement(TagsPrism.PRISM_TYPE)); - for (final Element element : elements) { + for (Element element : elements) { ctx.doc().addTagsDefinition(element); } } - + private void writeOpenAPI() { ctx.doc().writeApi(); } private void writeControllerAdapter(Element controller) { if (controller instanceof TypeElement) { - final var reader = new ControllerReader((TypeElement) controller, ctx); + ControllerReader reader = new ControllerReader((TypeElement) controller, ctx); reader.read(true); try { writeControllerAdapter(ctx, reader); - } catch (final Throwable e) { + } catch (Throwable e) { e.printStackTrace(); ctx.logError(reader.beanType(), "Failed to write $Route class " + e); } } } - /** Write the adapter code for the given controller. */ - public abstract void writeControllerAdapter(ProcessingContext ctx, ControllerReader reader) - throws IOException; + /** + * Write the adapter code for the given controller. + */ + public abstract void writeControllerAdapter(ProcessingContext ctx, ControllerReader reader) throws IOException; + } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java index 2493b6274..79c87c7d9 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java @@ -18,8 +18,9 @@ import javax.lang.model.type.TypeKind; import javax.lang.model.type.TypeMirror; import javax.lang.model.util.ElementFilter; - -/** Reads the type information for the Controller (bean). */ +/** + * Reads the type information for the Controller (bean). + */ public final class ControllerReader { private final ProcessingContext ctx; @@ -38,9 +39,10 @@ public final class ControllerReader { private final boolean hasValid; private boolean methodHasValid; - /** Flag set when the controller is dependent on a request scope type. */ + /** + * Flag set when the controller is dependent on a request scope type. + */ private boolean requestScope; - private boolean docHidden; public ControllerReader(TypeElement beanType, ProcessingContext ctx) { @@ -100,9 +102,9 @@ void addImports(boolean withSingleton) { } private List initInterfaces() { - final List interfaces = new ArrayList<>(); - for (final TypeMirror anInterface : beanType.getInterfaces()) { - final var ifaceElement = ctx.asElement(anInterface); + List interfaces = new ArrayList<>(); + for (TypeMirror anInterface : beanType.getInterfaces()) { + final Element ifaceElement = ctx.asElement(anInterface); final var controller = ControllerPrism.getInstanceOn(ifaceElement); if (controller != null && !controller.value().isBlank() || PathPrism.getInstanceOn(ifaceElement) != null) { @@ -113,8 +115,8 @@ private List initInterfaces() { } private List initInterfaceMethods() { - final List ifaceMethods = new ArrayList<>(); - for (final Element anInterface : interfaces) { + List ifaceMethods = new ArrayList<>(); + for (Element anInterface : interfaces) { ifaceMethods.addAll(ElementFilter.methodsIn(anInterface.getEnclosedElements())); } return ifaceMethods; @@ -185,8 +187,8 @@ public boolean hasValid() { } /** - * Return true if the controller has request scoped dependencies. In that case a BeanFactory will - * have been generated. + * Return true if the controller has request scoped dependencies. + * In that case a BeanFactory will have been generated. */ boolean isRequestScoped() { return requestScope; @@ -196,7 +198,7 @@ public void read(boolean withSingleton) { if (!roles.isEmpty()) { ctx.platform().controllerRoles(roles, this); } - for (final Element element : beanType.getEnclosedElements()) { + for (Element element : beanType.getEnclosedElements()) { if (element.getKind() == ElementKind.METHOD) { readMethod((ExecutableElement) element); } else if (element.getKind() == ElementKind.FIELD) { @@ -213,7 +215,7 @@ private void deriveIncludeValidation() { } private boolean methodHasValid() { - for (final MethodReader method : methods) { + for (MethodReader method : methods) { if (method.hasValid()) { return true; } @@ -223,19 +225,21 @@ private boolean methodHasValid() { private void readField(Element element) { if (!requestScope) { - final var rawType = element.asType().toString(); + final String rawType = element.asType().toString(); requestScope = RequestScopeTypes.isRequestType(rawType); } } - /** Read methods from superclasses taking into account generics. */ + /** + * Read methods from superclasses taking into account generics. + */ private void readSuper(TypeElement beanType) { - final var superclass = beanType.getSuperclass(); + TypeMirror superclass = beanType.getSuperclass(); if (superclass.getKind() != TypeKind.NONE) { - final var declaredType = (DeclaredType) superclass; - final var superElement = ctx.asElement(superclass); + DeclaredType declaredType = (DeclaredType) superclass; + final Element superElement = ctx.asElement(superclass); if (!"java.lang.Object".equals(superElement.toString())) { - for (final Element element : superElement.getEnclosedElements()) { + for (Element element : superElement.getEnclosedElements()) { if (element.getKind() == ElementKind.METHOD) { readMethod((ExecutableElement) element, declaredType); } else if (element.getKind() == ElementKind.FIELD) { @@ -259,7 +263,7 @@ private void readMethod(ExecutableElement method, DeclaredType declaredType) { // actual taking into account generics actualExecutable = (ExecutableType) ctx.asMemberOf(declaredType, method); } - final var methodReader = new MethodReader(this, method, actualExecutable, ctx); + MethodReader methodReader = new MethodReader(this, method, actualExecutable, ctx); if (methodReader.isWebMethod()) { methodReader.read(); methods.add(methodReader); @@ -297,7 +301,7 @@ public void addImportType(String rawType) { } public void addImportTypes(Set types) { - for (final String type : types) { + for (String type : types) { addImportType(type); } } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java index 80084b33e..17be7aca6 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java @@ -3,6 +3,7 @@ import static io.avaje.http.generator.core.ParamType.RESPONSE_HANDLER; import javax.lang.model.element.Element; +import javax.lang.model.element.TypeElement; import io.avaje.http.generator.core.openapi.MethodDocBuilder; import io.avaje.http.generator.core.openapi.MethodParamDocBuilder; @@ -28,19 +29,13 @@ public class ElementReader { private String paramDefault; private boolean notNullKotlin; - // private boolean notNullJavax; + //private boolean notNullJavax; ElementReader(Element element, ProcessingContext ctx, ParamType defaultType, boolean formMarker) { this(element, null, Util.typeDef(element.asType()), ctx, defaultType, formMarker); } - ElementReader( - Element element, - UType type, - String rawType, - ProcessingContext ctx, - ParamType defaultType, - boolean formMarker) { + ElementReader(Element element, UType type, String rawType, ProcessingContext ctx, ParamType defaultType, boolean formMarker) { this.ctx = ctx; this.element = element; this.type = type; @@ -173,7 +168,7 @@ private String handlerShortType() { void addImports(ControllerReader bean) { if (typeHandler != null) { - final var importType = typeHandler.importType(); + String importType = typeHandler.importType(); if (importType != null) { bean.addImportType(rawType); } @@ -190,7 +185,9 @@ void writeParamName(Append writer) { } } - /** Build the OpenAPI documentation for this parameter. */ + /** + * Build the OpenAPI documentation for this parameter. + */ void buildApiDocumentation(MethodDocBuilder methodDoc) { if (!isPlatformContext()) { new MethodParamDocBuilder(methodDoc, this).build(); @@ -214,7 +211,7 @@ void writeCtxGet(Append writer, PathSegments segments) { // body passed as method parameter (Helidon) return; } - final var shortType = handlerShortType(); + String shortType = handlerShortType(); writer.append("%s var %s = ", ctx.platform().indent(), varName); if (setValue(writer, segments, shortType)) { writer.append(";").eol(); @@ -226,15 +223,15 @@ void setValue(Append writer) { } private boolean setValue(Append writer, PathSegments segments, String shortType) { - // if (formMarker && impliedParamType && typeHandler == null) { - // if (ParamType.FORM != paramType) { - // throw new IllegalStateException("Don't get here?"); - // } - //// // @Form on method and this type is a "bean" so treat is as a form bean - //// writeForm(writer, shortType, varName, ParamType.FORMPARAM); - //// paramType = ParamType.FORM; - //// return false; - // } +// if (formMarker && impliedParamType && typeHandler == null) { +// if (ParamType.FORM != paramType) { +// throw new IllegalStateException("Don't get here?"); +// } +//// // @Form on method and this type is a "bean" so treat is as a form bean +//// writeForm(writer, shortType, varName, ParamType.FORMPARAM); +//// paramType = ParamType.FORM; +//// return false; +// } if (ParamType.FORM == paramType) { writeForm(writer, shortType, varName, ParamType.FORMPARAM); return false; @@ -244,12 +241,12 @@ private boolean setValue(Append writer, PathSegments segments, String shortType) return false; } if (impliedParamType) { - final var name = matrixParamName != null ? matrixParamName : varName; - final var segment = segments.segment(name); + var name = matrixParamName != null ? matrixParamName : varName; + PathSegments.Segment segment = segments.segment(name); if (segment != null) { // path or matrix parameter - final var requiredParam = segment.isRequired(varName); - final var asMethod = + boolean requiredParam = segment.isRequired(varName); + String asMethod = (typeHandler == null) ? null : (requiredParam) ? typeHandler.asMethod() : typeHandler.toMethod(); @@ -265,7 +262,7 @@ private boolean setValue(Append writer, PathSegments segments, String shortType) } } - final var asMethod = (typeHandler == null) ? null : typeHandler.toMethod(); + String asMethod = (typeHandler == null) ? null : typeHandler.toMethod(); if (asMethod != null) { writer.append(asMethod); } @@ -274,18 +271,19 @@ private boolean setValue(Append writer, PathSegments segments, String shortType) // this is a body (POST, PATCH) writer.append(ctx.platform().bodyAsClass(type)); - } else if (hasParamDefault()) { - ctx.platform().writeReadParameter(writer, paramType, paramName, paramDefault); } else { - final var checkNull = - notNullKotlin || (paramType == ParamType.FORMPARAM && typeHandler.isPrimitive()); - if (checkNull) { - writer.append("checkNull("); - } - ctx.platform().writeReadParameter(writer, paramType, paramName); - // writer.append("ctx.%s(\"%s\")", paramType, paramName); - if (checkNull) { - writer.append(", \"%s\")", paramName); + if (hasParamDefault()) { + ctx.platform().writeReadParameter(writer, paramType, paramName, paramDefault); + } else { + boolean checkNull = notNullKotlin || (paramType == ParamType.FORMPARAM && typeHandler.isPrimitive()); + if (checkNull) { + writer.append("checkNull("); + } + ctx.platform().writeReadParameter(writer, paramType, paramName); + //writer.append("ctx.%s(\"%s\")", paramType, paramName); + if (checkNull) { + writer.append(", \"%s\")", paramName); + } } } @@ -295,10 +293,9 @@ private boolean setValue(Append writer, PathSegments segments, String shortType) return true; } - private void writeForm( - Append writer, String shortType, String varName, ParamType defaultParamType) { - final var formBeanType = ctx.typeElement(rawType); - final var form = new BeanParamReader(ctx, formBeanType, varName, shortType, defaultParamType); + private void writeForm(Append writer, String shortType, String varName, ParamType defaultParamType) { + TypeElement formBeanType = ctx.typeElement(rawType); + BeanParamReader form = new BeanParamReader(ctx, formBeanType, varName, shortType, defaultParamType); form.write(writer); } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java index 321274da1..1920a42f2 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java @@ -26,9 +26,10 @@ public class MethodReader { private final boolean isVoid; private final List params = new ArrayList<>(); private final Javadoc javadoc; - /** Holds enum Roles that are required for the method. */ + /** + * Holds enum Roles that are required for the method. + */ private final List methodRoles; - private final Optional producesAnnotation; private final List apiResponses; private final ExecutableType actualExecutable; @@ -41,11 +42,7 @@ public class MethodReader { private String webMethodPath; private boolean formMarker; - MethodReader( - ControllerReader bean, - ExecutableElement element, - ExecutableType actualExecutable, - ProcessingContext ctx) { + MethodReader(ControllerReader bean, ExecutableElement element, ExecutableType actualExecutable, ProcessingContext ctx) { this.ctx = ctx; this.bean = bean; this.element = element; @@ -165,13 +162,9 @@ public Optional findAnnotation(Function> prismFunc) return findAnnotation(prismFunc, element); } - public Optional findAnnotation( - Function> prismFunc, ExecutableElement elem) { - final var annotation = prismFunc.apply(elem); - if (annotation.isPresent()) { - return annotation; - } - return bean.findMethodAnnotation(prismFunc, elem); + public Optional findAnnotation(Function> prismFunc, ExecutableElement elem) { + + return prismFunc.apply(elem).or(() -> bean.findMethodAnnotation(prismFunc, elem)); } private List addTagsToList(Element element, List list) { @@ -203,20 +196,20 @@ void read() { } // non-path parameters default to form or query parameters based on the // existence of @Form annotation on the method - final var defaultParamType = (formMarker) ? ParamType.FORMPARAM : ParamType.QUERYPARAM; + ParamType defaultParamType = (formMarker) ? ParamType.FORMPARAM : ParamType.QUERYPARAM; final List parameters = element.getParameters(); - for (var i = 0; i < parameters.size(); i++) { - final VariableElement p = parameters.get(i); + for (int i = 0; i < parameters.size(); i++) { + VariableElement p = parameters.get(i); TypeMirror typeMirror; if (actualParams != null) { typeMirror = actualParams.get(i); } else { typeMirror = p.asType(); } - final var rawType = Util.typeDef(typeMirror); - final var type = Util.parse(typeMirror.toString()); - final var param = new MethodParam(p, type, rawType, ctx, defaultParamType, formMarker); + String rawType = Util.typeDef(typeMirror); + UType type = Util.parse(typeMirror.toString()); + MethodParam param = new MethodParam(p, type, rawType, ctx, defaultParamType, formMarker); params.add(param); param.addImports(bean); } @@ -226,13 +219,15 @@ public void buildApiDoc() { buildApiDocumentation(ctx); } - /** Build the OpenAPI documentation for the method / operation. */ + /** + * Build the OpenAPI documentation for the method / operation. + */ public void buildApiDocumentation(ProcessingContext ctx) { new MethodDocBuilder(this, ctx.doc()).build(); } public List roles() { - final var roles = new ArrayList<>(methodRoles); + var roles = new ArrayList<>(methodRoles); roles.addAll(bean.roles()); return roles; } @@ -305,7 +300,7 @@ public String simpleName() { } public boolean isFormBody() { - for (final MethodParam param : params) { + for (MethodParam param : params) { if (param.isForm()) { return true; } @@ -314,7 +309,7 @@ public boolean isFormBody() { } public String bodyType() { - for (final MethodParam param : params) { + for (MethodParam param : params) { if (param.isBody()) { return param.shortType(); } @@ -323,7 +318,7 @@ public String bodyType() { } public String bodyName() { - for (final MethodParam param : params) { + for (MethodParam param : params) { if (param.isBody()) { return param.name(); } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/DocContext.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/DocContext.java index 2f26605b1..21ba26192 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/DocContext.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/DocContext.java @@ -9,9 +9,11 @@ import javax.annotation.processing.Messager; import javax.annotation.processing.ProcessingEnvironment; import javax.lang.model.element.Element; +import javax.lang.model.element.TypeElement; import javax.lang.model.type.TypeMirror; import javax.lang.model.util.Elements; import javax.tools.Diagnostic; +import javax.tools.FileObject; import javax.tools.StandardLocation; import io.avaje.http.generator.core.OpenAPIDefinitionPrism; @@ -59,10 +61,10 @@ public boolean isOpenApiAvailable() { private OpenAPI initOpenAPI() { - final var openAPI = new OpenAPI(); + OpenAPI openAPI = new OpenAPI(); openAPI.setPaths(new Paths()); - final var info = new Info(); + Info info = new Info(); info.setTitle(""); info.setVersion(""); openAPI.setInfo(info); @@ -71,7 +73,7 @@ private OpenAPI initOpenAPI() { } Schema toSchema(String rawType, Element element) { - final var typeElement = elements.getTypeElement(rawType); + TypeElement typeElement = elements.getTypeElement(rawType); if (typeElement == null) { // primitive types etc return schemaBuilder.toSchema(element.asType()); @@ -96,16 +98,18 @@ void addRequestBody(Operation operation, Schema schema, boolean asForm, String d schemaBuilder.addRequestBody(operation, schema, asForm, description); } - /** Return the OpenAPI adding the paths and schemas. */ + /** + * Return the OpenAPI adding the paths and schemas. + */ private OpenAPI getApiForWriting() { - var paths = openAPI.getPaths(); + Paths paths = openAPI.getPaths(); if (paths == null) { paths = new Paths(); openAPI.setPaths(paths); } // add paths by natural order - for (final Map.Entry entry : pathMap.entrySet()) { + for (Map.Entry entry : pathMap.entrySet()) { paths.addPathItem(entry.getKey(), entry.getValue()); } @@ -113,9 +117,11 @@ private OpenAPI getApiForWriting() { return openAPI; } - /** Return the components creating if needed. */ + /** + * Return the components creating if needed. + */ private Components components() { - var components = openAPI.getComponents(); + Components components = openAPI.getComponents(); if (components == null) { components = new Components(); openAPI.setComponents(components); @@ -136,7 +142,7 @@ public void addTagsDefinition(Element element) { final var tags = TagsPrism.getInstanceOn(element); if (tags == null) return; - for (final var tag : tags.value()) { + for(var tag : tags.value()){ openAPI.addTagsItem(createTagItem(tag)); } } @@ -161,6 +167,7 @@ public void readApiDefinition(Element element) { if (!info.version().isEmpty()) { openAPI.getInfo().setVersion(info.version()); } + } public void writeApi() { @@ -178,7 +185,7 @@ public void writeApi() { } private Writer createMetaWriter() throws IOException { - final var writer = filer.createResource(StandardLocation.CLASS_OUTPUT, "meta", "openapi.json"); + FileObject writer = filer.createResource(StandardLocation.CLASS_OUTPUT, "meta", "openapi.json"); return writer.openWriter(); } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/KnownTypes.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/KnownTypes.java index 7f228050d..2a0e549c3 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/KnownTypes.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/KnownTypes.java @@ -1,14 +1,5 @@ package io.avaje.http.generator.core.openapi; -import io.swagger.v3.oas.models.media.BooleanSchema; -import io.swagger.v3.oas.models.media.DateSchema; -import io.swagger.v3.oas.models.media.DateTimeSchema; -import io.swagger.v3.oas.models.media.FileSchema; -import io.swagger.v3.oas.models.media.IntegerSchema; -import io.swagger.v3.oas.models.media.NumberSchema; -import io.swagger.v3.oas.models.media.Schema; -import io.swagger.v3.oas.models.media.StringSchema; - import java.io.File; import java.math.BigDecimal; import java.math.BigInteger; @@ -24,6 +15,15 @@ import java.util.Map; import java.util.UUID; +import io.swagger.v3.oas.models.media.BooleanSchema; +import io.swagger.v3.oas.models.media.DateSchema; +import io.swagger.v3.oas.models.media.DateTimeSchema; +import io.swagger.v3.oas.models.media.FileSchema; +import io.swagger.v3.oas.models.media.IntegerSchema; +import io.swagger.v3.oas.models.media.NumberSchema; +import io.swagger.v3.oas.models.media.Schema; +import io.swagger.v3.oas.models.media.StringSchema; + /** * Helper to translate known Java types to OpenAPI Schema. */ diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/MethodDocBuilder.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/MethodDocBuilder.java index 5ee08005e..813d87838 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/MethodDocBuilder.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/MethodDocBuilder.java @@ -6,6 +6,7 @@ import io.avaje.http.generator.core.javadoc.Javadoc; import io.avaje.prism.GeneratePrism; import io.swagger.v3.oas.models.Operation; +import io.swagger.v3.oas.models.PathItem; import io.swagger.v3.oas.models.responses.ApiResponse; import io.swagger.v3.oas.models.responses.ApiResponses; @@ -32,7 +33,7 @@ public void build() { return; } - // operation.setOperationId(); + //operation.setOperationId(); operation.setSummary(javadoc.getSummary()); operation.setDescription(javadoc.getDescription()); operation.setTags(methodReader.tags()); @@ -42,7 +43,7 @@ public void build() { operation.setDeprecated(true); } - final var pathItem = ctx.pathItem(methodReader.fullPath()); + PathItem pathItem = ctx.pathItem(methodReader.fullPath()); switch (methodReader.webMethod()) { case GET: pathItem.setGet(operation); @@ -61,14 +62,14 @@ public void build() { break; } - for (final MethodParam param : methodReader.params()) { + for (MethodParam param : methodReader.params()) { param.buildApiDocumentation(this); } - final var responses = new ApiResponses(); + ApiResponses responses = new ApiResponses(); operation.setResponses(responses); - final var response = new ApiResponse(); + ApiResponse response = new ApiResponse(); response.setDescription(javadoc.getReturnDescription()); final var produces = methodReader.produces(); @@ -80,7 +81,7 @@ public void build() { response.setDescription("No content"); } } else { - response.setContent(ctx.createContent(methodReader.returnType(), contentMediaType)); + response.setContent(ctx.createContent(methodReader.returnType(), contentMediaType)); } var override2xx = false; for (final var responseAnnotation : methodReader.apiResponses()) { diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/SchemaDocBuilder.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/SchemaDocBuilder.java index 5c26f5445..9c3ee4a0e 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/SchemaDocBuilder.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/SchemaDocBuilder.java @@ -5,6 +5,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.TreeMap; import javax.lang.model.element.AnnotationMirror; @@ -33,8 +34,8 @@ import io.swagger.v3.oas.models.parameters.RequestBody; /** Help build OpenAPI Schema objects. */ -@GeneratePrism(value = jakarta.validation.constraints.Size.class) -@GeneratePrism(value = jakarta.validation.constraints.Email.class) +@GeneratePrism(jakarta.validation.constraints.Size.class) +@GeneratePrism(jakarta.validation.constraints.Email.class) @GeneratePrism(value = javax.validation.constraints.Size.class, name = "JavaxSizePrism") @GeneratePrism(value = javax.validation.constraints.Email.class, name = "JavaxEmailPrism") class SchemaDocBuilder { @@ -61,24 +62,26 @@ Map getSchemas() { } Content createContent(TypeMirror returnType, String mediaType) { - final var mt = new MediaType(); + MediaType mt = new MediaType(); mt.setSchema(toSchema(returnType)); - final var content = new Content(); + Content content = new Content(); content.addMediaType(mediaType, mt); return content; } - /** Add parameter as a form parameter. */ + /** + * Add parameter as a form parameter. + */ void addFormParam(Operation operation, String varName, Schema schema) { - final var body = requestBody(operation); - final var formSchema = requestFormParamSchema(body); + RequestBody body = requestBody(operation); + Schema formSchema = requestFormParamSchema(body); formSchema.addProperties(varName, schema); } private Schema requestFormParamSchema(RequestBody body) { - final var content = body.getContent(); - var mediaType = content.get(APP_FORM); + final Content content = body.getContent(); + MediaType mediaType = content.get(APP_FORM); Schema schema; if (mediaType != null) { @@ -93,26 +96,28 @@ private Schema requestFormParamSchema(RequestBody body) { return schema; } - /** Add as request body. */ + /** + * Add as request body. + */ void addRequestBody(Operation operation, Schema schema, boolean asForm, String description) { - final var body = requestBody(operation); + RequestBody body = requestBody(operation); body.setDescription(description); - final var mt = new MediaType(); + MediaType mt = new MediaType(); mt.schema(schema); - final var mime = asForm ? APP_FORM : APP_JSON; + String mime = asForm ? APP_FORM : APP_JSON; body.getContent().addMediaType(mime, mt); } private RequestBody requestBody(Operation operation) { - var body = operation.getRequestBody(); + RequestBody body = operation.getRequestBody(); if (body == null) { body = new RequestBody(); body.setRequired(true); - final var content = new Content(); + Content content = new Content(); body.setContent(content); operation.setRequestBody(body); } @@ -121,7 +126,7 @@ private RequestBody requestBody(Operation operation) { Schema toSchema(TypeMirror type) { - final Schema schema = knownTypes.createSchema(typeDef(type)); + Schema schema = knownTypes.createSchema(typeDef(type)); if (schema != null) { return schema; } @@ -142,9 +147,9 @@ Schema toSchema(TypeMirror type) { private Schema buildObjectSchema(TypeMirror type) { - final var objectSchemaKey = getObjectSchemaName(type); + String objectSchemaKey = getObjectSchemaName(type); - var objectSchema = schemas.get(objectSchemaKey); + Schema objectSchema = schemas.get(objectSchemaKey); if (objectSchema == null) { // Put first to resolve recursive stack overflow objectSchema = new ObjectSchema(); @@ -152,7 +157,7 @@ private Schema buildObjectSchema(TypeMirror type) { populateObjectSchema(type, objectSchema); } - final var ref = new Schema(); + Schema ref = new Schema(); ref.$ref("#/components/schemas/" + objectSchemaKey); return ref; } @@ -162,23 +167,23 @@ private Schema buildIterableSchema(TypeMirror type) { Schema itemSchema = new ObjectSchema().format("unknownIterableType"); if (type.getKind() == TypeKind.DECLARED) { - final List typeArguments = ((DeclaredType) type).getTypeArguments(); + List typeArguments = ((DeclaredType) type).getTypeArguments(); if (typeArguments.size() == 1) { itemSchema = toSchema(typeArguments.get(0)); } } - final var arraySchema = new ArraySchema(); + ArraySchema arraySchema = new ArraySchema(); arraySchema.setItems(itemSchema); return arraySchema; } private Schema buildArraySchema(TypeMirror type) { - final var arrayType = (ArrayType) type; - final Schema itemSchema = toSchema(arrayType.getComponentType()); + ArrayType arrayType = (ArrayType) type; + Schema itemSchema = toSchema(arrayType.getComponentType()); - final var arraySchema = new ArraySchema(); + ArraySchema arraySchema = new ArraySchema(); arraySchema.setItems(itemSchema); return arraySchema; } @@ -188,14 +193,14 @@ private Schema buildMapSchema(TypeMirror type) { Schema valueSchema = new ObjectSchema().format("unknownMapValueType"); if (type.getKind() == TypeKind.DECLARED) { - final var declaredType = (DeclaredType) type; - final List typeArguments = declaredType.getTypeArguments(); + DeclaredType declaredType = (DeclaredType) type; + List typeArguments = declaredType.getTypeArguments(); if (typeArguments.size() == 2) { valueSchema = toSchema(typeArguments.get(1)); } } - final var mapSchema = new MapSchema(); + MapSchema mapSchema = new MapSchema(); mapSchema.setAdditionalProperties(valueSchema); return mapSchema; } @@ -211,9 +216,9 @@ private String getObjectSchemaName(TypeMirror type) { } private void populateObjectSchema(TypeMirror objectType, Schema objectSchema) { - final var element = types.asElement(objectType); - for (final VariableElement field : allFields(element)) { - final Schema propSchema = toSchema(field.asType()); + Element element = types.asElement(objectType); + for (VariableElement field : allFields(element)) { + Schema propSchema = toSchema(field.asType()); if (isNotNullable(field)) { propSchema.setNullable(Boolean.FALSE); } @@ -260,26 +265,30 @@ private boolean isNotNullable(Element element) { .anyMatch(m -> m.toString().contains("@") && m.toString().contains("NotNull")); } - /** Gather all the fields (properties) for the given bean element. */ + /** + * Gather all the fields (properties) for the given bean element. + */ private List allFields(Element element) { - final List list = new ArrayList<>(); + List list = new ArrayList<>(); gatherProperties(list, element); return list; } - /** Recursively gather all the fields (properties) for the given bean element. */ + /** + * Recursively gather all the fields (properties) for the given bean element. + */ private void gatherProperties(List fields, Element element) { if (element == null) { return; } if (element instanceof TypeElement) { - final var mappedSuper = types.asElement(((TypeElement) element).getSuperclass()); + Element mappedSuper = types.asElement(((TypeElement) element).getSuperclass()); if (mappedSuper != null && !"java.lang.Object".equals(mappedSuper.toString())) { gatherProperties(fields, mappedSuper); } - for (final VariableElement field : ElementFilter.fieldsIn(element.getEnclosedElements())) { + for (VariableElement field : ElementFilter.fieldsIn(element.getEnclosedElements())) { if (!ignoreField(field)) { fields.add(field); } @@ -287,7 +296,9 @@ private void gatherProperties(List fields, Element element) { } } - /** Ignore static or transient fields. */ + /** + * Ignore static or transient fields. + */ private boolean ignoreField(VariableElement field) { return isStaticOrTransient(field) || isHiddenField(field); } @@ -297,10 +308,8 @@ private boolean isHiddenField(VariableElement field) { if (HiddenPrism.getOptionalOn(field).isPresent()) { return true; } - - for (final AnnotationMirror annotationMirror : field.getAnnotationMirrors()) { - final var simpleName = - annotationMirror.getAnnotationType().asElement().getSimpleName().toString(); + for (AnnotationMirror annotationMirror : field.getAnnotationMirrors()) { + String simpleName = annotationMirror.getAnnotationType().asElement().getSimpleName().toString(); if ("JsonIgnore".equals(simpleName)) { return true; } @@ -309,7 +318,8 @@ private boolean isHiddenField(VariableElement field) { } private boolean isStaticOrTransient(VariableElement field) { - final var modifiers = field.getModifiers(); + Set modifiers = field.getModifiers(); return (modifiers.contains(Modifier.STATIC) || modifiers.contains(Modifier.TRANSIENT)); } + } diff --git a/http-generator-helidon/dependency-reduced-pom.xml b/http-generator-helidon/dependency-reduced-pom.xml deleted file mode 100644 index 6a78840d8..000000000 --- a/http-generator-helidon/dependency-reduced-pom.xml +++ /dev/null @@ -1,49 +0,0 @@ - - - - avaje-http-parent - io.avaje - 1.26-SNAPSHOT - - 4.0.0 - avaje-http-helidon-generator - - - - maven-compiler-plugin - 3.10.1 - - 11 - 11 - -proc:none - - - - - - - io.avaje - junit - 1.1 - test - - - junit-jupiter-api - org.junit.jupiter - - - junit-jupiter-engine - org.junit.jupiter - - - assertj-core - org.assertj - - - mockito-core - org.mockito - - - - - diff --git a/http-generator-javalin/dependency-reduced-pom.xml b/http-generator-javalin/dependency-reduced-pom.xml deleted file mode 100644 index 18b9d7822..000000000 --- a/http-generator-javalin/dependency-reduced-pom.xml +++ /dev/null @@ -1,47 +0,0 @@ - - - - avaje-http-parent - io.avaje - 1.26-SNAPSHOT - - 4.0.0 - avaje-http-javalin-generator - - - - maven-compiler-plugin - 3.10.1 - - -proc:none - - - - - - - io.avaje - junit - 1.1 - test - - - junit-jupiter-api - org.junit.jupiter - - - junit-jupiter-engine - org.junit.jupiter - - - assertj-core - org.assertj - - - mockito-core - org.mockito - - - - - diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index d6b72bdbf..c5bf64295 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -1,31 +1,42 @@ - 4.0.0 - avaje-http-javalin-generator - - io.avaje - avaje-http-parent - 1.26-SNAPSHOT - .. - - - - io.avaje - avaje-http-generator-core - ${project.version} - - - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.10.1 - - - -proc:none - - - - + 4.0.0 + + avaje-http-javalin-generator + + + io.avaje + avaje-http-parent + 1.26-SNAPSHOT + .. + + + + + + io.avaje + avaje-http-generator-core + ${project.version} + + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.10.1 + + 11 + 11 + + -proc:none + + + + + + diff --git a/http-generator-jex/dependency-reduced-pom.xml b/http-generator-jex/dependency-reduced-pom.xml deleted file mode 100644 index bf7b29d36..000000000 --- a/http-generator-jex/dependency-reduced-pom.xml +++ /dev/null @@ -1,49 +0,0 @@ - - - - avaje-http-parent - io.avaje - 1.26-SNAPSHOT - - 4.0.0 - avaje-http-jex-generator - - - - maven-compiler-plugin - 3.10.1 - - 11 - 11 - -proc:none - - - - - - - io.avaje - junit - 1.1 - test - - - junit-jupiter-api - org.junit.jupiter - - - junit-jupiter-engine - org.junit.jupiter - - - assertj-core - org.assertj - - - mockito-core - org.mockito - - - - - diff --git a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java index 3f794b2cb..cf666f927 100644 --- a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java +++ b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java @@ -30,24 +30,24 @@ class ControllerMethodWriter { void write(boolean requestScoped) { - final var segments = method.pathSegments(); - final var fullPath = segments.fullPath(); + final PathSegments segments = method.pathSegments(); + final String fullPath = segments.fullPath(); writer.append(" routing.%s(\"%s\", ctx -> {", webMethod.name().toLowerCase(), fullPath).eol(); writer.append(" ctx.status(%s);", method.statusCode()).eol(); - final var matrixSegments = segments.matrixSegments(); - for (final PathSegments.Segment matrixSegment : matrixSegments) { + List matrixSegments = segments.matrixSegments(); + for (PathSegments.Segment matrixSegment : matrixSegments) { matrixSegment.writeCreateSegment(writer, ctx.platform()); } - final var params = method.params(); - for (final MethodParam param : params) { + final List params = method.params(); + for (MethodParam param : params) { param.writeCtxGet(writer, segments); } writer.append(" "); if (method.includeValidate()) { - for (final MethodParam param : params) { + for (MethodParam param : params) { param.writeValidate(writer); } } @@ -61,7 +61,7 @@ void write(boolean requestScoped) { writer.append("controller."); } writer.append(method.simpleName()).append("("); - for (var i = 0; i < params.size(); i++) { + for (int i = 0; i < params.size(); i++) { if (i > 0) { writer.append(", "); } @@ -74,10 +74,10 @@ void write(boolean requestScoped) { writer.append(";").eol(); writer.append(" }"); - final var roles = method.roles(); + List roles = method.roles(); if (!roles.isEmpty()) { writer.append(").withRoles("); - for (var i = 0; i < roles.size(); i++) { + for (int i = 0; i < roles.size(); i++) { if (i > 0) { writer.append(", "); } diff --git a/http-generator-nima/dependency-reduced-pom.xml b/http-generator-nima/dependency-reduced-pom.xml deleted file mode 100644 index 0e7245453..000000000 --- a/http-generator-nima/dependency-reduced-pom.xml +++ /dev/null @@ -1,55 +0,0 @@ - - - - avaje-http-parent - io.avaje - 1.26-SNAPSHOT - - 4.0.0 - avaje-http-nima-generator - - - - maven-compiler-plugin - 3.10.1 - - 19 - 19 - -proc:none - - - - - - - io.avaje - junit - 1.1 - test - - - junit-jupiter-api - org.junit.jupiter - - - junit-jupiter-engine - org.junit.jupiter - - - assertj-core - org.assertj - - - mockito-core - org.mockito - - - - - - 19 - 19 - UTF-8 - 19 - - diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java index 9eb3a73e4..1e5371060 100644 --- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java +++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java @@ -113,7 +113,7 @@ void writeHandler(boolean requestScoped) { if (!method.isVoid()) { writeContextReturn(); if (producesJson()) { - final var uType = UType.parse(method.returnType()); + final UType uType = UType.parse(method.returnType()); writer.append(" %sJsonType.toJson(result, res.outputStream());", uType.shortName()).eol(); } else { writer.append(" res.send(result);").eol(); diff --git a/pom.xml b/pom.xml index f6390b136..623329082 100644 --- a/pom.xml +++ b/pom.xml @@ -1,7 +1,5 @@ - + 4.0.0 org.avaje @@ -26,7 +24,6 @@ - io.avaje junit @@ -35,6 +32,7 @@ + http-api http-client From ea616ba9b651e4dcd40eb9627b6db1182ebc47f7 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sat, 11 Feb 2023 01:07:41 -0500 Subject: [PATCH 0587/1323] Update ControllerReader.java --- .../java/io/avaje/http/generator/core/ControllerReader.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java index 79c87c7d9..24c928cac 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java @@ -287,9 +287,7 @@ public String path() { return findAnnotation(ControllerPrism::getOptionalOn) .map(ControllerPrism::value) .filter(not(String::isBlank)) - .or( - () -> - findAnnotation(PathPrism::getOptionalOn).map(PathPrism::value)) + .or(() -> findAnnotation(PathPrism::getOptionalOn).map(PathPrism::value)) .map(Util::trimPath) .orElse(null); } From b7972e7cc18ab6ddc04e1bc76b58716c68da7ee4 Mon Sep 17 00:00:00 2001 From: Haydon Perrin Date: Sat, 11 Feb 2023 13:44:48 +0000 Subject: [PATCH 0588/1323] Added test for Javalin `Context#future(...)` support. --- .../example/myapp/web/HelloController.java | 18 ++++++++++++++++++ .../example/myapp/HelloControllerTest.java | 19 +++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/tests/test-javalin/src/main/java/org/example/myapp/web/HelloController.java b/tests/test-javalin/src/main/java/org/example/myapp/web/HelloController.java index 551d0f0eb..9960fad0d 100644 --- a/tests/test-javalin/src/main/java/org/example/myapp/web/HelloController.java +++ b/tests/test-javalin/src/main/java/org/example/myapp/web/HelloController.java @@ -5,6 +5,8 @@ import java.time.LocalDate; import java.util.ArrayList; import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.Executors; import javax.validation.Valid; @@ -142,6 +144,21 @@ List getAll() { return myService.findAll(); } + @Get("/async") + CompletableFuture> getAllAsync() { + return CompletableFuture.supplyAsync(() -> { + // Simulate a delay as if an actual IO operation is being executed. + // This also helps ensure that we aren't just getting lucky with timings. + try { + Thread.sleep(10L); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + + return myService.findAll(); + }, Executors.newSingleThreadExecutor()); // Example of how to use a custom executor. + } + // @Hidden @Delete("{id}") void deleteById(int id) { @@ -159,4 +176,5 @@ String getWithMatrixParam(int year, String author, String country, String other, String slashAccepting(String name, String nam0, String nam1) { return "got name:" + name + " splat0:" + nam0 + " splat1:" + nam1; } + } diff --git a/tests/test-javalin/src/test/java/org/example/myapp/HelloControllerTest.java b/tests/test-javalin/src/test/java/org/example/myapp/HelloControllerTest.java index fdd151b9a..0bb3b94f6 100644 --- a/tests/test-javalin/src/test/java/org/example/myapp/HelloControllerTest.java +++ b/tests/test-javalin/src/test/java/org/example/myapp/HelloControllerTest.java @@ -62,6 +62,25 @@ void hello2() { assertThat(helloDtos).hasSize(2); } + @Test + void helloAsyncRequestHandling() { + TypeRef> listDto = new TypeRef>() { }; + final List beans = given() + .get(baseUrl + "/hello/async") + .then() + .statusCode(200) + .extract() + .as(listDto); + + assertThat(beans).hasSize(2); + + final List helloDtos = client.request() + .path("hello/async") + .GET().list(HelloDto.class); + + assertThat(helloDtos).hasSize(2); + } + @Test void getWithPathParamAndQueryParam() { From e061ca2a774064cd58e493036116e05e57a175cb Mon Sep 17 00:00:00 2001 From: Haydon Perrin Date: Sat, 11 Feb 2023 13:55:53 +0000 Subject: [PATCH 0589/1323] JsonBUtil: Throw exception if `CompletableFuture` is missing a generic type definition. --- .../main/java/io/avaje/http/generator/core/JsonBUtil.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java index d3afdd1d6..3b5d809f2 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java @@ -51,7 +51,11 @@ private static void addJsonBodyType(MethodReader methodReader, Consumer a public static void writeJsonbType(UType type, Append writer) { // Support for CompletableFuture's. - if (type.isGeneric() && type.mainType().equals("java.util.concurrent.CompletableFuture")) { + if (type.mainType().equals("java.util.concurrent.CompletableFuture")) { + if (!type.isGeneric()) { + throw new IllegalStateException("CompletableFuture usages must have a generic type defined. e.g. `CompletableFuture` or `CompletableFuture`."); + } + writeJsonbType(type.paramRaw(), writer); return; } From b4b124c98091937d0d5b4906d1908d584d48e279 Mon Sep 17 00:00:00 2001 From: Haydon Perrin Date: Sat, 11 Feb 2023 14:00:42 +0000 Subject: [PATCH 0590/1323] ControllerMethodWriter: Renamed `return` variable names to `result` for consistency with the generated code. --- .../javalin/ControllerMethodWriter.java | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java index 0fdd9e68b..db08b334a 100644 --- a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java +++ b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java @@ -88,12 +88,12 @@ private void writeContextReturn() { // Support for CompletableFuture's. final UType type = UType.parse(method.returnType()); if (type.isGeneric() && type.mainType().equals("java.util.concurrent.CompletableFuture")) { - final String returnVariableName = "futureResult"; + final String futureResultVariableName = "futureResult"; writer.append(" ctx.future(() -> {").eol(); - writer.append(" return result.thenAccept(%s -> {", returnVariableName).eol(); + writer.append(" return result.thenAccept(%s -> {", futureResultVariableName).eol(); writer.append(" "); - this.writeContextReturn(returnVariableName); + this.writeContextReturn(futureResultVariableName); writer.eol().append(" });").eol(); writer.append(" });").eol(); return; @@ -103,7 +103,7 @@ private void writeContextReturn() { this.writeContextReturn("result"); } - private void writeContextReturn(final String returnVariableName) { + private void writeContextReturn(final String resultVariableName) { final var produces = method.produces(); if (produces == null || MediaType.APPLICATION_JSON.equalsIgnoreCase(produces)) { if (useJsonB) { @@ -112,16 +112,16 @@ private void writeContextReturn(final String returnVariableName) { uType = uType.paramRaw(); } - writer.append(" %sJsonType.toJson(%s, ctx.contentType(\"application/json\").outputStream());", uType.shortName(), returnVariableName); + writer.append(" %sJsonType.toJson(%s, ctx.contentType(\"application/json\").outputStream());", uType.shortName(), resultVariableName); } else { - writer.append(" ctx.json(%s);", returnVariableName); + writer.append(" ctx.json(%s);", resultVariableName); } } else if (MediaType.TEXT_HTML.equalsIgnoreCase(produces)) { - writer.append(" ctx.html(%s);", returnVariableName); + writer.append(" ctx.html(%s);", resultVariableName); } else if (MediaType.TEXT_PLAIN.equalsIgnoreCase(produces)) { - writer.append(" ctx.contentType(\"text/plain\").result(%s);", returnVariableName); + writer.append(" ctx.contentType(\"text/plain\").result(%s);", resultVariableName); } else { - writer.append(" ctx.contentType(\"%s\").result(%s);", produces, returnVariableName); + writer.append(" ctx.contentType(\"%s\").result(%s);", produces, resultVariableName); } } } From 2cb32b612f4a563afa278d08419b05b4e4302e64 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Sun, 12 Feb 2023 13:02:07 +1300 Subject: [PATCH 0591/1323] update generated test openapi.json output --- .../src/main/resources/public/openapi.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/test-javalin-jsonb/src/main/resources/public/openapi.json b/tests/test-javalin-jsonb/src/main/resources/public/openapi.json index bd9768ec5..4ebdf89b1 100644 --- a/tests/test-javalin-jsonb/src/main/resources/public/openapi.json +++ b/tests/test-javalin-jsonb/src/main/resources/public/openapi.json @@ -1,18 +1,18 @@ { "openapi" : "3.0.1", "info" : { - "title" : "Example service", + "title" : "Example service showing off the Path extension method of controller", "description" : "Example Javalin controllers with Java and Maven", "version" : "" }, "tags" : [ { "name" : "tag1", - "description" : "it's somethin" + "description" : "this is added to openapi tags" }, { "name" : "tag1", - "description" : "this is added to openapi tags" + "description" : "it's somethin" } ], "paths" : { From be06848d54e1abf3069bf11450ecdd91b46a811c Mon Sep 17 00:00:00 2001 From: Haydon Perrin Date: Sun, 12 Feb 2023 13:50:54 +0000 Subject: [PATCH 0592/1323] Moved CompletableFuture generic validation to ControllerMethodWriter. --- .../main/java/io/avaje/http/generator/core/JsonBUtil.java | 4 ---- .../http/generator/javalin/ControllerMethodWriter.java | 8 ++++++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java index 3b5d809f2..146338a2b 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java @@ -52,10 +52,6 @@ private static void addJsonBodyType(MethodReader methodReader, Consumer a public static void writeJsonbType(UType type, Append writer) { // Support for CompletableFuture's. if (type.mainType().equals("java.util.concurrent.CompletableFuture")) { - if (!type.isGeneric()) { - throw new IllegalStateException("CompletableFuture usages must have a generic type defined. e.g. `CompletableFuture` or `CompletableFuture`."); - } - writeJsonbType(type.paramRaw(), writer); return; } diff --git a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java index db08b334a..92bf49128 100644 --- a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java +++ b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java @@ -87,7 +87,11 @@ void write(boolean requestScoped) { private void writeContextReturn() { // Support for CompletableFuture's. final UType type = UType.parse(method.returnType()); - if (type.isGeneric() && type.mainType().equals("java.util.concurrent.CompletableFuture")) { + if (type.mainType().equals("java.util.concurrent.CompletableFuture")) { + if (!type.isGeneric()) { + throw new IllegalStateException("CompletableFuture must be generic type (e.g. CompletableFuture, CompletableFuture)."); + } + final String futureResultVariableName = "futureResult"; writer.append(" ctx.future(() -> {").eol(); @@ -108,7 +112,7 @@ private void writeContextReturn(final String resultVariableName) { if (produces == null || MediaType.APPLICATION_JSON.equalsIgnoreCase(produces)) { if (useJsonB) { var uType = UType.parse(method.returnType()); - if (uType.isGeneric() && uType.mainType().equals("java.util.concurrent.CompletableFuture")) { + if (uType.mainType().equals("java.util.concurrent.CompletableFuture")) { uType = uType.paramRaw(); } From e7101f5d5e2180999b07165dfd7499aee98421da Mon Sep 17 00:00:00 2001 From: Haydon Perrin Date: Sun, 12 Feb 2023 13:53:28 +0000 Subject: [PATCH 0593/1323] ControllerWriter: Only write JsonType global variables for CompletableFuture's if not already present. --- .../http/generator/javalin/ControllerWriter.java | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java index e39aa0959..8b4b73cb4 100644 --- a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java +++ b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java @@ -89,8 +89,13 @@ private void writeClassStart() { for (UType type : jsonTypes.values()) { // Support for CompletableFuture's. - if (type.isGeneric() && type.mainType().equals("java.util.concurrent.CompletableFuture")) { + if (type.mainType().equals("java.util.concurrent.CompletableFuture")) { type = type.paramRaw(); + + if (this.jsonTypes.containsKey(type.full())) { + // Already written before -- we can skip. + continue; + } } // Everything else @@ -113,6 +118,12 @@ private void writeClassStart() { } if (useJsonB) { for (final UType type : jsonTypes.values()) { + // Skip trying to assign a global variable value for any UType that is a Completable Future. Because the paramRaw() should + // already be in this jsonTypes map anyway and write the assignment all by itself. + if (type.mainType().equals("java.util.concurrent.CompletableFuture")) { + continue; + } + JsonBUtil.writeJsonbType(type, writer); } } From cf568390236dbce792fef5506c2381ae419e4806 Mon Sep 17 00:00:00 2001 From: Haydon Perrin Date: Sun, 12 Feb 2023 13:54:06 +0000 Subject: [PATCH 0594/1323] test-javalin-jsonb: Added async request handling tests. --- .../example/myapp/web/HelloController.java | 17 +++++++++++++++++ .../example/myapp/HelloControllerTest.java | 19 +++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/HelloController.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/HelloController.java index 4996122b3..e5e5915d2 100644 --- a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/HelloController.java +++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/HelloController.java @@ -5,6 +5,8 @@ import java.time.LocalDate; import java.util.ArrayList; import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.Executors; import javax.validation.Valid; @@ -142,6 +144,21 @@ List getAll() { return myService.findAll(); } + @Get("/async") + CompletableFuture> getAllAsync() { + return CompletableFuture.supplyAsync(() -> { + // Simulate a delay as if an actual IO operation is being executed. + // This also helps ensure that we aren't just getting lucky with timings. + try { + Thread.sleep(10L); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + + return myService.findAll(); + }, Executors.newSingleThreadExecutor()); // Example of how to use a custom executor. + } + // @Hidden @Delete(":id") void deleteById(int id) { diff --git a/tests/test-javalin-jsonb/src/test/java/org/example/myapp/HelloControllerTest.java b/tests/test-javalin-jsonb/src/test/java/org/example/myapp/HelloControllerTest.java index fdd151b9a..e13c77d69 100644 --- a/tests/test-javalin-jsonb/src/test/java/org/example/myapp/HelloControllerTest.java +++ b/tests/test-javalin-jsonb/src/test/java/org/example/myapp/HelloControllerTest.java @@ -62,6 +62,25 @@ void hello2() { assertThat(helloDtos).hasSize(2); } + @Test + void helloAsyncRequestHandling() { + TypeRef> listDto = new TypeRef>() { }; + final List beans = given() + .get(baseUrl + "/hello/async") + .then() + .statusCode(200) + .extract() + .as(listDto); + + assertThat(beans).hasSize(2); + + final List helloDtos = client.request() + .path("hello/async") + .GET().list(HelloDto.class); + + assertThat(helloDtos).hasSize(2); + } + @Test void getWithPathParamAndQueryParam() { From 8d444a786b318a18fa509f6be737dffa4037b00d Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Mon, 13 Feb 2023 09:29:50 +1300 Subject: [PATCH 0595/1323] For tests use asList() so we can assert on statusCode() as well as response body --- .../org/example/myapp/HelloControllerTest.java | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/tests/test-javalin/src/test/java/org/example/myapp/HelloControllerTest.java b/tests/test-javalin/src/test/java/org/example/myapp/HelloControllerTest.java index 0bb3b94f6..3672dac56 100644 --- a/tests/test-javalin/src/test/java/org/example/myapp/HelloControllerTest.java +++ b/tests/test-javalin/src/test/java/org/example/myapp/HelloControllerTest.java @@ -55,11 +55,12 @@ void hello2() { assertThat(beans).hasSize(2); - final List helloDtos = client.request() + final HttpResponse> helloDtos = client.request() .path("hello") - .GET().list(HelloDto.class); + .GET().asList(HelloDto.class); - assertThat(helloDtos).hasSize(2); + assertThat(helloDtos.statusCode()).isEqualTo(200); + assertThat(helloDtos.body()).hasSize(2); } @Test @@ -74,11 +75,12 @@ void helloAsyncRequestHandling() { assertThat(beans).hasSize(2); - final List helloDtos = client.request() + final HttpResponse> helloDtos = client.request() .path("hello/async") - .GET().list(HelloDto.class); + .GET().asList(HelloDto.class); - assertThat(helloDtos).hasSize(2); + assertThat(helloDtos.statusCode()).isEqualTo(200); + assertThat(helloDtos.body()).hasSize(2); } @Test From 4ab9bad12a4071d96d242b71be526778c39ff4a9 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Mon, 13 Feb 2023 09:30:13 +1300 Subject: [PATCH 0596/1323] Trim unneeded whitespace from generated code --- .../io/avaje/http/generator/javalin/ControllerMethodWriter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java index 1133ed7c8..46d72b787 100644 --- a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java +++ b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java @@ -106,7 +106,7 @@ private void writeContextReturn() { writer.append(" "); this.writeContextReturn(futureResultVariableName); writer.eol().append(" });").eol(); - writer.append(" });").eol(); + writer.append(" });"); return; } From 1badc22d1d3b614cd449493c5f66c5a716cc2b29 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Mon, 13 Feb 2023 09:31:56 +1300 Subject: [PATCH 0597/1323] Fix generated openapi schema for CompletableFuture response body Note: Not detecting openapi array vs object there though --- .gitignore | 1 + .../core/openapi/SchemaDocBuilder.java | 14 +++++++++++-- .../avaje/http/generator/core/UtilTest.java | 7 +++++++ .../src/main/resources/public/openapi.json | 21 +++++++++++++++++++ .../src/main/resources/public/openapi.json | 21 +++++++++++++++++++ 5 files changed, 62 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 2c1471b49..ba8980bcf 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,4 @@ build/ */bin/ *.editorconfig *.Module +dependency-reduced-pom.xml diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/SchemaDocBuilder.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/SchemaDocBuilder.java index 9c3ee4a0e..b5557534a 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/SchemaDocBuilder.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/SchemaDocBuilder.java @@ -22,6 +22,7 @@ import javax.lang.model.util.Types; import io.avaje.http.generator.core.HiddenPrism; +import io.avaje.http.generator.core.UType; import io.avaje.http.generator.core.Util; import io.avaje.prism.GeneratePrism; import io.swagger.v3.oas.models.Operation; @@ -43,6 +44,7 @@ class SchemaDocBuilder { private static final String APP_FORM = "application/x-www-form-urlencoded"; private static final String APP_JSON = "application/json"; + private final Elements elements; private final Types types; private final KnownTypes knownTypes; private final TypeMirror iterableType; @@ -52,6 +54,7 @@ class SchemaDocBuilder { SchemaDocBuilder(Types types, Elements elements) { this.types = types; + this.elements = elements; this.knownTypes = new KnownTypes(); this.iterableType = types.erasure(elements.getTypeElement("java.lang.Iterable").asType()); this.mapType = types.erasure(elements.getTypeElement("java.util.Map").asType()); @@ -112,7 +115,6 @@ void addRequestBody(Operation operation, Schema schema, boolean asForm, String d } private RequestBody requestBody(Operation operation) { - RequestBody body = operation.getRequestBody(); if (body == null) { body = new RequestBody(); @@ -125,7 +127,15 @@ private RequestBody requestBody(Operation operation) { } Schema toSchema(TypeMirror type) { - + UType uType = UType.parse(type); + if (uType.mainType().equals("java.util.concurrent.CompletableFuture")) { + UType bodyType = uType.paramRaw(); + if (bodyType.isGeneric()) { // Container type like List, Set etc + bodyType = bodyType.paramRaw(); + } + TypeElement typeElement = elements.getTypeElement(bodyType.full()); + type = typeElement.asType(); + } Schema schema = knownTypes.createSchema(typeDef(type)); if (schema != null) { return schema; diff --git a/http-generator-core/src/test/java/io/avaje/http/generator/core/UtilTest.java b/http-generator-core/src/test/java/io/avaje/http/generator/core/UtilTest.java index 9ee2b5aff..ff75d5801 100644 --- a/http-generator-core/src/test/java/io/avaje/http/generator/core/UtilTest.java +++ b/http-generator-core/src/test/java/io/avaje/http/generator/core/UtilTest.java @@ -122,6 +122,13 @@ void parse_CompletableFutureListBean() { assertThat(type.importTypes()).containsExactly("java.util.concurrent.CompletableFuture", "java.util.List", "org.example.Repo"); assertThat(type.shortType()).isEqualTo("CompletableFuture>"); + + assertThat(type.mainType()).isEqualTo("java.util.concurrent.CompletableFuture"); + UType param = type.paramRaw(); + assertThat(param.isGeneric()).isTrue(); + assertThat(param.full()).isEqualTo("java.util.List"); + UType uType = param.paramRaw(); + assertThat(uType.full()).isEqualTo("org.example.Repo"); } @Test diff --git a/tests/test-javalin-jsonb/src/main/resources/public/openapi.json b/tests/test-javalin-jsonb/src/main/resources/public/openapi.json index 4ebdf89b1..4fb82ad32 100644 --- a/tests/test-javalin-jsonb/src/main/resources/public/openapi.json +++ b/tests/test-javalin-jsonb/src/main/resources/public/openapi.json @@ -324,6 +324,27 @@ } } }, + "/hello/async" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/HelloDto" + } + } + } + } + } + } + }, "/hello/findbyname/{name}" : { "get" : { "tags" : [ diff --git a/tests/test-javalin/src/main/resources/public/openapi.json b/tests/test-javalin/src/main/resources/public/openapi.json index 56cea1bbc..d8bcf426d 100644 --- a/tests/test-javalin/src/main/resources/public/openapi.json +++ b/tests/test-javalin/src/main/resources/public/openapi.json @@ -314,6 +314,27 @@ } } }, + "/hello/async" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/HelloDto" + } + } + } + } + } + } + }, "/hello/findbyname/{name}" : { "get" : { "tags" : [ From 9b9778cb16999c2360d89a359942616ce546d58f Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Mon, 13 Feb 2023 09:43:00 +1300 Subject: [PATCH 0598/1323] Fix to SchemaDocBuilder to support CompletableFuture response --- .../core/openapi/SchemaDocBuilder.java | 31 ++++++------------- .../src/main/resources/public/openapi.json | 5 ++- .../src/main/resources/public/openapi.json | 5 ++- 3 files changed, 17 insertions(+), 24 deletions(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/SchemaDocBuilder.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/SchemaDocBuilder.java index b5557534a..9d29e35ca 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/SchemaDocBuilder.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/SchemaDocBuilder.java @@ -49,6 +49,7 @@ class SchemaDocBuilder { private final KnownTypes knownTypes; private final TypeMirror iterableType; private final TypeMirror mapType; + private final TypeMirror completableFutureType; private final Map schemas = new TreeMap<>(); @@ -58,6 +59,7 @@ class SchemaDocBuilder { this.knownTypes = new KnownTypes(); this.iterableType = types.erasure(elements.getTypeElement("java.lang.Iterable").asType()); this.mapType = types.erasure(elements.getTypeElement("java.util.Map").asType()); + this.completableFutureType = types.erasure(elements.getTypeElement("java.util.concurrent.CompletableFuture").asType()); } Map getSchemas() { @@ -82,7 +84,6 @@ void addFormParam(Operation operation, String varName, Schema schema) { } private Schema requestFormParamSchema(RequestBody body) { - final Content content = body.getContent(); MediaType mediaType = content.get(APP_FORM); @@ -103,7 +104,6 @@ private Schema requestFormParamSchema(RequestBody body) { * Add as request body. */ void addRequestBody(Operation operation, Schema schema, boolean asForm, String description) { - RequestBody body = requestBody(operation); body.setDescription(description); @@ -126,15 +126,14 @@ private RequestBody requestBody(Operation operation) { return body; } + private static TypeMirror typeArgument(TypeMirror type) { + List typeArguments = ((DeclaredType) type).getTypeArguments(); + return typeArguments.get(0); + } + Schema toSchema(TypeMirror type) { - UType uType = UType.parse(type); - if (uType.mainType().equals("java.util.concurrent.CompletableFuture")) { - UType bodyType = uType.paramRaw(); - if (bodyType.isGeneric()) { // Container type like List, Set etc - bodyType = bodyType.paramRaw(); - } - TypeElement typeElement = elements.getTypeElement(bodyType.full()); - type = typeElement.asType(); + if (types.isAssignable(type, completableFutureType)) { + type = typeArgument(type); } Schema schema = knownTypes.createSchema(typeDef(type)); if (schema != null) { @@ -143,20 +142,16 @@ Schema toSchema(TypeMirror type) { if (types.isAssignable(type, mapType)) { return buildMapSchema(type); } - if (type.getKind() == TypeKind.ARRAY) { return buildArraySchema(type); } - if (types.isAssignable(type, iterableType)) { return buildIterableSchema(type); } - return buildObjectSchema(type); } private Schema buildObjectSchema(TypeMirror type) { - String objectSchemaKey = getObjectSchemaName(type); Schema objectSchema = schemas.get(objectSchemaKey); @@ -173,7 +168,6 @@ private Schema buildObjectSchema(TypeMirror type) { } private Schema buildIterableSchema(TypeMirror type) { - Schema itemSchema = new ObjectSchema().format("unknownIterableType"); if (type.getKind() == TypeKind.DECLARED) { @@ -189,7 +183,6 @@ private Schema buildIterableSchema(TypeMirror type) { } private Schema buildArraySchema(TypeMirror type) { - ArrayType arrayType = (ArrayType) type; Schema itemSchema = toSchema(arrayType.getComponentType()); @@ -199,7 +192,6 @@ private Schema buildArraySchema(TypeMirror type) { } private Schema buildMapSchema(TypeMirror type) { - Schema valueSchema = new ObjectSchema().format("unknownMapValueType"); if (type.getKind() == TypeKind.DECLARED) { @@ -216,7 +208,6 @@ private Schema buildMapSchema(TypeMirror type) { } private String getObjectSchemaName(TypeMirror type) { - var canonicalName = Util.trimAnnotations(type.toString()); final var pos = canonicalName.lastIndexOf('.'); if (pos > -1) { @@ -246,7 +237,6 @@ private void setFormatFromValidation(Element element, Schema propSchema) { } private void setLengthMinMax(Element element, Schema propSchema) { - SizePrism.getOptionalOn(element) .ifPresent( size -> { @@ -279,7 +269,6 @@ private boolean isNotNullable(Element element) { * Gather all the fields (properties) for the given bean element. */ private List allFields(Element element) { - List list = new ArrayList<>(); gatherProperties(list, element); return list; @@ -289,7 +278,6 @@ private List allFields(Element element) { * Recursively gather all the fields (properties) for the given bean element. */ private void gatherProperties(List fields, Element element) { - if (element == null) { return; } @@ -314,7 +302,6 @@ private boolean ignoreField(VariableElement field) { } private boolean isHiddenField(VariableElement field) { - if (HiddenPrism.getOptionalOn(field).isPresent()) { return true; } diff --git a/tests/test-javalin-jsonb/src/main/resources/public/openapi.json b/tests/test-javalin-jsonb/src/main/resources/public/openapi.json index 4fb82ad32..a27d78847 100644 --- a/tests/test-javalin-jsonb/src/main/resources/public/openapi.json +++ b/tests/test-javalin-jsonb/src/main/resources/public/openapi.json @@ -337,7 +337,10 @@ "content" : { "application/json" : { "schema" : { - "$ref" : "#/components/schemas/HelloDto" + "items" : { + "$ref" : "#/components/schemas/HelloDto" + }, + "type" : "array" } } } diff --git a/tests/test-javalin/src/main/resources/public/openapi.json b/tests/test-javalin/src/main/resources/public/openapi.json index d8bcf426d..482ad9e9a 100644 --- a/tests/test-javalin/src/main/resources/public/openapi.json +++ b/tests/test-javalin/src/main/resources/public/openapi.json @@ -327,7 +327,10 @@ "content" : { "application/json" : { "schema" : { - "$ref" : "#/components/schemas/HelloDto" + "items" : { + "$ref" : "#/components/schemas/HelloDto" + }, + "type" : "array" } } } From dce0304b23f72de91d7e90bcd3461725bbe92d3e Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Mon, 13 Feb 2023 09:44:56 +1300 Subject: [PATCH 0599/1323] [maven-release-plugin] prepare release avaje-http-parent-1.26 --- http-api/pom.xml | 4 ++-- http-client-gson-adapter/pom.xml | 6 +++--- http-client/pom.xml | 6 +++--- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 4 ++-- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-generator-nima/pom.xml | 2 +- pom.xml | 10 ++++------ 10 files changed, 19 insertions(+), 21 deletions(-) diff --git a/http-api/pom.xml b/http-api/pom.xml index 10f142510..9c0978914 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.26-SNAPSHOT + 1.26 .. @@ -12,7 +12,7 @@ scm:git:git@github.com:avaje/avaje-http.git - avaje-http-parent-1.19 + avaje-http-parent-1.26 diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index 96e4950a4..53ff3d739 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,13 +4,13 @@ io.avaje avaje-http-parent - 1.26-SNAPSHOT + 1.26 .. io.avaje avaje-http-client-gson - 1.26-SNAPSHOT + 1.26 @@ -23,7 +23,7 @@ io.avaje avaje-http-client - 1.26-SNAPSHOT + 1.26 provided diff --git a/http-client/pom.xml b/http-client/pom.xml index 30641e376..f696b1dd6 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,17 +4,17 @@ io.avaje avaje-http-parent - 1.26-SNAPSHOT + 1.26 .. io.avaje avaje-http-client - 1.26-SNAPSHOT + 1.26 scm:git:git@github.com:avaje/avaje-http-client.git - HEAD + avaje-http-parent-1.26 diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index eec4d9e56..5f3e51e73 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -5,7 +5,7 @@ io.avaje avaje-http-parent - 1.26-SNAPSHOT + 1.26 .. diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 25dd84c30..a192d4213 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-parent - 1.26-SNAPSHOT + 1.26 .. @@ -29,7 +29,7 @@ io.avaje avaje-http-api - 1.26-SNAPSHOT + 1.26 true provided diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index 06b61a8a1..2f4b113cf 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-parent - 1.26-SNAPSHOT + 1.26 .. diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index c5bf64295..73ae7fed2 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-parent - 1.26-SNAPSHOT + 1.26 .. diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index 5d49ab318..a711f7407 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-parent - 1.26-SNAPSHOT + 1.26 .. diff --git a/http-generator-nima/pom.xml b/http-generator-nima/pom.xml index 9f9732687..dac45b04c 100644 --- a/http-generator-nima/pom.xml +++ b/http-generator-nima/pom.xml @@ -3,7 +3,7 @@ avaje-http-parent io.avaje - 1.26-SNAPSHOT + 1.26 4.0.0 diff --git a/pom.xml b/pom.xml index 623329082..5480244fb 100644 --- a/pom.xml +++ b/pom.xml @@ -9,12 +9,12 @@ io.avaje avaje-http-parent - 1.26-SNAPSHOT + 1.26 pom scm:git:git@github.com:avaje/avaje-http.git - avaje-http-parent-1.19 + avaje-http-parent-1.26 @@ -77,11 +77,9 @@ process-resources - + - + From b460392237aa074482da6c9ea70b5c8becf528f0 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Mon, 13 Feb 2023 09:45:02 +1300 Subject: [PATCH 0600/1323] [maven-release-plugin] prepare for next development iteration --- http-api/pom.xml | 4 ++-- http-client-gson-adapter/pom.xml | 6 +++--- http-client/pom.xml | 6 +++--- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 4 ++-- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-generator-nima/pom.xml | 2 +- pom.xml | 4 ++-- 10 files changed, 17 insertions(+), 17 deletions(-) diff --git a/http-api/pom.xml b/http-api/pom.xml index 9c0978914..0a3945d7e 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.26 + 1.27-SNAPSHOT .. @@ -12,7 +12,7 @@ scm:git:git@github.com:avaje/avaje-http.git - avaje-http-parent-1.26 + avaje-http-parent-1.19 diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index 53ff3d739..3904fd468 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,13 +4,13 @@ io.avaje avaje-http-parent - 1.26 + 1.27-SNAPSHOT .. io.avaje avaje-http-client-gson - 1.26 + 1.27-SNAPSHOT @@ -23,7 +23,7 @@ io.avaje avaje-http-client - 1.26 + 1.27-SNAPSHOT provided diff --git a/http-client/pom.xml b/http-client/pom.xml index f696b1dd6..473220101 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,17 +4,17 @@ io.avaje avaje-http-parent - 1.26 + 1.27-SNAPSHOT .. io.avaje avaje-http-client - 1.26 + 1.27-SNAPSHOT scm:git:git@github.com:avaje/avaje-http-client.git - avaje-http-parent-1.26 + HEAD diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index 5f3e51e73..c89c4ec1c 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -5,7 +5,7 @@ io.avaje avaje-http-parent - 1.26 + 1.27-SNAPSHOT .. diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index a192d4213..d016ca1cb 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-parent - 1.26 + 1.27-SNAPSHOT .. @@ -29,7 +29,7 @@ io.avaje avaje-http-api - 1.26 + 1.27-SNAPSHOT true provided diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index 2f4b113cf..88e74c077 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-parent - 1.26 + 1.27-SNAPSHOT .. diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index 73ae7fed2..75e548b51 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-parent - 1.26 + 1.27-SNAPSHOT .. diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index a711f7407..8294aef7a 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-parent - 1.26 + 1.27-SNAPSHOT .. diff --git a/http-generator-nima/pom.xml b/http-generator-nima/pom.xml index dac45b04c..e0b8958fa 100644 --- a/http-generator-nima/pom.xml +++ b/http-generator-nima/pom.xml @@ -3,7 +3,7 @@ avaje-http-parent io.avaje - 1.26 + 1.27-SNAPSHOT 4.0.0 diff --git a/pom.xml b/pom.xml index 5480244fb..3746179a2 100644 --- a/pom.xml +++ b/pom.xml @@ -9,12 +9,12 @@ io.avaje avaje-http-parent - 1.26 + 1.27-SNAPSHOT pom scm:git:git@github.com:avaje/avaje-http.git - avaje-http-parent-1.26 + avaje-http-parent-1.19 From e369fb32deebe862d06572177b96491115cff3d6 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Mon, 13 Feb 2023 09:50:24 +1300 Subject: [PATCH 0601/1323] bump test versions after release --- tests/pom.xml | 2 +- tests/test-nima-jsonb/.factorypath | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/pom.xml b/tests/pom.xml index 63ac48bff..90c2a9822 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -20,7 +20,7 @@ 2.14.1 2.5 8.12-RC3 - 1.26-SNAPSHOT + 1.27-SNAPSHOT diff --git a/tests/test-nima-jsonb/.factorypath b/tests/test-nima-jsonb/.factorypath index 5443151a3..abc529618 100644 --- a/tests/test-nima-jsonb/.factorypath +++ b/tests/test-nima-jsonb/.factorypath @@ -1,7 +1,7 @@ - + From b4e89528a62ac37ce024e9b9d92e52eef295e736 Mon Sep 17 00:00:00 2001 From: Haydon Perrin Date: Tue, 14 Feb 2023 19:42:14 +0000 Subject: [PATCH 0602/1323] #158: Fixed CompletableFuture usages not writing JsonType variable values if no other endpoints are defined with the same return type. --- .../avaje/http/generator/core/JsonBUtil.java | 14 +++++++------- .../generator/javalin/ControllerWriter.java | 19 +------------------ 2 files changed, 8 insertions(+), 25 deletions(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java index 146338a2b..1014e88cc 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java @@ -33,7 +33,13 @@ public static Map jsonTypes(ControllerReader reader) { methodReader -> { addJsonBodyType(methodReader, addToMap); if (!methodReader.isVoid()) { - addToMap.accept(UType.parse(methodReader.returnType())); + UType uType = UType.parse(methodReader.returnType()); + + if (uType.mainType().equals("java.util.concurrent.CompletableFuture")) { + uType = uType.paramRaw(); + } + + addToMap.accept(uType); } }); @@ -50,12 +56,6 @@ private static void addJsonBodyType(MethodReader methodReader, Consumer a } public static void writeJsonbType(UType type, Append writer) { - // Support for CompletableFuture's. - if (type.mainType().equals("java.util.concurrent.CompletableFuture")) { - writeJsonbType(type.paramRaw(), writer); - return; - } - writer.append(" this.%sJsonType = jsonB.type(", type.shortName()); if (!type.isGeneric()) { writer.append("%s.class)", Util.shortName(PrimitiveUtil.wrap(type.full()))); diff --git a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java index 8b4b73cb4..6ad12f09a 100644 --- a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java +++ b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java @@ -88,17 +88,6 @@ private void writeClassStart() { } for (UType type : jsonTypes.values()) { - // Support for CompletableFuture's. - if (type.mainType().equals("java.util.concurrent.CompletableFuture")) { - type = type.paramRaw(); - - if (this.jsonTypes.containsKey(type.full())) { - // Already written before -- we can skip. - continue; - } - } - - // Everything else final var typeString = PrimitiveUtil.wrap(type.shortType()).replace(",", ", "); writer.append(" private final JsonType<%s> %sJsonType;", typeString, type.shortName()).eol(); } @@ -117,13 +106,7 @@ private void writeClassStart() { writer.append(" this.validator = validator;").eol(); } if (useJsonB) { - for (final UType type : jsonTypes.values()) { - // Skip trying to assign a global variable value for any UType that is a Completable Future. Because the paramRaw() should - // already be in this jsonTypes map anyway and write the assignment all by itself. - if (type.mainType().equals("java.util.concurrent.CompletableFuture")) { - continue; - } - + for (UType type : jsonTypes.values()) { JsonBUtil.writeJsonbType(type, writer); } } From 32e9879fcda6f08c4658140f30d99136fc68d0db Mon Sep 17 00:00:00 2001 From: Haydon Perrin Date: Tue, 14 Feb 2023 19:50:14 +0000 Subject: [PATCH 0603/1323] TestController: Added single definition completablefuture return type test --- .../java/org/example/myapp/web/test/TestController.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController.java index 8f3ce5f72..ea01ae879 100644 --- a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController.java +++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController.java @@ -3,8 +3,10 @@ import java.util.List; import java.util.Map; import java.util.Set; +import java.util.concurrent.CompletableFuture; import org.example.myapp.web.AppRoles; +import org.example.myapp.web.HelloDto; import org.example.myapp.web.Roles; import io.avaje.http.api.Controller; @@ -122,4 +124,10 @@ void neo( System.out.println("Ever have that feeling where you're not sure if you're awake or dreaming?"); } + + @Get("/async") + CompletableFuture getAllAsync() { + return CompletableFuture.supplyAsync(() -> new HelloDto(12, "Jim", "asd")); + } + } From 294e7585a0f6bfdd9879787d237fade67581bea0 Mon Sep 17 00:00:00 2001 From: rob Date: Wed, 15 Feb 2023 09:12:18 +1300 Subject: [PATCH 0604/1323] Update the test generated openapi.json with new /test/async endpoint --- .../src/main/resources/public/openapi.json | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/tests/test-javalin-jsonb/src/main/resources/public/openapi.json b/tests/test-javalin-jsonb/src/main/resources/public/openapi.json index a27d78847..c4be01913 100644 --- a/tests/test-javalin-jsonb/src/main/resources/public/openapi.json +++ b/tests/test-javalin-jsonb/src/main/resources/public/openapi.json @@ -1024,6 +1024,27 @@ } } }, + "/test/async" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/HelloDto" + } + } + } + } + } + } + }, "/test/byte" : { "get" : { "tags" : [ From a7052d3921cb50e2e7d4fca57f27f63ff8993282 Mon Sep 17 00:00:00 2001 From: rob Date: Wed, 15 Feb 2023 09:13:35 +1300 Subject: [PATCH 0605/1323] [maven-release-plugin] prepare release avaje-http-parent-1.27 --- http-api/pom.xml | 4 ++-- http-client-gson-adapter/pom.xml | 6 +++--- http-client/pom.xml | 6 +++--- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 4 ++-- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-generator-nima/pom.xml | 2 +- pom.xml | 4 ++-- 10 files changed, 17 insertions(+), 17 deletions(-) diff --git a/http-api/pom.xml b/http-api/pom.xml index 0a3945d7e..99964dd8b 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.27-SNAPSHOT + 1.27 .. @@ -12,7 +12,7 @@ scm:git:git@github.com:avaje/avaje-http.git - avaje-http-parent-1.19 + avaje-http-parent-1.27 diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index 3904fd468..17b5adb9b 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,13 +4,13 @@ io.avaje avaje-http-parent - 1.27-SNAPSHOT + 1.27 .. io.avaje avaje-http-client-gson - 1.27-SNAPSHOT + 1.27 @@ -23,7 +23,7 @@ io.avaje avaje-http-client - 1.27-SNAPSHOT + 1.27 provided diff --git a/http-client/pom.xml b/http-client/pom.xml index 473220101..3b9caf71e 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,17 +4,17 @@ io.avaje avaje-http-parent - 1.27-SNAPSHOT + 1.27 .. io.avaje avaje-http-client - 1.27-SNAPSHOT + 1.27 scm:git:git@github.com:avaje/avaje-http-client.git - HEAD + avaje-http-parent-1.27 diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index c89c4ec1c..63ecb677d 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -5,7 +5,7 @@ io.avaje avaje-http-parent - 1.27-SNAPSHOT + 1.27 .. diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index d016ca1cb..b581f8eb6 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-parent - 1.27-SNAPSHOT + 1.27 .. @@ -29,7 +29,7 @@ io.avaje avaje-http-api - 1.27-SNAPSHOT + 1.27 true provided diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index 88e74c077..43dab7108 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-parent - 1.27-SNAPSHOT + 1.27 .. diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index 75e548b51..be5505556 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-parent - 1.27-SNAPSHOT + 1.27 .. diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index 8294aef7a..a3787aa4d 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-parent - 1.27-SNAPSHOT + 1.27 .. diff --git a/http-generator-nima/pom.xml b/http-generator-nima/pom.xml index e0b8958fa..37157989a 100644 --- a/http-generator-nima/pom.xml +++ b/http-generator-nima/pom.xml @@ -3,7 +3,7 @@ avaje-http-parent io.avaje - 1.27-SNAPSHOT + 1.27 4.0.0 diff --git a/pom.xml b/pom.xml index 3746179a2..fb9d26ab5 100644 --- a/pom.xml +++ b/pom.xml @@ -9,12 +9,12 @@ io.avaje avaje-http-parent - 1.27-SNAPSHOT + 1.27 pom scm:git:git@github.com:avaje/avaje-http.git - avaje-http-parent-1.19 + avaje-http-parent-1.27 From 46db88b2d7ae607abe22b4c5f8bd54b04df3de0d Mon Sep 17 00:00:00 2001 From: rob Date: Wed, 15 Feb 2023 09:13:42 +1300 Subject: [PATCH 0606/1323] [maven-release-plugin] prepare for next development iteration --- http-api/pom.xml | 4 ++-- http-client-gson-adapter/pom.xml | 6 +++--- http-client/pom.xml | 6 +++--- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 4 ++-- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-generator-nima/pom.xml | 2 +- pom.xml | 4 ++-- 10 files changed, 17 insertions(+), 17 deletions(-) diff --git a/http-api/pom.xml b/http-api/pom.xml index 99964dd8b..adfc4ee2d 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.27 + 1.28-SNAPSHOT .. @@ -12,7 +12,7 @@ scm:git:git@github.com:avaje/avaje-http.git - avaje-http-parent-1.27 + avaje-http-parent-1.19 diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index 17b5adb9b..8efb1705b 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,13 +4,13 @@ io.avaje avaje-http-parent - 1.27 + 1.28-SNAPSHOT .. io.avaje avaje-http-client-gson - 1.27 + 1.28-SNAPSHOT @@ -23,7 +23,7 @@ io.avaje avaje-http-client - 1.27 + 1.28-SNAPSHOT provided diff --git a/http-client/pom.xml b/http-client/pom.xml index 3b9caf71e..8fffadfe2 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,17 +4,17 @@ io.avaje avaje-http-parent - 1.27 + 1.28-SNAPSHOT .. io.avaje avaje-http-client - 1.27 + 1.28-SNAPSHOT scm:git:git@github.com:avaje/avaje-http-client.git - avaje-http-parent-1.27 + HEAD diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index 63ecb677d..d8bfbc625 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -5,7 +5,7 @@ io.avaje avaje-http-parent - 1.27 + 1.28-SNAPSHOT .. diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index b581f8eb6..2518d278f 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-parent - 1.27 + 1.28-SNAPSHOT .. @@ -29,7 +29,7 @@ io.avaje avaje-http-api - 1.27 + 1.28-SNAPSHOT true provided diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index 43dab7108..b77263ce2 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-parent - 1.27 + 1.28-SNAPSHOT .. diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index be5505556..071841f35 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-parent - 1.27 + 1.28-SNAPSHOT .. diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index a3787aa4d..e27fd40ad 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-parent - 1.27 + 1.28-SNAPSHOT .. diff --git a/http-generator-nima/pom.xml b/http-generator-nima/pom.xml index 37157989a..f0eb2734e 100644 --- a/http-generator-nima/pom.xml +++ b/http-generator-nima/pom.xml @@ -3,7 +3,7 @@ avaje-http-parent io.avaje - 1.27 + 1.28-SNAPSHOT 4.0.0 diff --git a/pom.xml b/pom.xml index fb9d26ab5..fbb490e11 100644 --- a/pom.xml +++ b/pom.xml @@ -9,12 +9,12 @@ io.avaje avaje-http-parent - 1.27 + 1.28-SNAPSHOT pom scm:git:git@github.com:avaje/avaje-http.git - avaje-http-parent-1.27 + avaje-http-parent-1.19 From 8b8e9d49572a46afbad6da82811e9d2af93e51d7 Mon Sep 17 00:00:00 2001 From: rob Date: Wed, 15 Feb 2023 09:42:55 +1300 Subject: [PATCH 0607/1323] Bump test versions after release --- tests/pom.xml | 2 +- tests/test-nima-jsonb/.factorypath | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/pom.xml b/tests/pom.xml index 90c2a9822..0700bacb5 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -20,7 +20,7 @@ 2.14.1 2.5 8.12-RC3 - 1.27-SNAPSHOT + 1.28-SNAPSHOT diff --git a/tests/test-nima-jsonb/.factorypath b/tests/test-nima-jsonb/.factorypath index abc529618..741f86c2a 100644 --- a/tests/test-nima-jsonb/.factorypath +++ b/tests/test-nima-jsonb/.factorypath @@ -1,7 +1,7 @@ - + From 001b053048f1dfd554fbc3ff2292947c88d43e32 Mon Sep 17 00:00:00 2001 From: ZY Date: Thu, 16 Feb 2023 11:44:01 +0800 Subject: [PATCH 0608/1323] OpenAPI uses javadoc for fields --- .../http/generator/core/openapi/SchemaDocBuilder.java | 9 +++++++++ .../src/main/java/org/example/myapp/web/HelloDto.java | 6 ++++++ 2 files changed, 15 insertions(+) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/SchemaDocBuilder.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/SchemaDocBuilder.java index 9d29e35ca..30da0fd5c 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/SchemaDocBuilder.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/SchemaDocBuilder.java @@ -2,6 +2,7 @@ import static io.avaje.http.generator.core.Util.typeDef; +import io.avaje.http.generator.core.javadoc.Javadoc; import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -223,6 +224,7 @@ private void populateObjectSchema(TypeMirror objectType, Schema objectSch if (isNotNullable(field)) { propSchema.setNullable(Boolean.FALSE); } + setDescription(field, propSchema); setLengthMinMax(field, propSchema); setFormatFromValidation(field, propSchema); objectSchema.addProperties(field.getSimpleName().toString(), propSchema); @@ -236,6 +238,13 @@ private void setFormatFromValidation(Element element, Schema propSchema) { } } + private void setDescription(Element element, Schema propSchema) { + var doc = Javadoc.parse(elements.getDocComment(element)); + if (!doc.getSummary().isEmpty()) { + propSchema.setDescription(doc.getSummary()); + } + } + private void setLengthMinMax(Element element, Schema propSchema) { SizePrism.getOptionalOn(element) .ifPresent( diff --git a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/HelloDto.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/HelloDto.java index abd2ff856..ac3762420 100644 --- a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/HelloDto.java +++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/HelloDto.java @@ -8,7 +8,13 @@ public class HelloDto { public int id; + /** + * This is a comment. + */ public String name; + /** + * This is a comment + */ public String otherParam; private UUID gid; From 2d5cd50ec8197d4db889859098a5a3555bc58440 Mon Sep 17 00:00:00 2001 From: rob Date: Thu, 16 Feb 2023 23:52:03 +1300 Subject: [PATCH 0609/1323] Updated openapi.json using javadoc field comment --- .../src/main/resources/public/openapi.json | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/test-javalin-jsonb/src/main/resources/public/openapi.json b/tests/test-javalin-jsonb/src/main/resources/public/openapi.json index c4be01913..dfa9169c6 100644 --- a/tests/test-javalin-jsonb/src/main/resources/public/openapi.json +++ b/tests/test-javalin-jsonb/src/main/resources/public/openapi.json @@ -1575,10 +1575,12 @@ "nullable" : false }, "name" : { - "type" : "string" + "type" : "string", + "description" : "This is a comment" }, "otherParam" : { - "type" : "string" + "type" : "string", + "description" : "This is a comment" }, "gid" : { "type" : "string", From 6e74bb81678b5e94d20d2204f5dfa81e3a4ecba5 Mon Sep 17 00:00:00 2001 From: ZY Date: Fri, 17 Feb 2023 18:58:58 +0800 Subject: [PATCH 0610/1323] Upgrade swagger version to 2.2.8 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index fbb490e11..3803d0458 100644 --- a/pom.xml +++ b/pom.xml @@ -19,7 +19,7 @@ true - 2.0.8 + 2.2.8 ${project.build.directory}${file.separator}module-info.shade From 88487535b602813ba50fd4bf3b9e0b370a942337 Mon Sep 17 00:00:00 2001 From: ZY Date: Fri, 17 Feb 2023 19:25:08 +0800 Subject: [PATCH 0611/1323] support `@SecurityScheme` --- http-generator-core/pom.xml | 21 +- .../http/generator/core/BaseProcessor.java | 16 +- .../http/generator/core/MethodReader.java | 49 +- .../generator/core/openapi/DocContext.java | 71 +- .../core/openapi/MethodDocBuilder.java | 8 + .../http/generator/core/package-info.java | 4 + .../src/main/java/module-info.java | 4 + .../src/main/java/org/example/myapp/Main.java | 16 +- .../example/myapp/web/SecurityController.java | 23 + .../org/example/myapp/web/SecurityRoles.java | 23 + .../src/main/resources/public/openapi.json | 3201 ++++++++--------- .../resources/expectedInheritedOpenApi.json | 122 +- .../src/test/resources/expectedOpenApi.json | 274 +- .../src/main/resources/public/openapi.json | 1718 +++++---- .../src/main/resources/public/openapi.json | 447 ++- 15 files changed, 2958 insertions(+), 3039 deletions(-) create mode 100644 tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/SecurityController.java create mode 100644 tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/SecurityRoles.java diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 2518d278f..88b19ba30 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -11,13 +11,7 @@ .. - - 2.0.8 - - - - io.avaje avaje-prisms @@ -36,12 +30,12 @@ io.swagger.core.v3 - swagger-models + swagger-core ${swagger.version} - com.fasterxml.jackson.core - jackson-annotations + jakarta.validation + jakarta.validation-api @@ -70,15 +64,6 @@ provided - - - io.swagger.core.v3 - swagger-annotations - ${swagger.version} - true - provided - - diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java index bc4fe60d6..4ed248e5d 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java @@ -2,7 +2,6 @@ import java.io.IOException; import java.util.Set; - import javax.annotation.processing.AbstractProcessor; import javax.annotation.processing.ProcessingEnvironment; import javax.annotation.processing.RoundEnvironment; @@ -41,6 +40,7 @@ public boolean process(Set annotations, RoundEnvironment if (ctx.isOpenApiAvailable()) { readOpenApiDefinition(round); readTagDefinitions(round); + readSecuritySchemes(round); } final Set controllers = @@ -75,7 +75,19 @@ private void readTagDefinitions(RoundEnvironment round) { ctx.doc().addTagsDefinition(element); } } - + + private void readSecuritySchemes(RoundEnvironment round) { + Set elements = round.getElementsAnnotatedWith(ctx.typeElement(SecuritySchemePrism.PRISM_TYPE)); + for (Element element : elements) { + ctx.doc().addSecurityScheme(element); + } + + elements = round.getElementsAnnotatedWith(ctx.typeElement(SecuritySchemesPrism.PRISM_TYPE)); + for (Element element : elements) { + ctx.doc().addSecuritySchemes(element); + } + } + private void writeOpenAPI() { ctx.doc().writeApi(); } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java index 1920a42f2..3729f07e9 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java @@ -1,13 +1,17 @@ package io.avaje.http.generator.core; +import io.avaje.http.generator.core.javadoc.Javadoc; +import io.avaje.http.generator.core.openapi.MethodDocBuilder; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Optional; +import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Predicate; import java.util.stream.Collectors; import java.util.stream.Stream; - +import javax.lang.model.element.AnnotationMirror; import javax.lang.model.element.Element; import javax.lang.model.element.ExecutableElement; import javax.lang.model.element.VariableElement; @@ -15,9 +19,6 @@ import javax.lang.model.type.TypeKind; import javax.lang.model.type.TypeMirror; -import io.avaje.http.generator.core.javadoc.Javadoc; -import io.avaje.http.generator.core.openapi.MethodDocBuilder; - public class MethodReader { private final ProcessingContext ctx; @@ -31,6 +32,7 @@ public class MethodReader { */ private final List methodRoles; private final Optional producesAnnotation; + private final List securityRequirements; private final List apiResponses; private final ExecutableType actualExecutable; private final List actualParams; @@ -57,6 +59,7 @@ public class MethodReader { ctx.superMethods(element.getEnclosingElement(), element.getSimpleName().toString()); superMethods.forEach(m -> methodRoles.addAll(Util.findRoles(m))); + this.securityRequirements = readSecurityRequirements(); this.apiResponses = buildApiResponses(); this.javadoc = buildJavadoc(element, ctx); @@ -130,6 +133,40 @@ public Javadoc javadoc() { return javadoc; } + private List readSecurityRequirements() { + var list = new ArrayList(); + + readSecurityRequirements(element, list); + for (ExecutableElement superMethod : superMethods) { + readSecurityRequirements(superMethod, list); + } + readSecurityRequirements(bean.beanType(), list); + + var map = new HashMap(); + for (SecurityRequirementPrism p : list) { + if (!map.containsKey(p.name())) { + map.put(p.name(), p); + } + } + return List.copyOf(map.values()); + } + + private void readSecurityRequirements(Element element, List list) { + Consumer f = e -> { + Optional.ofNullable(SecurityRequirementsPrism.getInstanceOn(e)) + .map(SecurityRequirementsPrism::value) + .ifPresent(list::addAll); + Optional.ofNullable(SecurityRequirementPrism.getAllInstancesOn(e)) + .ifPresent(list::addAll); + }; + f.accept(element); + + for (AnnotationMirror annotationMirror : element.getAnnotationMirrors()) { + // find only one level + f.accept(annotationMirror.getAnnotationType().asElement()); + } + } + private List buildApiResponses() { final var container = @@ -260,6 +297,10 @@ public String produces() { return producesAnnotation.map(ProducesPrism::value).orElseGet(bean::produces); } + public List securityRequirements() { + return securityRequirements; + } + public List apiResponses() { return apiResponses; } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/DocContext.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/DocContext.java index 21ba26192..f1491b558 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/DocContext.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/DocContext.java @@ -1,10 +1,26 @@ package io.avaje.http.generator.core.openapi; +import io.avaje.http.generator.core.OpenAPIDefinitionPrism; +import io.avaje.http.generator.core.SecuritySchemePrism; +import io.avaje.http.generator.core.SecuritySchemesPrism; +import io.avaje.http.generator.core.TagPrism; +import io.avaje.http.generator.core.TagsPrism; +import io.swagger.v3.core.util.Json; +import io.swagger.v3.oas.models.Components; +import io.swagger.v3.oas.models.OpenAPI; +import io.swagger.v3.oas.models.Operation; +import io.swagger.v3.oas.models.PathItem; +import io.swagger.v3.oas.models.Paths; +import io.swagger.v3.oas.models.info.Info; +import io.swagger.v3.oas.models.media.Content; +import io.swagger.v3.oas.models.media.Schema; +import io.swagger.v3.oas.models.security.SecurityScheme; +import io.swagger.v3.oas.models.tags.Tag; import java.io.IOException; import java.io.Writer; +import java.util.List; import java.util.Map; import java.util.TreeMap; - import javax.annotation.processing.Filer; import javax.annotation.processing.Messager; import javax.annotation.processing.ProcessingEnvironment; @@ -16,19 +32,6 @@ import javax.tools.FileObject; import javax.tools.StandardLocation; -import io.avaje.http.generator.core.OpenAPIDefinitionPrism; -import io.avaje.http.generator.core.TagPrism; -import io.avaje.http.generator.core.TagsPrism; -import io.swagger.v3.oas.models.Components; -import io.swagger.v3.oas.models.OpenAPI; -import io.swagger.v3.oas.models.Operation; -import io.swagger.v3.oas.models.PathItem; -import io.swagger.v3.oas.models.Paths; -import io.swagger.v3.oas.models.info.Info; -import io.swagger.v3.oas.models.media.Content; -import io.swagger.v3.oas.models.media.Schema; -import io.swagger.v3.oas.models.tags.Tag; - /** Context for building the OpenAPI documentation. */ public class DocContext { @@ -154,6 +157,39 @@ public void addTagDefinition(Element element) { openAPI.addTagsItem(createTagItem(tag)); } + public void addSecurityScheme(Element element) { + var schemes = SecuritySchemePrism.getAllInstancesOn(element); + if (schemes == null) { + return; + } + this.addSecuritySchemes(schemes); + } + + public void addSecuritySchemes(Element element) { + var schemes = SecuritySchemesPrism.getInstanceOn(element); + this.addSecuritySchemes(schemes.value()); + } + + void addSecuritySchemes(List schemes) { + for (SecuritySchemePrism p : schemes) { + var ss = new SecurityScheme() + .type(SecurityScheme.Type.valueOf(p.type())) + .in(SecurityScheme.In.valueOf(p.in())) + .name(p.paramName()); + + if (!p.description().isEmpty()) { + ss.description(p.description()); + } + if (!p.bearerFormat().isEmpty()) { + ss.bearerFormat(p.bearerFormat()); + } + if (!p.scheme().isEmpty()) { + ss.scheme(p.scheme()); + } + components().addSecuritySchemes(p.name(), ss); + } + } + public void readApiDefinition(Element element) { final var openApi = OpenAPIDefinitionPrism.getInstanceOn(element); @@ -167,17 +203,12 @@ public void readApiDefinition(Element element) { if (!info.version().isEmpty()) { openAPI.getInfo().setVersion(info.version()); } - } public void writeApi() { - final var openAPI = getApiForWriting(); try (var metaWriter = createMetaWriter()) { - - final var json = OpenAPISerializer.serialize(openAPI); - JsonFormatter.prettyPrintJson(metaWriter, json); - + Json.pretty().writeValue(metaWriter, openAPI); } catch (final Exception e) { logError(null, "Error writing openapi file" + e.getMessage()); e.printStackTrace(); diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/MethodDocBuilder.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/MethodDocBuilder.java index 813d87838..9d0a9a70d 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/MethodDocBuilder.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/MethodDocBuilder.java @@ -3,12 +3,14 @@ import io.avaje.http.generator.core.HiddenPrism; import io.avaje.http.generator.core.MethodParam; import io.avaje.http.generator.core.MethodReader; +import io.avaje.http.generator.core.SecurityRequirementPrism; import io.avaje.http.generator.core.javadoc.Javadoc; import io.avaje.prism.GeneratePrism; import io.swagger.v3.oas.models.Operation; import io.swagger.v3.oas.models.PathItem; import io.swagger.v3.oas.models.responses.ApiResponse; import io.swagger.v3.oas.models.responses.ApiResponses; +import io.swagger.v3.oas.models.security.SecurityRequirement; /** Build the OpenAPI documentation for a method. */ @GeneratePrism(Deprecated.class) @@ -62,6 +64,12 @@ public void build() { break; } + var securityRequirements = methodReader.securityRequirements(); + for (SecurityRequirementPrism p : securityRequirements) { + var o = new SecurityRequirement().addList(p.name(), p.scopes()); + operation.addSecurityItem(o); + } + for (MethodParam param : methodReader.params()) { param.buildApiDocumentation(this); } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/package-info.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/package-info.java index 18896ff2e..4a9513d98 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/package-info.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/package-info.java @@ -20,6 +20,10 @@ @GeneratePrism(value = io.swagger.v3.oas.annotations.OpenAPIDefinition.class, publicAccess = true) @GeneratePrism(value = io.swagger.v3.oas.annotations.tags.Tag.class, publicAccess = true) @GeneratePrism(value = io.swagger.v3.oas.annotations.tags.Tags.class, publicAccess = true) +@GeneratePrism(value = io.swagger.v3.oas.annotations.security.SecurityScheme.class, publicAccess = true) +@GeneratePrism(value = io.swagger.v3.oas.annotations.security.SecuritySchemes.class, publicAccess = true) +@GeneratePrism(value = io.swagger.v3.oas.annotations.security.SecurityRequirement.class, publicAccess = true) +@GeneratePrism(value = io.swagger.v3.oas.annotations.security.SecurityRequirements.class, publicAccess = true) @GeneratePrism(value = io.avaje.http.api.OpenAPIResponse.class, publicAccess = true) @GeneratePrism(value = io.avaje.http.api.OpenAPIResponses.class, publicAccess = true) @GeneratePrism(value = io.swagger.v3.oas.annotations.Hidden.class, publicAccess = true) diff --git a/http-generator-core/src/main/java/module-info.java b/http-generator-core/src/main/java/module-info.java index 9e895411f..a81133ccf 100644 --- a/http-generator-core/src/main/java/module-info.java +++ b/http-generator-core/src/main/java/module-info.java @@ -6,6 +6,10 @@ requires java.sql; requires java.compiler; + requires com.fasterxml.jackson.annotation; + requires com.fasterxml.jackson.core; + requires com.fasterxml.jackson.databind; + requires io.swagger.v3.core; // SHADED: All content after this line will be removed at package time requires static io.avaje.prism; diff --git a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/Main.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/Main.java index f788ac2c6..ad68865e3 100644 --- a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/Main.java +++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/Main.java @@ -1,12 +1,5 @@ package org.example.myapp; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import io.avaje.http.api.InvalidPathArgumentException; import io.avaje.http.api.InvalidTypeArgumentException; import io.avaje.http.api.ValidationException; @@ -17,10 +10,19 @@ import io.javalin.Javalin; import io.javalin.http.staticfiles.Location; import io.swagger.v3.oas.annotations.OpenAPIDefinition; +import io.swagger.v3.oas.annotations.enums.SecuritySchemeIn; +import io.swagger.v3.oas.annotations.enums.SecuritySchemeType; import io.swagger.v3.oas.annotations.info.Info; +import io.swagger.v3.oas.annotations.security.SecurityScheme; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; @InjectModule(name = "app", requires = Validator.class) @OpenAPIDefinition(info = @Info(title = "Example service", description = "Example Javalin controllers with Java and Maven")) +@SecurityScheme(type = SecuritySchemeType.APIKEY, in = SecuritySchemeIn.QUERY, name = "JWT", paramName = "access_token", description = "JSON Web Tokens are an open, industry standard RFC 7519 method for representing claims securely between two parties.") public class Main { private static final Logger log = LoggerFactory.getLogger(Main.class); diff --git a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/SecurityController.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/SecurityController.java new file mode 100644 index 000000000..304aa5ea0 --- /dev/null +++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/SecurityController.java @@ -0,0 +1,23 @@ +package org.example.myapp.web; + +import io.avaje.http.api.Controller; +import io.avaje.http.api.Get; +import io.avaje.http.api.Path; +import io.swagger.v3.oas.annotations.security.SecurityRequirement; + +@Controller +@Path("/security") +class SecurityController { + + @Get("/first") + @SecurityRequirement(name = "JWT") + String first() { + return "simple"; + } + + @Get("/second") + @SecurityRoles + String second() { + return "simple"; + } +} diff --git a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/SecurityRoles.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/SecurityRoles.java new file mode 100644 index 000000000..e508955c5 --- /dev/null +++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/SecurityRoles.java @@ -0,0 +1,23 @@ +package org.example.myapp.web; + +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import io.swagger.v3.oas.annotations.security.SecurityRequirement; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +/** + * Specify permitted roles. + */ +@SecurityRequirement(name = "JWT") +@Target(value={METHOD, TYPE}) +@Retention(value=RUNTIME) +public @interface SecurityRoles { + + /** + * Specify the permitted roles. + */ + AppRoles[] value() default {}; +} diff --git a/tests/test-javalin-jsonb/src/main/resources/public/openapi.json b/tests/test-javalin-jsonb/src/main/resources/public/openapi.json index dfa9169c6..9b3412386 100644 --- a/tests/test-javalin-jsonb/src/main/resources/public/openapi.json +++ b/tests/test-javalin-jsonb/src/main/resources/public/openapi.json @@ -1,1650 +1,1555 @@ { - "openapi" : "3.0.1", - "info" : { - "title" : "Example service showing off the Path extension method of controller", - "description" : "Example Javalin controllers with Java and Maven", - "version" : "" - }, - "tags" : [ - { - "name" : "tag1", - "description" : "this is added to openapi tags" - }, - { - "name" : "tag1", - "description" : "it's somethin" - } - ], - "paths" : { - "/bars" : { - "get" : { - "tags" : [ - - ], - "summary" : "", - "description" : "", - "responses" : { - "200" : { - "description" : "", - "content" : { - "text/plain" : { - "schema" : { - "type" : "string" - } - } - } - } - } - } - }, - "/bars/find/{code}" : { - "get" : { - "tags" : [ - - ], - "summary" : "", - "description" : "", - "parameters" : [ - { - "name" : "code", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } - ], - "responses" : { - "200" : { - "description" : "", - "content" : { - "application/json" : { - "schema" : { - "items" : { - "$ref" : "#/components/schemas/Bar" - }, - "type" : "array" - } - } - } - } - } - } - }, - "/bars/{id}" : { - "get" : { - "tags" : [ - - ], - "summary" : "", - "description" : "", - "parameters" : [ - { - "name" : "id", - "in" : "path", - "required" : true, - "schema" : { - "type" : "integer", - "format" : "int64", - "nullable" : false - } - } - ], - "responses" : { - "200" : { - "description" : "", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/Bar" - } - } - } - } - } - } - }, - "/baz" : { - "get" : { - "tags" : [ - - ], - "summary" : "", - "description" : "", - "responses" : { - "200" : { - "description" : "", - "content" : { - "application/json" : { - "schema" : { - "items" : { - "$ref" : "#/components/schemas/Baz" - }, - "type" : "array" - } - } - } - } - } - }, - "post" : { - "tags" : [ - - ], - "summary" : "", - "description" : "", - "requestBody" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/Baz" - } - } - }, - "required" : true - }, - "responses" : { - "201" : { - "description" : "", - "content" : { - "application/json" : { - "schema" : { - "type" : "integer", - "format" : "int64" - } - } - } - } - } - } - }, - "/baz/checkparams/{id}" : { - "get" : { - "tags" : [ - - ], - "summary" : "", - "description" : "", - "parameters" : [ - { - "name" : "id", - "in" : "path", - "required" : true, - "schema" : { - "type" : "integer", - "format" : "int32", - "nullable" : false - } - }, - { - "name" : "p1", - "in" : "query", - "schema" : { - "type" : "string" - } - }, - { - "name" : "p2", - "in" : "query", - "schema" : { - "type" : "number" - } - }, - { - "name" : "p3", - "in" : "query", - "schema" : { - "type" : "integer", - "format" : "int32" - } - }, - { - "name" : "p4", - "in" : "query", - "schema" : { - "type" : "number" - } - }, - { - "name" : "body", - "in" : "query", - "schema" : { - "type" : "string" - } - } - ], - "responses" : { - "200" : { - "description" : "", - "content" : { - "application/json" : { - "schema" : { - "type" : "string" - } - } - } - } - } - } - }, - "/baz/findbyname/{name}" : { - "get" : { - "tags" : [ - - ], - "summary" : "Find the baz by name", - "description" : "This is some more comments about this method.", - "parameters" : [ - { - "name" : "name", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } - ], - "responses" : { - "200" : { - "description" : "The list of baz", - "content" : { - "application/json" : { - "schema" : { - "items" : { - "$ref" : "#/components/schemas/Baz" - }, - "type" : "array" - } - } - } - } - } - } - }, - "/baz/{id}" : { - "get" : { - "tags" : [ - - ], - "summary" : "", - "description" : "", - "parameters" : [ - { - "name" : "id", - "in" : "path", - "required" : true, - "schema" : { - "type" : "integer", - "format" : "int64" - } - } - ], - "responses" : { - "200" : { - "description" : "", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/Baz" - } - } - } - } - } - } - }, - "/hello" : { - "post" : { - "tags" : [ - - ], - "summary" : "Simple example post with JSON body response", - "description" : "", - "requestBody" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/HelloDto" - } - } - }, - "required" : true - }, - "responses" : { - "201" : { - "description" : "", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/HelloDto" - } - } - } - } - } - } - }, - "/hello/async" : { - "get" : { - "tags" : [ - - ], - "summary" : "", - "description" : "", - "responses" : { - "200" : { - "description" : "", - "content" : { - "application/json" : { - "schema" : { - "items" : { - "$ref" : "#/components/schemas/HelloDto" - }, - "type" : "array" - } - } - } - } - } - } - }, - "/hello/findbyname/{name}" : { - "get" : { - "tags" : [ - - ], - "summary" : "Find Hellos by name", - "description" : "", - "parameters" : [ - { - "name" : "name", - "in" : "path", - "description" : "The name to search for", - "required" : true, - "schema" : { - "type" : "string" - } - }, - { - "name" : "myParam", - "in" : "query", - "schema" : { - "type" : "string" - } - } - ], - "responses" : { - "200" : { - "description" : "The Hellos that we found.", - "content" : { - "application/json" : { - "schema" : { - "items" : { - "$ref" : "#/components/schemas/HelloDto" - }, - "type" : "array" - } - } - } - } - } - } - }, - "/hello/message" : { - "get" : { - "tags" : [ - - ], - "summary" : "", - "description" : "", - "responses" : { - "200" : { - "description" : "", - "content" : { - "text/plain" : { - "schema" : { - "type" : "string" - } - } - } - } - } - } - }, - "/hello/mySave" : { - "post" : { - "tags" : [ - - ], - "summary" : "", - "description" : "", - "requestBody" : { - "content" : { - "application/x-www-form-urlencoded" : { - "schema" : { - "type" : "object", - "properties" : { - "name" : { - "type" : "string" - }, - "email" : { - "type" : "string" - }, - "url" : { - "type" : "string" - } - } - } - } - }, - "required" : true - }, - "responses" : { - "201" : { - "description" : "No content" - } - } - } - }, - "/hello/savebean/{foo}" : { - "post" : { - "tags" : [ - - ], - "summary" : "Save the hello using json body", - "description" : "", - "parameters" : [ - { - "name" : "foo", - "in" : "path", - "description" : "The hello doo id", - "required" : true, - "schema" : { - "type" : "string" - } - } - ], - "requestBody" : { - "description" : "The hello body as json", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/HelloDto" - } - } - }, - "required" : true - }, - "responses" : { - "201" : { - "description" : "No content" - } - } - } - }, - "/hello/saveform" : { - "post" : { - "tags" : [ - - ], - "summary" : "Create the new Hello using a form", - "description" : "", - "requestBody" : { - "content" : { - "application/x-www-form-urlencoded" : { - "schema" : { - "$ref" : "#/components/schemas/HelloForm" - } - } - }, - "required" : true - }, - "responses" : { - "201" : { - "description" : "No content" - } - } - } - }, - "/hello/saveform2" : { - "post" : { - "tags" : [ - - ], - "summary" : "", - "description" : "", - "requestBody" : { - "content" : { - "application/x-www-form-urlencoded" : { - "schema" : { - "type" : "object", - "properties" : { - "name" : { - "type" : "string" - }, - "email" : { - "type" : "string" - }, - "url" : { - "type" : "string" - } - } - } - } - }, - "required" : true - }, - "responses" : { - "201" : { - "description" : "No content" - } - } - } - }, - "/hello/saveform3" : { - "post" : { - "tags" : [ - - ], - "summary" : "", - "description" : "", - "requestBody" : { - "content" : { - "application/x-www-form-urlencoded" : { - "schema" : { - "$ref" : "#/components/schemas/HelloForm" - } - } - }, - "required" : true - }, - "responses" : { - "201" : { - "description" : "", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/HelloDto" - } - } - } - } - } - } - }, - "/hello/slash/{name}//other/" : { - "get" : { - "tags" : [ - - ], - "summary" : "", - "description" : "", - "parameters" : [ - { - "name" : "name", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, - { - "name" : "nam0", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, - { - "name" : "nam1", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } - ], - "responses" : { - "200" : { - "description" : "", - "content" : { - "text/plain" : { - "schema" : { - "type" : "string" - } - } - } - } - } - } - }, - "/hello/withMatrix/{year_segment}/{other}" : { - "get" : { - "tags" : [ - - ], - "summary" : "", - "description" : "", - "parameters" : [ - { - "name" : "year", - "in" : "path", - "required" : true, - "schema" : { - "type" : "integer", - "format" : "int32", - "nullable" : false - } - }, - { - "name" : "author", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, - { - "name" : "country", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, - { - "name" : "other", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, - { - "name" : "extra", - "in" : "query", - "schema" : { - "type" : "string" - } - } - ], - "responses" : { - "200" : { - "description" : "", - "content" : { - "text/plain" : { - "schema" : { - "type" : "string" - } - } - } - } - } - } - }, - "/hello/withValidBean" : { - "get" : { - "tags" : [ - - ], - "summary" : "", - "description" : "", - "parameters" : [ - { - "name" : "bean", - "in" : "bean", - "schema" : { - "$ref" : "#/components/schemas/GetBeanForm" - } - } - ], - "responses" : { - "200" : { - "description" : "", - "content" : { - "text/plain" : { - "schema" : { - "type" : "string" - } - } - } - } - } - } - }, - "/hello/{id}" : { - "delete" : { - "tags" : [ - - ], - "summary" : "", - "description" : "", - "parameters" : [ - { - "name" : "id", - "in" : "path", - "required" : true, - "schema" : { - "type" : "integer", - "format" : "int32", - "nullable" : false - } - } - ], - "responses" : { - "204" : { - "description" : "No content" - } - } - } - }, - "/hello/{id}/{date}" : { - "get" : { - "tags" : [ - - ], - "summary" : "Return the Hello DTO", - "description" : "", - "parameters" : [ - { - "name" : "id", - "in" : "path", - "description" : "The hello Id.", - "required" : true, - "schema" : { - "type" : "integer", - "format" : "int32", - "nullable" : false - } - }, - { - "name" : "date", - "in" : "path", - "description" : "The name of the hello", - "required" : true, - "schema" : { - "type" : "string", - "format" : "date" - } - }, - { - "name" : "otherParam", - "in" : "query", - "description" : "Optional other parameter", - "schema" : { - "type" : "string" - } - } - ], - "responses" : { - "200" : { - "description" : "The Hello DTO given the id and name.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/HelloDto" - } - } - } - } - }, - "deprecated" : true - } - }, - "/javalin/health" : { - "get" : { - "tags" : [ - "tag1" - ], - "summary" : "Standard Get", - "description" : "", - "responses" : { - "500" : { - "description" : "a health check", - "content" : { - "text/plain" : { - "schema" : { - "$ref" : "#/components/schemas/ErrorResponse" - } - } - } - }, - "403" : { - "description" : "Not Authorized" - }, - "200" : { - "description" : "a health check", - "content" : { - "text/plain" : { - "schema" : { - "type" : "string" - } - } - } - } - } - } - }, - "/openapi/get" : { - "get" : { - "tags" : [ - - ], - "summary" : "Example of Open API Get (up to the first period is the summary)", - "description" : "When using Javalin Context only This Javadoc description is added to the generated openapi.json", - "responses" : { - "200" : { - "description" : "funny phrase (this part of the javadoc is added to the response desc)", - "content" : { - "text/plain" : { - "schema" : { - "type" : "string" - } - } - } - } - } - } - }, - "/openapi/post" : { - "post" : { - "tags" : [ - "tag1" - ], - "summary" : "Standard Post", - "description" : "uses tag annotation to add tags to openapi json", - "requestBody" : { - "description" : "the body (this is used for generated request body desc)", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/Person" - } - } - }, - "required" : true - }, - "responses" : { - "200" : { - "description" : "overrides @return javadoc description", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/Person" - } - } - } - }, - "201" : { - "description" : "the response body (from javadoc)", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/Person" - } - } - } - }, - "400" : { - "description" : "User not found (Will not have an associated response schema)" - }, - "500" : { - "description" : "Some other Error (Will have this error class as the response class)", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ErrorResponse" - } - } - } - } - } - } - }, - "/openapi/post1" : { - "post" : { - "tags" : [ - - ], - "summary" : "Standard Post", - "description" : "The Deprecated annotation adds \"deprecacted:true\" to the generated json", - "requestBody" : { - "description" : "the body", - "content" : { - "application/json" : { - "schema" : { - "items" : { - "$ref" : "#/components/schemas/Person" - }, - "type" : "array" - } - } - }, - "required" : true - }, - "responses" : { - "400" : { - "description" : "User not found" - }, - "500" : { - "description" : "Some other Error", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ErrorResponse" - } - } - } - }, - "201" : { - "description" : "the response body (from javadoc)", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/Person" - } - } - } - } - }, - "deprecated" : true - } - }, - "/openapi/put" : { - "put" : { - "tags" : [ - - ], - "summary" : "", - "description" : "", - "responses" : { - "204" : { - "description" : "", - "content" : { - "text/plain" : { - "schema" : { - "type" : "string" - } - } - } - }, - "203" : { - "description" : "", - "content" : { - "text/plain" : { - "schema" : { - "type" : "string" - } - } - } - } - } - } - }, - "/req-scoped" : { - "get" : { - "tags" : [ - - ], - "summary" : "", - "description" : "", - "responses" : { - "200" : { - "description" : "", - "content" : { - "text/plain" : { - "schema" : { - "type" : "string" - } - } - } - } - } - } - }, - "/test" : { - "get" : { - "tags" : [ - - ], - "summary" : "", - "description" : "", - "responses" : { - "200" : { - "description" : "", - "content" : { - "text/plain" : { - "schema" : { - "type" : "string" - } - } - } - } - } - } - }, - "/test/async" : { - "get" : { - "tags" : [ - - ], - "summary" : "", - "description" : "", - "responses" : { - "200" : { - "description" : "", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/HelloDto" - } - } - } - } - } - } - }, - "/test/byte" : { - "get" : { - "tags" : [ - - ], - "summary" : "", - "description" : "", - "responses" : { - "200" : { - "description" : "", - "content" : { - "image/png" : { - "schema" : { - "items" : { - "$ref" : "#/components/schemas/byte" - }, - "type" : "array" - } - } - } - } - } - } - }, - "/test/ctx" : { - "get" : { - "tags" : [ - - ], - "summary" : "", - "description" : "", - "responses" : { - "200" : { - "description" : "No content" - } - } - } - }, - "/test/form" : { - "post" : { - "tags" : [ - - ], - "summary" : "", - "description" : "", - "requestBody" : { - "content" : { - "application/x-www-form-urlencoded" : { - "schema" : { - "type" : "object", - "properties" : { - "name" : { - "type" : "string" - }, - "email" : { - "type" : "string" - }, - "url" : { - "type" : "string" - } - } - } - } - }, - "required" : true - }, - "responses" : { - "201" : { - "description" : "", - "content" : { - "application/json" : { - "schema" : { - "type" : "string" - } - } - } - } - } - } - }, - "/test/formBean" : { - "post" : { - "tags" : [ - - ], - "summary" : "", - "description" : "", - "requestBody" : { - "content" : { - "application/x-www-form-urlencoded" : { - "schema" : { - "$ref" : "#/components/schemas/MyForm" - } - } - }, - "required" : true - }, - "responses" : { - "201" : { - "description" : "", - "content" : { - "application/json" : { - "schema" : { - "type" : "string" - } - } - } - } - } - } - }, - "/test/header" : { - "get" : { - "tags" : [ - - ], - "summary" : "", - "description" : "", - "parameters" : [ - { - "name" : "head", - "in" : "header", - "schema" : { - "type" : "string" - } - } - ], - "responses" : { - "200" : { - "description" : "", - "content" : { - "application/json" : { - "schema" : { - "type" : "string" - } - } - } - } - } - } - }, - "/test/hey" : { - "get" : { - "tags" : [ - - ], - "summary" : "", - "description" : "", - "responses" : { - "200" : { - "description" : "", - "content" : { - "text/plain" : { - "schema" : { - "type" : "string" - } - } - } - } - } - } - }, - "/test/int" : { - "put" : { - "tags" : [ - - ], - "summary" : "", - "description" : "", - "responses" : { - "200" : { - "description" : "", - "content" : { - "application/json" : { - "schema" : { - "type" : "integer", - "format" : "int32", - "nullable" : false - } - } - } - } - } - } - }, - "/test/long" : { - "put" : { - "tags" : [ - - ], - "summary" : "", - "description" : "", - "responses" : { - "200" : { - "description" : "", - "content" : { - "application/json" : { - "schema" : { - "type" : "integer", - "format" : "int64", - "nullable" : false - } - } - } - } - } - } - }, - "/test/person" : { - "post" : { - "tags" : [ - - ], - "summary" : "", - "description" : "", - "requestBody" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/Person" - } - } - }, - "required" : true - }, - "responses" : { - "201" : { - "description" : "", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/Person" - } - } - } - } - } - } - }, - "/test/person/update" : { - "put" : { - "tags" : [ - - ], - "summary" : "", - "description" : "", - "requestBody" : { - "content" : { - "application/json" : { - "schema" : { - "items" : { - "$ref" : "#/components/schemas/Person" - }, - "type" : "array" - } - } - }, - "required" : true - }, - "responses" : { - "200" : { - "description" : "", - "content" : { - "application/json" : { - "schema" : { - "type" : "string" - } - } - } - } - } - } - }, - "/test/person/{name}" : { - "get" : { - "tags" : [ - - ], - "summary" : "", - "description" : "", - "parameters" : [ - { - "name" : "name", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } - ], - "responses" : { - "200" : { - "description" : "", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/Person" - } - } - } - } - } - } - }, - "/test/person/{sortBy}/list" : { - "get" : { - "tags" : [ - - ], - "summary" : "", - "description" : "", - "parameters" : [ - { - "name" : "sortBy", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } - ], - "responses" : { - "200" : { - "description" : "", - "content" : { - "application/json" : { - "schema" : { - "items" : { - "$ref" : "#/components/schemas/Person" - }, - "type" : "array" - } - } - } - } - } - } - }, - "/test/person/{sortBy}/map" : { - "get" : { - "tags" : [ - - ], - "summary" : "", - "description" : "", - "parameters" : [ - { - "name" : "sortBy", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } - ], - "responses" : { - "200" : { - "description" : "", - "content" : { - "application/json" : { - "schema" : { - "type" : "object", - "additionalProperties" : { - "$ref" : "#/components/schemas/Person" - } - } - } - } - } - } - } - }, - "/test/person/{sortBy}/set" : { - "get" : { - "tags" : [ - - ], - "summary" : "", - "description" : "", - "parameters" : [ - { - "name" : "sortBy", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } - ], - "responses" : { - "200" : { - "description" : "", - "content" : { - "application/json" : { - "schema" : { - "items" : { - "$ref" : "#/components/schemas/Person" - }, - "type" : "array" - } - } - } - } - } - } - }, - "/test/withMatrixParam/{type-1_segment}/{range_segment}" : { - "get" : { - "tags" : [ - - ], - "summary" : "", - "description" : "", - "parameters" : [ - { - "name" : "type", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, - { - "name" : "category", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, - { - "name" : "vendor", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, - { - "name" : "range", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, - { - "name" : "style", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } - ], - "responses" : { - "200" : { - "description" : "No content" - } - } - } - } - }, - "components" : { - "schemas" : { - "Bar" : { - "type" : "object", - "properties" : { - "id" : { - "type" : "integer", - "format" : "int64", - "nullable" : false - }, - "name" : { - "type" : "string" - } - } - }, - "Baz" : { - "type" : "object", - "properties" : { - "id" : { - "type" : "integer", - "format" : "int64" - }, - "name" : { - "type" : "string" - }, - "startDate" : { - "type" : "string", - "format" : "date" - } - } - }, - "ErrorResponse" : { - "type" : "object", - "properties" : { - "id" : { - "type" : "string" - }, - "text" : { - "type" : "string" - } - } - }, - "GetBeanForm" : { - "type" : "object", - "properties" : { - "name" : { - "maxLength" : 150, - "minLength" : 2, - "type" : "string", - "nullable" : false - }, - "email" : { - "maxLength" : 100, - "type" : "string", - "format" : "email" - } - } - }, - "HelloDto" : { - "type" : "object", - "properties" : { - "id" : { - "type" : "integer", - "format" : "int32", - "nullable" : false - }, - "name" : { - "type" : "string", - "description" : "This is a comment" - }, - "otherParam" : { - "type" : "string", - "description" : "This is a comment" - }, - "gid" : { - "type" : "string", - "format" : "uuid" - }, - "whenAction" : { - "type" : "string", - "format" : "date-time" - } - } - }, - "HelloForm" : { - "type" : "object", - "properties" : { - "name" : { - "maxLength" : 150, - "minLength" : 2, - "type" : "string", - "nullable" : false - }, - "email" : { - "maxLength" : 100, - "type" : "string", - "format" : "email" - }, - "url" : { - "type" : "string" - }, - "startDate" : { - "type" : "string", - "format" : "date" - } - } - }, - "MyForm" : { - "type" : "object", - "properties" : { - "name" : { - "type" : "string" - }, - "email" : { - "type" : "string" - }, - "url" : { - "type" : "string" - } - } - }, - "Person" : { - "type" : "object", - "properties" : { - "id" : { - "type" : "integer", - "format" : "int64", - "nullable" : false - }, - "name" : { - "type" : "string" - } - } - }, - "byte" : { - "type" : "object" - } - } - } + "openapi" : "3.0.1", + "info" : { + "title" : "Example service", + "description" : "Example Javalin controllers with Java and Maven", + "version" : "" + }, + "tags" : [ { + "name" : "tag1", + "description" : "it's somethin" + }, { + "name" : "tag1", + "description" : "this is added to openapi tags" + } ], + "paths" : { + "/bars" : { + "get" : { + "tags" : [ ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/bars/find/{code}" : { + "get" : { + "tags" : [ ], + "summary" : "", + "description" : "", + "parameters" : [ { + "name" : "code", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + } ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "array", + "items" : { + "$ref" : "#/components/schemas/Bar" + } + } + } + } + } + } + } + }, + "/bars/{id}" : { + "get" : { + "tags" : [ ], + "summary" : "", + "description" : "", + "parameters" : [ { + "name" : "id", + "in" : "path", + "required" : true, + "schema" : { + "type" : "integer", + "format" : "int64", + "nullable" : false + } + } ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Bar" + } + } + } + } + } + } + }, + "/baz" : { + "get" : { + "tags" : [ ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "array", + "items" : { + "$ref" : "#/components/schemas/Baz" + } + } + } + } + } + } + }, + "post" : { + "tags" : [ ], + "summary" : "", + "description" : "", + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Baz" + } + } + }, + "required" : true + }, + "responses" : { + "201" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "integer", + "format" : "int64" + } + } + } + } + } + } + }, + "/baz/checkparams/{id}" : { + "get" : { + "tags" : [ ], + "summary" : "", + "description" : "", + "parameters" : [ { + "name" : "id", + "in" : "path", + "required" : true, + "schema" : { + "type" : "integer", + "format" : "int32", + "nullable" : false + } + }, { + "name" : "p1", + "in" : "query", + "schema" : { + "type" : "string" + } + }, { + "name" : "p2", + "in" : "query", + "schema" : { + "type" : "number" + } + }, { + "name" : "p3", + "in" : "query", + "schema" : { + "type" : "integer", + "format" : "int32" + } + }, { + "name" : "p4", + "in" : "query", + "schema" : { + "type" : "number" + } + }, { + "name" : "body", + "in" : "query", + "schema" : { + "type" : "string" + } + } ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/baz/findbyname/{name}" : { + "get" : { + "tags" : [ ], + "summary" : "Find the baz by name", + "description" : "This is some more comments about this method.", + "parameters" : [ { + "name" : "name", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + } ], + "responses" : { + "200" : { + "description" : "The list of baz", + "content" : { + "application/json" : { + "schema" : { + "type" : "array", + "items" : { + "$ref" : "#/components/schemas/Baz" + } + } + } + } + } + } + } + }, + "/baz/{id}" : { + "get" : { + "tags" : [ ], + "summary" : "", + "description" : "", + "parameters" : [ { + "name" : "id", + "in" : "path", + "required" : true, + "schema" : { + "type" : "integer", + "format" : "int64" + } + } ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Baz" + } + } + } + } + } + } + }, + "/hello" : { + "post" : { + "tags" : [ ], + "summary" : "Simple example post with JSON body response", + "description" : "", + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/HelloDto" + } + } + }, + "required" : true + }, + "responses" : { + "201" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/HelloDto" + } + } + } + } + } + } + }, + "/hello/async" : { + "get" : { + "tags" : [ ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "array", + "items" : { + "$ref" : "#/components/schemas/HelloDto" + } + } + } + } + } + } + } + }, + "/hello/findbyname/{name}" : { + "get" : { + "tags" : [ ], + "summary" : "Find Hellos by name", + "description" : "", + "parameters" : [ { + "name" : "name", + "in" : "path", + "description" : "The name to search for", + "required" : true, + "schema" : { + "type" : "string" + } + }, { + "name" : "myParam", + "in" : "query", + "schema" : { + "type" : "string" + } + } ], + "responses" : { + "200" : { + "description" : "The Hellos that we found.", + "content" : { + "application/json" : { + "schema" : { + "type" : "array", + "items" : { + "$ref" : "#/components/schemas/HelloDto" + } + } + } + } + } + } + } + }, + "/hello/message" : { + "get" : { + "tags" : [ ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/hello/mySave" : { + "post" : { + "tags" : [ ], + "summary" : "", + "description" : "", + "requestBody" : { + "content" : { + "application/x-www-form-urlencoded" : { + "schema" : { + "type" : "object", + "properties" : { + "name" : { + "type" : "string" + }, + "email" : { + "type" : "string" + }, + "url" : { + "type" : "string" + } + } + } + } + }, + "required" : true + }, + "responses" : { + "201" : { + "description" : "No content" + } + } + } + }, + "/hello/savebean/{foo}" : { + "post" : { + "tags" : [ ], + "summary" : "Save the hello using json body", + "description" : "", + "parameters" : [ { + "name" : "foo", + "in" : "path", + "description" : "The hello doo id", + "required" : true, + "schema" : { + "type" : "string" + } + } ], + "requestBody" : { + "description" : "The hello body as json", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/HelloDto" + } + } + }, + "required" : true + }, + "responses" : { + "201" : { + "description" : "No content" + } + } + } + }, + "/hello/saveform" : { + "post" : { + "tags" : [ ], + "summary" : "Create the new Hello using a form", + "description" : "", + "requestBody" : { + "content" : { + "application/x-www-form-urlencoded" : { + "schema" : { + "$ref" : "#/components/schemas/HelloForm" + } + } + }, + "required" : true + }, + "responses" : { + "201" : { + "description" : "No content" + } + } + } + }, + "/hello/saveform2" : { + "post" : { + "tags" : [ ], + "summary" : "", + "description" : "", + "requestBody" : { + "content" : { + "application/x-www-form-urlencoded" : { + "schema" : { + "type" : "object", + "properties" : { + "name" : { + "type" : "string" + }, + "email" : { + "type" : "string" + }, + "url" : { + "type" : "string" + } + } + } + } + }, + "required" : true + }, + "responses" : { + "201" : { + "description" : "No content" + } + } + } + }, + "/hello/saveform3" : { + "post" : { + "tags" : [ ], + "summary" : "", + "description" : "", + "requestBody" : { + "content" : { + "application/x-www-form-urlencoded" : { + "schema" : { + "$ref" : "#/components/schemas/HelloForm" + } + } + }, + "required" : true + }, + "responses" : { + "201" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/HelloDto" + } + } + } + } + } + } + }, + "/hello/slash/{name}//other/" : { + "get" : { + "tags" : [ ], + "summary" : "", + "description" : "", + "parameters" : [ { + "name" : "name", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + }, { + "name" : "nam0", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + }, { + "name" : "nam1", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + } ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/hello/withMatrix/{year_segment}/{other}" : { + "get" : { + "tags" : [ ], + "summary" : "", + "description" : "", + "parameters" : [ { + "name" : "year", + "in" : "path", + "required" : true, + "schema" : { + "type" : "integer", + "format" : "int32", + "nullable" : false + } + }, { + "name" : "author", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + }, { + "name" : "country", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + }, { + "name" : "other", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + }, { + "name" : "extra", + "in" : "query", + "schema" : { + "type" : "string" + } + } ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/hello/withValidBean" : { + "get" : { + "tags" : [ ], + "summary" : "", + "description" : "", + "parameters" : [ { + "name" : "bean", + "in" : "bean", + "schema" : { + "$ref" : "#/components/schemas/GetBeanForm" + } + } ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/hello/{id}" : { + "delete" : { + "tags" : [ ], + "summary" : "", + "description" : "", + "parameters" : [ { + "name" : "id", + "in" : "path", + "required" : true, + "schema" : { + "type" : "integer", + "format" : "int32", + "nullable" : false + } + } ], + "responses" : { + "204" : { + "description" : "No content" + } + } + } + }, + "/hello/{id}/{date}" : { + "get" : { + "tags" : [ ], + "summary" : "Return the Hello DTO", + "description" : "", + "parameters" : [ { + "name" : "id", + "in" : "path", + "description" : "The hello Id.", + "required" : true, + "schema" : { + "type" : "integer", + "format" : "int32", + "nullable" : false + } + }, { + "name" : "date", + "in" : "path", + "description" : "The name of the hello", + "required" : true, + "schema" : { + "type" : "string", + "format" : "date" + } + }, { + "name" : "otherParam", + "in" : "query", + "description" : "Optional other parameter", + "schema" : { + "type" : "string" + } + } ], + "responses" : { + "200" : { + "description" : "The Hello DTO given the id and name.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/HelloDto" + } + } + } + } + }, + "deprecated" : true + } + }, + "/javalin/health" : { + "get" : { + "tags" : [ "tag1" ], + "summary" : "Standard Get", + "description" : "", + "responses" : { + "500" : { + "description" : "a health check", + "content" : { + "text/plain" : { + "schema" : { + "$ref" : "#/components/schemas/ErrorResponse" + } + } + } + }, + "403" : { + "description" : "Not Authorized" + }, + "200" : { + "description" : "a health check", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/openapi/get" : { + "get" : { + "tags" : [ ], + "summary" : "Example of Open API Get (up to the first period is the summary)", + "description" : "When using Javalin Context only This Javadoc description is added to the generated openapi.json", + "responses" : { + "200" : { + "description" : "funny phrase (this part of the javadoc is added to the response desc)", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/openapi/post" : { + "post" : { + "tags" : [ "tag1" ], + "summary" : "Standard Post", + "description" : "uses tag annotation to add tags to openapi json", + "requestBody" : { + "description" : "the body (this is used for generated request body desc)", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Person" + } + } + }, + "required" : true + }, + "responses" : { + "200" : { + "description" : "overrides @return javadoc description", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Person" + } + } + } + }, + "201" : { + "description" : "the response body (from javadoc)", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Person" + } + } + } + }, + "400" : { + "description" : "User not found (Will not have an associated response schema)" + }, + "500" : { + "description" : "Some other Error (Will have this error class as the response class)", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ErrorResponse" + } + } + } + } + } + } + }, + "/openapi/post1" : { + "post" : { + "tags" : [ ], + "summary" : "Standard Post", + "description" : "The Deprecated annotation adds \"deprecacted:true\" to the generated json", + "requestBody" : { + "description" : "the body", + "content" : { + "application/json" : { + "schema" : { + "type" : "array", + "items" : { + "$ref" : "#/components/schemas/Person" + } + } + } + }, + "required" : true + }, + "responses" : { + "400" : { + "description" : "User not found" + }, + "500" : { + "description" : "Some other Error", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ErrorResponse" + } + } + } + }, + "201" : { + "description" : "the response body (from javadoc)", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Person" + } + } + } + } + }, + "deprecated" : true + } + }, + "/openapi/put" : { + "put" : { + "tags" : [ ], + "summary" : "", + "description" : "", + "responses" : { + "204" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + }, + "203" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/req-scoped" : { + "get" : { + "tags" : [ ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/security/first" : { + "get" : { + "tags" : [ ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "string" + } + } + } + } + }, + "security" : [ { + "JWT" : [ ] + } ] + } + }, + "/security/second" : { + "get" : { + "tags" : [ ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "string" + } + } + } + } + }, + "security" : [ { + "JWT" : [ ] + } ] + } + }, + "/test" : { + "get" : { + "tags" : [ ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/test/async" : { + "get" : { + "tags" : [ ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/HelloDto" + } + } + } + } + } + } + }, + "/test/byte" : { + "get" : { + "tags" : [ ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "", + "content" : { + "image/png" : { + "schema" : { + "type" : "array", + "items" : { + "$ref" : "#/components/schemas/byte" + } + } + } + } + } + } + } + }, + "/test/ctx" : { + "get" : { + "tags" : [ ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "No content" + } + } + } + }, + "/test/form" : { + "post" : { + "tags" : [ ], + "summary" : "", + "description" : "", + "requestBody" : { + "content" : { + "application/x-www-form-urlencoded" : { + "schema" : { + "type" : "object", + "properties" : { + "name" : { + "type" : "string" + }, + "email" : { + "type" : "string" + }, + "url" : { + "type" : "string" + } + } + } + } + }, + "required" : true + }, + "responses" : { + "201" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/test/formBean" : { + "post" : { + "tags" : [ ], + "summary" : "", + "description" : "", + "requestBody" : { + "content" : { + "application/x-www-form-urlencoded" : { + "schema" : { + "$ref" : "#/components/schemas/MyForm" + } + } + }, + "required" : true + }, + "responses" : { + "201" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/test/header" : { + "get" : { + "tags" : [ ], + "summary" : "", + "description" : "", + "parameters" : [ { + "name" : "head", + "in" : "header", + "schema" : { + "type" : "string" + } + } ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/test/hey" : { + "get" : { + "tags" : [ ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/test/int" : { + "put" : { + "tags" : [ ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "integer", + "format" : "int32", + "nullable" : false + } + } + } + } + } + } + }, + "/test/long" : { + "put" : { + "tags" : [ ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "integer", + "format" : "int64", + "nullable" : false + } + } + } + } + } + } + }, + "/test/person" : { + "post" : { + "tags" : [ ], + "summary" : "", + "description" : "", + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Person" + } + } + }, + "required" : true + }, + "responses" : { + "201" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Person" + } + } + } + } + } + } + }, + "/test/person/update" : { + "put" : { + "tags" : [ ], + "summary" : "", + "description" : "", + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "type" : "array", + "items" : { + "$ref" : "#/components/schemas/Person" + } + } + } + }, + "required" : true + }, + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/test/person/{name}" : { + "get" : { + "tags" : [ ], + "summary" : "", + "description" : "", + "parameters" : [ { + "name" : "name", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + } ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Person" + } + } + } + } + } + } + }, + "/test/person/{sortBy}/list" : { + "get" : { + "tags" : [ ], + "summary" : "", + "description" : "", + "parameters" : [ { + "name" : "sortBy", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + } ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "array", + "items" : { + "$ref" : "#/components/schemas/Person" + } + } + } + } + } + } + } + }, + "/test/person/{sortBy}/map" : { + "get" : { + "tags" : [ ], + "summary" : "", + "description" : "", + "parameters" : [ { + "name" : "sortBy", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + } ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "object", + "additionalProperties" : { + "$ref" : "#/components/schemas/Person" + } + } + } + } + } + } + } + }, + "/test/person/{sortBy}/set" : { + "get" : { + "tags" : [ ], + "summary" : "", + "description" : "", + "parameters" : [ { + "name" : "sortBy", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + } ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "array", + "items" : { + "$ref" : "#/components/schemas/Person" + } + } + } + } + } + } + } + }, + "/test/withMatrixParam/{type-1_segment}/{range_segment}" : { + "get" : { + "tags" : [ ], + "summary" : "", + "description" : "", + "parameters" : [ { + "name" : "type", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + }, { + "name" : "category", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + }, { + "name" : "vendor", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + }, { + "name" : "range", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + }, { + "name" : "style", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + } ], + "responses" : { + "200" : { + "description" : "No content" + } + } + } + } + }, + "components" : { + "schemas" : { + "Bar" : { + "type" : "object", + "properties" : { + "id" : { + "type" : "integer", + "format" : "int64", + "nullable" : false + }, + "name" : { + "type" : "string" + } + } + }, + "Baz" : { + "type" : "object", + "properties" : { + "id" : { + "type" : "integer", + "format" : "int64" + }, + "name" : { + "type" : "string" + }, + "startDate" : { + "type" : "string", + "format" : "date" + } + } + }, + "ErrorResponse" : { + "type" : "object", + "properties" : { + "id" : { + "type" : "string" + }, + "text" : { + "type" : "string" + } + } + }, + "GetBeanForm" : { + "type" : "object", + "properties" : { + "name" : { + "maxLength" : 150, + "minLength" : 2, + "type" : "string", + "nullable" : false + }, + "email" : { + "maxLength" : 100, + "type" : "string", + "format" : "email" + } + } + }, + "HelloDto" : { + "type" : "object", + "properties" : { + "id" : { + "type" : "integer", + "format" : "int32", + "nullable" : false + }, + "name" : { + "type" : "string", + "description" : "This is a comment" + }, + "otherParam" : { + "type" : "string", + "description" : "This is a comment" + }, + "gid" : { + "type" : "string", + "format" : "uuid" + }, + "whenAction" : { + "type" : "string", + "format" : "date-time" + } + } + }, + "HelloForm" : { + "type" : "object", + "properties" : { + "name" : { + "maxLength" : 150, + "minLength" : 2, + "type" : "string", + "nullable" : false + }, + "email" : { + "maxLength" : 100, + "type" : "string", + "format" : "email" + }, + "url" : { + "type" : "string" + }, + "startDate" : { + "type" : "string", + "format" : "date" + } + } + }, + "MyForm" : { + "type" : "object", + "properties" : { + "name" : { + "type" : "string" + }, + "email" : { + "type" : "string" + }, + "url" : { + "type" : "string" + } + } + }, + "Person" : { + "type" : "object", + "properties" : { + "id" : { + "type" : "integer", + "format" : "int64", + "nullable" : false + }, + "name" : { + "type" : "string" + } + } + }, + "byte" : { + "type" : "object" + } + }, + "securitySchemes" : { + "JWT" : { + "type" : "apiKey", + "description" : "JSON Web Tokens are an open, industry standard RFC 7519 method for representing claims securely between two parties.", + "name" : "access_token", + "in" : "query" + } + } + } } \ No newline at end of file diff --git a/tests/test-javalin-jsonb/src/test/resources/expectedInheritedOpenApi.json b/tests/test-javalin-jsonb/src/test/resources/expectedInheritedOpenApi.json index 4b1490dac..95cec1ab1 100644 --- a/tests/test-javalin-jsonb/src/test/resources/expectedInheritedOpenApi.json +++ b/tests/test-javalin-jsonb/src/test/resources/expectedInheritedOpenApi.json @@ -1,64 +1,60 @@ { - "openapi" : "3.0.1", - "info" : { - "title" : "Example service showing off the Path extension method of controller", - "version" : "" - }, - "tags" : [ - { - "name" : "tag1", - "description" : "it's somethin" - } - ], - "paths" : { - "/javalin/health" : { - "get" : { - "tags" : [ - "tag1" - ], - "summary" : "Standard Get", - "description" : "", - "responses" : { - "500" : { - "description" : "a health check", - "content" : { - "text/plain" : { - "schema" : { - "$ref" : "#/components/schemas/ErrorResponse" - } - } - } - }, - "403" : { - "description" : "Not Authorized" - }, - "200" : { - "description" : "a health check", - "content" : { - "text/plain" : { - "schema" : { - "type" : "string" - } - } - } - } - } - } - } - }, - "components" : { - "schemas" : { - "ErrorResponse" : { - "type" : "object", - "properties" : { - "id" : { - "type" : "string" - }, - "text" : { - "type" : "string" - } - } - } - } - } -} + "openapi" : "3.0.1", + "info" : { + "title" : "Example service showing off the Path extension method of controller", + "version" : "" + }, + "tags" : [ { + "name" : "tag1", + "description" : "it's somethin" + } ], + "paths" : { + "/javalin/health" : { + "get" : { + "tags" : [ "tag1" ], + "summary" : "Standard Get", + "description" : "", + "responses" : { + "500" : { + "description" : "a health check", + "content" : { + "text/plain" : { + "schema" : { + "$ref" : "#/components/schemas/ErrorResponse" + } + } + } + }, + "403" : { + "description" : "Not Authorized" + }, + "200" : { + "description" : "a health check", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + } + }, + "components" : { + "schemas" : { + "ErrorResponse" : { + "type" : "object", + "properties" : { + "id" : { + "type" : "string" + }, + "text" : { + "type" : "string" + } + } + } + } + } +} \ No newline at end of file diff --git a/tests/test-javalin-jsonb/src/test/resources/expectedOpenApi.json b/tests/test-javalin-jsonb/src/test/resources/expectedOpenApi.json index 14772e3e7..51a998431 100644 --- a/tests/test-javalin-jsonb/src/test/resources/expectedOpenApi.json +++ b/tests/test-javalin-jsonb/src/test/resources/expectedOpenApi.json @@ -1,29 +1,27 @@ { - "openapi": "3.0.1", - "info": { - "title": "Example service", - "description": "Example Javalin controllers with Java and Maven", - "version": "" + "openapi" : "3.0.1", + "info" : { + "title" : "Example service", + "description" : "Example Javalin controllers with Java and Maven", + "version" : "" }, - "tags": [ - { - "name": "tag1", - "description": "this is added to openapi tags" - } - ], - "paths": { - "/openapi/get": { - "get": { - "tags": [], - "summary": "Example of Open API Get (up to the first period is the summary)", - "description": "When using Javalin Context only This Javadoc description is added to the generated openapi.json", - "responses": { - "200": { - "description": "funny phrase (this part of the javadoc is added to the response desc)", - "content": { - "text/plain": { - "schema": { - "type": "string" + "tags" : [ { + "name" : "tag1", + "description" : "this is added to openapi tags" + } ], + "paths" : { + "/openapi/get" : { + "get" : { + "tags" : [ ], + "summary" : "Example of Open API Get (up to the first period is the summary)", + "description" : "When using Javalin Context only This Javadoc description is added to the generated openapi.json", + "responses" : { + "200" : { + "description" : "funny phrase (this part of the javadoc is added to the response desc)", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" } } } @@ -31,54 +29,52 @@ } } }, - "/openapi/post": { - "post": { - "tags": [ - "tag1" - ], - "summary": "Standard Post", - "description": "uses tag annotation to add tags to openapi json", - "requestBody": { - "description": "the body (this is used for generated request body desc)", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Person" + "/openapi/post" : { + "post" : { + "tags" : [ "tag1" ], + "summary" : "Standard Post", + "description" : "uses tag annotation to add tags to openapi json", + "requestBody" : { + "description" : "the body (this is used for generated request body desc)", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Person" } } }, - "required": true + "required" : true }, - "responses": { - "200": { - "description": "overrides @return javadoc description", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Person" + "responses" : { + "200" : { + "description" : "overrides @return javadoc description", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Person" } } } }, - "201": { - "description": "the response body (from javadoc)", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Person" + "201" : { + "description" : "the response body (from javadoc)", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Person" } } } }, - "400": { - "description": "User not found (Will not have an associated response schema)" + "400" : { + "description" : "User not found (Will not have an associated response schema)" }, - "500": { - "description": "Some other Error (Will have this error class as the response class)", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" + "500" : { + "description" : "Some other Error (Will have this error class as the response class)", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ErrorResponse" } } } @@ -86,111 +82,109 @@ } } }, - "/openapi/post1": { - "post": { - "tags": [], - "summary": "Standard Post", - "description": "The Deprecated annotation adds \"deprecacted:true\" to the generated json", - "requestBody": { - "description": "the body", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Person" + "/openapi/post1" : { + "post" : { + "tags" : [ ], + "summary" : "Standard Post", + "description" : "The Deprecated annotation adds \"deprecacted:true\" to the generated json", + "requestBody" : { + "description" : "the body", + "content" : { + "application/json" : { + "schema" : { + "type" : "array", + "items" : { + "$ref" : "#/components/schemas/Person" } } } }, - "required": true + "required" : true }, - "responses": { - "400": { - "description": "User not found" + "responses" : { + "400" : { + "description" : "User not found" }, - "500": { - "description": "Some other Error", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" + "500" : { + "description" : "Some other Error", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ErrorResponse" } } } }, - "201": { - "description": "the response body (from javadoc)", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Person" + "201" : { + "description" : "the response body (from javadoc)", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Person" } } } } }, - "deprecated": true + "deprecated" : true } }, - "/openapi/put" : { - "put" : { - "tags" : [ - - ], - "summary" : "", - "description" : "", - "responses" : { - "204" : { - "description" : "", - "content" : { - "text/plain" : { - "schema" : { - "type" : "string" - } - } - } - }, - "203" : { - "description" : "", - "content" : { - "text/plain" : { - "schema" : { - "type" : "string" - } - } - } - } - } - } - } - }, - "components": { - "schemas": { - "ErrorResponse": { - "type": "object", - "properties": { - "id": { - "type": "string" + "/openapi/put" : { + "put" : { + "tags" : [ ], + "summary" : "", + "description" : "", + "responses" : { + "204" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + }, + "203" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + } + }, + "components" : { + "schemas" : { + "ErrorResponse" : { + "type" : "object", + "properties" : { + "id" : { + "type" : "string" }, - "text": { - "type": "string" + "text" : { + "type" : "string" } } }, - "Person": { - "type": "object", - "properties": { - "id": { - "type": "integer", - "format": "int64", - "nullable": false + "Person" : { + "type" : "object", + "properties" : { + "id" : { + "type" : "integer", + "format" : "int64", + "nullable" : false }, - "name": { - "type": "string" + "name" : { + "type" : "string" } } } } } -} +} \ No newline at end of file diff --git a/tests/test-javalin/src/main/resources/public/openapi.json b/tests/test-javalin/src/main/resources/public/openapi.json index 482ad9e9a..ebea982df 100644 --- a/tests/test-javalin/src/main/resources/public/openapi.json +++ b/tests/test-javalin/src/main/resources/public/openapi.json @@ -1,903 +1,819 @@ { - "openapi" : "3.0.1", - "info" : { - "title" : "Example service", - "description" : "Example Javalin controllers with Java and Maven", - "version" : "" - }, - "paths" : { - "/bars" : { - "get" : { - "tags" : [ - - ], - "summary" : "", - "description" : "", - "responses" : { - "200" : { - "description" : "", - "content" : { - "text/plain" : { - "schema" : { - "type" : "string" - } - } - } - } - } - } - }, - "/bars/find/{code}" : { - "get" : { - "tags" : [ - - ], - "summary" : "", - "description" : "", - "parameters" : [ - { - "name" : "code", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } - ], - "responses" : { - "200" : { - "description" : "", - "content" : { - "application/json" : { - "schema" : { - "items" : { - "$ref" : "#/components/schemas/Bar" - }, - "type" : "array" - } - } - } - } - } - } - }, - "/bars/{id}" : { - "get" : { - "tags" : [ - - ], - "summary" : "", - "description" : "", - "parameters" : [ - { - "name" : "id", - "in" : "path", - "required" : true, - "schema" : { - "type" : "integer", - "format" : "int64", - "nullable" : false - } - } - ], - "responses" : { - "200" : { - "description" : "", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/Bar" - } - } - } - } - } - } - }, - "/baz" : { - "get" : { - "tags" : [ - - ], - "summary" : "", - "description" : "", - "responses" : { - "200" : { - "description" : "", - "content" : { - "application/json" : { - "schema" : { - "items" : { - "$ref" : "#/components/schemas/Baz" - }, - "type" : "array" - } - } - } - } - } - }, - "post" : { - "tags" : [ - - ], - "summary" : "", - "description" : "", - "requestBody" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/Baz" - } - } - }, - "required" : true - }, - "responses" : { - "201" : { - "description" : "", - "content" : { - "application/json" : { - "schema" : { - "type" : "integer", - "format" : "int64" - } - } - } - } - } - } - }, - "/baz/checkparams/{id}" : { - "get" : { - "tags" : [ - - ], - "summary" : "", - "description" : "", - "parameters" : [ - { - "name" : "id", - "in" : "path", - "required" : true, - "schema" : { - "type" : "integer", - "format" : "int32", - "nullable" : false - } - }, - { - "name" : "p1", - "in" : "query", - "schema" : { - "type" : "string" - } - }, - { - "name" : "p2", - "in" : "query", - "schema" : { - "type" : "number" - } - }, - { - "name" : "p3", - "in" : "query", - "schema" : { - "type" : "integer", - "format" : "int32" - } - }, - { - "name" : "p4", - "in" : "query", - "schema" : { - "type" : "number" - } - }, - { - "name" : "body", - "in" : "query", - "schema" : { - "type" : "string" - } - } - ], - "responses" : { - "200" : { - "description" : "", - "content" : { - "application/json" : { - "schema" : { - "type" : "string" - } - } - } - } - } - } - }, - "/baz/findbyname/{name}" : { - "get" : { - "tags" : [ - - ], - "summary" : "Find the baz by name", - "description" : "This is some more comments about this method.", - "parameters" : [ - { - "name" : "name", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } - ], - "responses" : { - "200" : { - "description" : "The list of baz", - "content" : { - "application/json" : { - "schema" : { - "items" : { - "$ref" : "#/components/schemas/Baz" - }, - "type" : "array" - } - } - } - } - } - } - }, - "/baz/{id}" : { - "get" : { - "tags" : [ - - ], - "summary" : "", - "description" : "", - "parameters" : [ - { - "name" : "id", - "in" : "path", - "required" : true, - "schema" : { - "type" : "integer", - "format" : "int64" - } - } - ], - "responses" : { - "200" : { - "description" : "", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/Baz" - } - } - } - } - } - } - }, - "/hello" : { - "post" : { - "tags" : [ - - ], - "summary" : "Simple example post with JSON body response", - "description" : "", - "requestBody" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/HelloDto" - } - } - }, - "required" : true - }, - "responses" : { - "201" : { - "description" : "", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/HelloDto" - } - } - } - } - } - } - }, - "/hello/async" : { - "get" : { - "tags" : [ - - ], - "summary" : "", - "description" : "", - "responses" : { - "200" : { - "description" : "", - "content" : { - "application/json" : { - "schema" : { - "items" : { - "$ref" : "#/components/schemas/HelloDto" - }, - "type" : "array" - } - } - } - } - } - } - }, - "/hello/findbyname/{name}" : { - "get" : { - "tags" : [ - - ], - "summary" : "Find Hellos by name", - "description" : "", - "parameters" : [ - { - "name" : "name", - "in" : "path", - "description" : "The name to search for", - "required" : true, - "schema" : { - "type" : "string" - } - }, - { - "name" : "myParam", - "in" : "query", - "schema" : { - "type" : "string" - } - } - ], - "responses" : { - "200" : { - "description" : "The Hellos that we found.", - "content" : { - "application/json" : { - "schema" : { - "items" : { - "$ref" : "#/components/schemas/HelloDto" - }, - "type" : "array" - } - } - } - } - } - } - }, - "/hello/message" : { - "get" : { - "tags" : [ - - ], - "summary" : "", - "description" : "", - "responses" : { - "200" : { - "description" : "", - "content" : { - "text/plain" : { - "schema" : { - "type" : "string" - } - } - } - } - } - } - }, - "/hello/mySave" : { - "post" : { - "tags" : [ - - ], - "summary" : "", - "description" : "", - "requestBody" : { - "content" : { - "application/x-www-form-urlencoded" : { - "schema" : { - "type" : "object", - "properties" : { - "name" : { - "type" : "string" - }, - "email" : { - "type" : "string" - }, - "url" : { - "type" : "string" - } - } - } - } - }, - "required" : true - }, - "responses" : { - "201" : { - "description" : "No content" - } - } - } - }, - "/hello/savebean/{foo}" : { - "post" : { - "tags" : [ - - ], - "summary" : "Save the hello using json body", - "description" : "", - "parameters" : [ - { - "name" : "foo", - "in" : "path", - "description" : "The hello doo id", - "required" : true, - "schema" : { - "type" : "string" - } - } - ], - "requestBody" : { - "description" : "The hello body as json", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/HelloDto" - } - } - }, - "required" : true - }, - "responses" : { - "201" : { - "description" : "No content" - } - } - } - }, - "/hello/saveform" : { - "post" : { - "tags" : [ - - ], - "summary" : "Create the new Hello using a form", - "description" : "", - "requestBody" : { - "content" : { - "application/x-www-form-urlencoded" : { - "schema" : { - "$ref" : "#/components/schemas/HelloForm" - } - } - }, - "required" : true - }, - "responses" : { - "201" : { - "description" : "No content" - } - } - } - }, - "/hello/saveform2" : { - "post" : { - "tags" : [ - - ], - "summary" : "", - "description" : "", - "requestBody" : { - "content" : { - "application/x-www-form-urlencoded" : { - "schema" : { - "type" : "object", - "properties" : { - "name" : { - "type" : "string" - }, - "email" : { - "type" : "string" - }, - "url" : { - "type" : "string" - } - } - } - } - }, - "required" : true - }, - "responses" : { - "201" : { - "description" : "No content" - } - } - } - }, - "/hello/saveform3" : { - "post" : { - "tags" : [ - - ], - "summary" : "", - "description" : "", - "requestBody" : { - "content" : { - "application/x-www-form-urlencoded" : { - "schema" : { - "$ref" : "#/components/schemas/HelloForm" - } - } - }, - "required" : true - }, - "responses" : { - "201" : { - "description" : "", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/HelloDto" - } - } - } - } - } - } - }, - "/hello/slash/{name}//other/" : { - "get" : { - "tags" : [ - - ], - "summary" : "", - "description" : "", - "parameters" : [ - { - "name" : "name", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, - { - "name" : "nam0", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, - { - "name" : "nam1", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } - ], - "responses" : { - "200" : { - "description" : "", - "content" : { - "text/plain" : { - "schema" : { - "type" : "string" - } - } - } - } - } - } - }, - "/hello/withMatrix/{year_segment}/{other}" : { - "get" : { - "tags" : [ - - ], - "summary" : "", - "description" : "", - "parameters" : [ - { - "name" : "year", - "in" : "path", - "required" : true, - "schema" : { - "type" : "integer", - "format" : "int32", - "nullable" : false - } - }, - { - "name" : "author", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, - { - "name" : "country", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, - { - "name" : "other", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, - { - "name" : "extra", - "in" : "query", - "schema" : { - "type" : "string" - } - } - ], - "responses" : { - "200" : { - "description" : "", - "content" : { - "text/plain" : { - "schema" : { - "type" : "string" - } - } - } - } - } - } - }, - "/hello/withValidBean" : { - "get" : { - "tags" : [ - - ], - "summary" : "", - "description" : "", - "parameters" : [ - { - "name" : "bean", - "in" : "bean", - "schema" : { - "$ref" : "#/components/schemas/GetBeanForm" - } - } - ], - "responses" : { - "200" : { - "description" : "", - "content" : { - "text/plain" : { - "schema" : { - "type" : "string" - } - } - } - } - } - } - }, - "/hello/{id}" : { - "delete" : { - "tags" : [ - - ], - "summary" : "", - "description" : "", - "parameters" : [ - { - "name" : "id", - "in" : "path", - "required" : true, - "schema" : { - "type" : "integer", - "format" : "int32", - "nullable" : false - } - } - ], - "responses" : { - "204" : { - "description" : "No content" - } - } - } - }, - "/hello/{id}/{date}" : { - "get" : { - "tags" : [ - - ], - "summary" : "Return the Hello DTO", - "description" : "", - "parameters" : [ - { - "name" : "id", - "in" : "path", - "description" : "The hello Id.", - "required" : true, - "schema" : { - "type" : "integer", - "format" : "int32", - "nullable" : false - } - }, - { - "name" : "date", - "in" : "path", - "description" : "The name of the hello", - "required" : true, - "schema" : { - "type" : "string", - "format" : "date" - } - }, - { - "name" : "otherParam", - "in" : "query", - "description" : "Optional other parameter", - "schema" : { - "type" : "string" - } - } - ], - "responses" : { - "200" : { - "description" : "The Hello DTO given the id and name.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/HelloDto" - } - } - } - } - }, - "deprecated" : true - } - }, - "/req-scoped" : { - "get" : { - "tags" : [ - - ], - "summary" : "", - "description" : "", - "responses" : { - "200" : { - "description" : "", - "content" : { - "text/plain" : { - "schema" : { - "type" : "string" - } - } - } - } - } - } - } - }, - "components" : { - "schemas" : { - "Bar" : { - "type" : "object", - "properties" : { - "id" : { - "type" : "integer", - "format" : "int64", - "nullable" : false - }, - "name" : { - "type" : "string" - } - } - }, - "Baz" : { - "type" : "object", - "properties" : { - "id" : { - "type" : "integer", - "format" : "int64" - }, - "name" : { - "type" : "string" - }, - "startDate" : { - "type" : "string", - "format" : "date" - } - } - }, - "GetBeanForm" : { - "type" : "object", - "properties" : { - "name" : { - "maxLength" : 150, - "minLength" : 2, - "type" : "string", - "nullable" : false - }, - "email" : { - "maxLength" : 100, - "type" : "string", - "format" : "email" - } - } - }, - "HelloDto" : { - "type" : "object", - "properties" : { - "id" : { - "type" : "integer", - "format" : "int32", - "nullable" : false - }, - "name" : { - "type" : "string" - }, - "otherParam" : { - "type" : "string" - }, - "gid" : { - "type" : "string", - "format" : "uuid" - }, - "whenAction" : { - "type" : "string", - "format" : "date-time" - } - } - }, - "HelloForm" : { - "type" : "object", - "properties" : { - "name" : { - "maxLength" : 150, - "minLength" : 2, - "type" : "string", - "nullable" : false - }, - "email" : { - "maxLength" : 100, - "type" : "string", - "format" : "email" - }, - "url" : { - "type" : "string" - }, - "startDate" : { - "type" : "string", - "format" : "date" - } - } - } - } - } + "openapi" : "3.0.1", + "info" : { + "title" : "Example service", + "description" : "Example Javalin controllers with Java and Maven", + "version" : "" + }, + "paths" : { + "/bars" : { + "get" : { + "tags" : [ ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/bars/find/{code}" : { + "get" : { + "tags" : [ ], + "summary" : "", + "description" : "", + "parameters" : [ { + "name" : "code", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + } ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "array", + "items" : { + "$ref" : "#/components/schemas/Bar" + } + } + } + } + } + } + } + }, + "/bars/{id}" : { + "get" : { + "tags" : [ ], + "summary" : "", + "description" : "", + "parameters" : [ { + "name" : "id", + "in" : "path", + "required" : true, + "schema" : { + "type" : "integer", + "format" : "int64", + "nullable" : false + } + } ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Bar" + } + } + } + } + } + } + }, + "/baz" : { + "get" : { + "tags" : [ ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "array", + "items" : { + "$ref" : "#/components/schemas/Baz" + } + } + } + } + } + } + }, + "post" : { + "tags" : [ ], + "summary" : "", + "description" : "", + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Baz" + } + } + }, + "required" : true + }, + "responses" : { + "201" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "integer", + "format" : "int64" + } + } + } + } + } + } + }, + "/baz/checkparams/{id}" : { + "get" : { + "tags" : [ ], + "summary" : "", + "description" : "", + "parameters" : [ { + "name" : "id", + "in" : "path", + "required" : true, + "schema" : { + "type" : "integer", + "format" : "int32", + "nullable" : false + } + }, { + "name" : "p1", + "in" : "query", + "schema" : { + "type" : "string" + } + }, { + "name" : "p2", + "in" : "query", + "schema" : { + "type" : "number" + } + }, { + "name" : "p3", + "in" : "query", + "schema" : { + "type" : "integer", + "format" : "int32" + } + }, { + "name" : "p4", + "in" : "query", + "schema" : { + "type" : "number" + } + }, { + "name" : "body", + "in" : "query", + "schema" : { + "type" : "string" + } + } ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/baz/findbyname/{name}" : { + "get" : { + "tags" : [ ], + "summary" : "Find the baz by name", + "description" : "This is some more comments about this method.", + "parameters" : [ { + "name" : "name", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + } ], + "responses" : { + "200" : { + "description" : "The list of baz", + "content" : { + "application/json" : { + "schema" : { + "type" : "array", + "items" : { + "$ref" : "#/components/schemas/Baz" + } + } + } + } + } + } + } + }, + "/baz/{id}" : { + "get" : { + "tags" : [ ], + "summary" : "", + "description" : "", + "parameters" : [ { + "name" : "id", + "in" : "path", + "required" : true, + "schema" : { + "type" : "integer", + "format" : "int64" + } + } ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Baz" + } + } + } + } + } + } + }, + "/hello" : { + "post" : { + "tags" : [ ], + "summary" : "Simple example post with JSON body response", + "description" : "", + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/HelloDto" + } + } + }, + "required" : true + }, + "responses" : { + "201" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/HelloDto" + } + } + } + } + } + } + }, + "/hello/async" : { + "get" : { + "tags" : [ ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "array", + "items" : { + "$ref" : "#/components/schemas/HelloDto" + } + } + } + } + } + } + } + }, + "/hello/findbyname/{name}" : { + "get" : { + "tags" : [ ], + "summary" : "Find Hellos by name", + "description" : "", + "parameters" : [ { + "name" : "name", + "in" : "path", + "description" : "The name to search for", + "required" : true, + "schema" : { + "type" : "string" + } + }, { + "name" : "myParam", + "in" : "query", + "schema" : { + "type" : "string" + } + } ], + "responses" : { + "200" : { + "description" : "The Hellos that we found.", + "content" : { + "application/json" : { + "schema" : { + "type" : "array", + "items" : { + "$ref" : "#/components/schemas/HelloDto" + } + } + } + } + } + } + } + }, + "/hello/message" : { + "get" : { + "tags" : [ ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/hello/mySave" : { + "post" : { + "tags" : [ ], + "summary" : "", + "description" : "", + "requestBody" : { + "content" : { + "application/x-www-form-urlencoded" : { + "schema" : { + "type" : "object", + "properties" : { + "name" : { + "type" : "string" + }, + "email" : { + "type" : "string" + }, + "url" : { + "type" : "string" + } + } + } + } + }, + "required" : true + }, + "responses" : { + "201" : { + "description" : "No content" + } + } + } + }, + "/hello/savebean/{foo}" : { + "post" : { + "tags" : [ ], + "summary" : "Save the hello using json body", + "description" : "", + "parameters" : [ { + "name" : "foo", + "in" : "path", + "description" : "The hello doo id", + "required" : true, + "schema" : { + "type" : "string" + } + } ], + "requestBody" : { + "description" : "The hello body as json", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/HelloDto" + } + } + }, + "required" : true + }, + "responses" : { + "201" : { + "description" : "No content" + } + } + } + }, + "/hello/saveform" : { + "post" : { + "tags" : [ ], + "summary" : "Create the new Hello using a form", + "description" : "", + "requestBody" : { + "content" : { + "application/x-www-form-urlencoded" : { + "schema" : { + "$ref" : "#/components/schemas/HelloForm" + } + } + }, + "required" : true + }, + "responses" : { + "201" : { + "description" : "No content" + } + } + } + }, + "/hello/saveform2" : { + "post" : { + "tags" : [ ], + "summary" : "", + "description" : "", + "requestBody" : { + "content" : { + "application/x-www-form-urlencoded" : { + "schema" : { + "type" : "object", + "properties" : { + "name" : { + "type" : "string" + }, + "email" : { + "type" : "string" + }, + "url" : { + "type" : "string" + } + } + } + } + }, + "required" : true + }, + "responses" : { + "201" : { + "description" : "No content" + } + } + } + }, + "/hello/saveform3" : { + "post" : { + "tags" : [ ], + "summary" : "", + "description" : "", + "requestBody" : { + "content" : { + "application/x-www-form-urlencoded" : { + "schema" : { + "$ref" : "#/components/schemas/HelloForm" + } + } + }, + "required" : true + }, + "responses" : { + "201" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/HelloDto" + } + } + } + } + } + } + }, + "/hello/slash/{name}//other/" : { + "get" : { + "tags" : [ ], + "summary" : "", + "description" : "", + "parameters" : [ { + "name" : "name", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + }, { + "name" : "nam0", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + }, { + "name" : "nam1", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + } ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/hello/withMatrix/{year_segment}/{other}" : { + "get" : { + "tags" : [ ], + "summary" : "", + "description" : "", + "parameters" : [ { + "name" : "year", + "in" : "path", + "required" : true, + "schema" : { + "type" : "integer", + "format" : "int32", + "nullable" : false + } + }, { + "name" : "author", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + }, { + "name" : "country", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + }, { + "name" : "other", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + }, { + "name" : "extra", + "in" : "query", + "schema" : { + "type" : "string" + } + } ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/hello/withValidBean" : { + "get" : { + "tags" : [ ], + "summary" : "", + "description" : "", + "parameters" : [ { + "name" : "bean", + "in" : "bean", + "schema" : { + "$ref" : "#/components/schemas/GetBeanForm" + } + } ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/hello/{id}" : { + "delete" : { + "tags" : [ ], + "summary" : "", + "description" : "", + "parameters" : [ { + "name" : "id", + "in" : "path", + "required" : true, + "schema" : { + "type" : "integer", + "format" : "int32", + "nullable" : false + } + } ], + "responses" : { + "204" : { + "description" : "No content" + } + } + } + }, + "/hello/{id}/{date}" : { + "get" : { + "tags" : [ ], + "summary" : "Return the Hello DTO", + "description" : "", + "parameters" : [ { + "name" : "id", + "in" : "path", + "description" : "The hello Id.", + "required" : true, + "schema" : { + "type" : "integer", + "format" : "int32", + "nullable" : false + } + }, { + "name" : "date", + "in" : "path", + "description" : "The name of the hello", + "required" : true, + "schema" : { + "type" : "string", + "format" : "date" + } + }, { + "name" : "otherParam", + "in" : "query", + "description" : "Optional other parameter", + "schema" : { + "type" : "string" + } + } ], + "responses" : { + "200" : { + "description" : "The Hello DTO given the id and name.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/HelloDto" + } + } + } + } + }, + "deprecated" : true + } + }, + "/req-scoped" : { + "get" : { + "tags" : [ ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + } + }, + "components" : { + "schemas" : { + "Bar" : { + "type" : "object", + "properties" : { + "id" : { + "type" : "integer", + "format" : "int64", + "nullable" : false + }, + "name" : { + "type" : "string" + } + } + }, + "Baz" : { + "type" : "object", + "properties" : { + "id" : { + "type" : "integer", + "format" : "int64" + }, + "name" : { + "type" : "string" + }, + "startDate" : { + "type" : "string", + "format" : "date" + } + } + }, + "GetBeanForm" : { + "type" : "object", + "properties" : { + "name" : { + "maxLength" : 150, + "minLength" : 2, + "type" : "string", + "nullable" : false + }, + "email" : { + "maxLength" : 100, + "type" : "string", + "format" : "email" + } + } + }, + "HelloDto" : { + "type" : "object", + "properties" : { + "id" : { + "type" : "integer", + "format" : "int32", + "nullable" : false + }, + "name" : { + "type" : "string" + }, + "otherParam" : { + "type" : "string" + }, + "gid" : { + "type" : "string", + "format" : "uuid" + }, + "whenAction" : { + "type" : "string", + "format" : "date-time" + } + } + }, + "HelloForm" : { + "type" : "object", + "properties" : { + "name" : { + "maxLength" : 150, + "minLength" : 2, + "type" : "string", + "nullable" : false + }, + "email" : { + "maxLength" : 100, + "type" : "string", + "format" : "email" + }, + "url" : { + "type" : "string" + }, + "startDate" : { + "type" : "string", + "format" : "date" + } + } + } + } + } } \ No newline at end of file diff --git a/tests/test-jex/src/main/resources/public/openapi.json b/tests/test-jex/src/main/resources/public/openapi.json index fb4378388..aa864f845 100644 --- a/tests/test-jex/src/main/resources/public/openapi.json +++ b/tests/test-jex/src/main/resources/public/openapi.json @@ -1,238 +1,213 @@ { - "openapi" : "3.0.1", - "info" : { - "title" : "", - "version" : "" - }, - "paths" : { - "/" : { - "get" : { - "tags" : [ - - ], - "summary" : "", - "description" : "", - "responses" : { - "200" : { - "description" : "", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/HelloDto" - } - } - } - } - } - }, - "put" : { - "tags" : [ - - ], - "summary" : "", - "description" : "", - "requestBody" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/HelloDto" - } - } - }, - "required" : true - }, - "responses" : { - "204" : { - "description" : "No content" - } - } - } - }, - "/other/{name}" : { - "get" : { - "tags" : [ - - ], - "summary" : "", - "description" : "", - "parameters" : [ - { - "name" : "name", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } - ], - "responses" : { - "200" : { - "description" : "", - "content" : { - "text/plain" : { - "schema" : { - "type" : "string" - } - } - } - } - } - } - }, - "/plain" : { - "get" : { - "tags" : [ - - ], - "summary" : "", - "description" : "", - "responses" : { - "200" : { - "description" : "", - "content" : { - "text/plain" : { - "schema" : { - "type" : "string" - } - } - } - } - } - } - }, - "/splat/{name}//other/" : { - "get" : { - "tags" : [ - - ], - "summary" : "", - "description" : "", - "parameters" : [ - { - "name" : "name", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } - ], - "responses" : { - "200" : { - "description" : "", - "content" : { - "text/plain" : { - "schema" : { - "type" : "string" - } - } - } - } - } - } - }, - "/splat2/{name}//other/" : { - "get" : { - "tags" : [ - - ], - "summary" : "", - "description" : "", - "parameters" : [ - { - "name" : "name", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, - { - "name" : "nam0", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, - { - "name" : "nam1", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - } - ], - "responses" : { - "200" : { - "description" : "", - "content" : { - "text/plain" : { - "schema" : { - "type" : "string" - } - } - } - } - } - } - }, - "/withDefault/{name}" : { - "get" : { - "tags" : [ - - ], - "summary" : "", - "description" : "", - "parameters" : [ - { - "name" : "name", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, - { - "name" : "limit", - "in" : "query", - "schema" : { - "type" : "string" - } - } - ], - "responses" : { - "200" : { - "description" : "", - "content" : { - "text/plain" : { - "schema" : { - "type" : "string" - } - } - } - } - } - } - } - }, - "components" : { - "schemas" : { - "HelloDto" : { - "type" : "object", - "properties" : { - "id" : { - "type" : "integer", - "format" : "int32", - "nullable" : false - }, - "name" : { - "type" : "string", - "nullable" : false - } - } - } - } - } + "openapi" : "3.0.1", + "info" : { + "title" : "", + "version" : "" + }, + "paths" : { + "/" : { + "get" : { + "tags" : [ ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/HelloDto" + } + } + } + } + } + }, + "put" : { + "tags" : [ ], + "summary" : "", + "description" : "", + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/HelloDto" + } + } + }, + "required" : true + }, + "responses" : { + "204" : { + "description" : "No content" + } + } + } + }, + "/other/{name}" : { + "get" : { + "tags" : [ ], + "summary" : "", + "description" : "", + "parameters" : [ { + "name" : "name", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + } ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/plain" : { + "get" : { + "tags" : [ ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/splat/{name}//other/" : { + "get" : { + "tags" : [ ], + "summary" : "", + "description" : "", + "parameters" : [ { + "name" : "name", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + } ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/splat2/{name}//other/" : { + "get" : { + "tags" : [ ], + "summary" : "", + "description" : "", + "parameters" : [ { + "name" : "name", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + }, { + "name" : "nam0", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + }, { + "name" : "nam1", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + } ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/withDefault/{name}" : { + "get" : { + "tags" : [ ], + "summary" : "", + "description" : "", + "parameters" : [ { + "name" : "name", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + }, { + "name" : "limit", + "in" : "query", + "schema" : { + "type" : "string" + } + } ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + } + }, + "components" : { + "schemas" : { + "HelloDto" : { + "type" : "object", + "properties" : { + "id" : { + "type" : "integer", + "format" : "int32", + "nullable" : false + }, + "name" : { + "type" : "string", + "nullable" : false + } + } + } + } + } } \ No newline at end of file From 0ce033854b786ef9d7ce44e920444fd110ab52b3 Mon Sep 17 00:00:00 2001 From: ZY Date: Mon, 20 Feb 2023 09:54:03 +0800 Subject: [PATCH 0612/1323] Use jackson instead of swagger core --- http-generator-core/pom.xml | 18 +- .../generator/core/openapi/DocContext.java | 14 +- .../src/main/java/module-info.java | 1 - pom.xml | 1 + .../src/main/resources/public/openapi.json | 721 +++++++++++++----- .../resources/expectedInheritedOpenApi.json | 25 +- .../src/test/resources/expectedOpenApi.json | 91 ++- .../src/main/resources/public/openapi.json | 389 +++++++--- .../src/main/resources/public/openapi.json | 87 ++- 9 files changed, 967 insertions(+), 380 deletions(-) diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 88b19ba30..866970b38 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -30,14 +30,18 @@ io.swagger.core.v3 - swagger-core + swagger-annotations ${swagger.version} - - - jakarta.validation - jakarta.validation-api - - + + + io.swagger.core.v3 + swagger-models + ${swagger.version} + + + com.fasterxml.jackson.core + jackson-databind + ${jackson.version} diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/DocContext.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/DocContext.java index f1491b558..d73416a6b 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/DocContext.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/DocContext.java @@ -1,11 +1,15 @@ package io.avaje.http.generator.core.openapi; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.core.util.DefaultPrettyPrinter; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; import io.avaje.http.generator.core.OpenAPIDefinitionPrism; import io.avaje.http.generator.core.SecuritySchemePrism; import io.avaje.http.generator.core.SecuritySchemesPrism; import io.avaje.http.generator.core.TagPrism; import io.avaje.http.generator.core.TagsPrism; -import io.swagger.v3.core.util.Json; import io.swagger.v3.oas.models.Components; import io.swagger.v3.oas.models.OpenAPI; import io.swagger.v3.oas.models.Operation; @@ -208,7 +212,13 @@ public void readApiDefinition(Element element) { public void writeApi() { final var openAPI = getApiForWriting(); try (var metaWriter = createMetaWriter()) { - Json.pretty().writeValue(metaWriter, openAPI); + var mapper = new ObjectMapper(); + mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); + mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false); + mapper.configure(SerializationFeature.WRITE_ENUMS_USING_TO_STRING, true); + mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); + mapper.writer(new DefaultPrettyPrinter()).writeValue(metaWriter, openAPI); } catch (final Exception e) { logError(null, "Error writing openapi file" + e.getMessage()); e.printStackTrace(); diff --git a/http-generator-core/src/main/java/module-info.java b/http-generator-core/src/main/java/module-info.java index a81133ccf..61c8ca012 100644 --- a/http-generator-core/src/main/java/module-info.java +++ b/http-generator-core/src/main/java/module-info.java @@ -9,7 +9,6 @@ requires com.fasterxml.jackson.annotation; requires com.fasterxml.jackson.core; requires com.fasterxml.jackson.databind; - requires io.swagger.v3.core; // SHADED: All content after this line will be removed at package time requires static io.avaje.prism; diff --git a/pom.xml b/pom.xml index 3803d0458..6ae65d32d 100644 --- a/pom.xml +++ b/pom.xml @@ -20,6 +20,7 @@ true 2.2.8 + 2.14.2 ${project.build.directory}${file.separator}module-info.shade diff --git a/tests/test-javalin-jsonb/src/main/resources/public/openapi.json b/tests/test-javalin-jsonb/src/main/resources/public/openapi.json index 9b3412386..9e5bc2505 100644 --- a/tests/test-javalin-jsonb/src/main/resources/public/openapi.json +++ b/tests/test-javalin-jsonb/src/main/resources/public/openapi.json @@ -24,8 +24,11 @@ "content" : { "text/plain" : { "schema" : { - "type" : "string" - } + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] + }, + "exampleSetFlag" : false } } } @@ -42,7 +45,9 @@ "in" : "path", "required" : true, "schema" : { - "type" : "string" + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] } } ], "responses" : { @@ -52,10 +57,14 @@ "application/json" : { "schema" : { "type" : "array", + "exampleSetFlag" : false, "items" : { - "$ref" : "#/components/schemas/Bar" - } - } + "$ref" : "#/components/schemas/Bar", + "exampleSetFlag" : false + }, + "types" : [ "array" ] + }, + "exampleSetFlag" : false } } } @@ -74,7 +83,9 @@ "schema" : { "type" : "integer", "format" : "int64", - "nullable" : false + "nullable" : false, + "exampleSetFlag" : false, + "types" : [ "integer" ] } } ], "responses" : { @@ -83,8 +94,10 @@ "content" : { "application/json" : { "schema" : { - "$ref" : "#/components/schemas/Bar" - } + "$ref" : "#/components/schemas/Bar", + "exampleSetFlag" : false + }, + "exampleSetFlag" : false } } } @@ -103,10 +116,14 @@ "application/json" : { "schema" : { "type" : "array", + "exampleSetFlag" : false, "items" : { - "$ref" : "#/components/schemas/Baz" - } - } + "$ref" : "#/components/schemas/Baz", + "exampleSetFlag" : false + }, + "types" : [ "array" ] + }, + "exampleSetFlag" : false } } } @@ -120,8 +137,10 @@ "content" : { "application/json" : { "schema" : { - "$ref" : "#/components/schemas/Baz" - } + "$ref" : "#/components/schemas/Baz", + "exampleSetFlag" : false + }, + "exampleSetFlag" : false } }, "required" : true @@ -133,8 +152,11 @@ "application/json" : { "schema" : { "type" : "integer", - "format" : "int64" - } + "format" : "int64", + "exampleSetFlag" : false, + "types" : [ "integer" ] + }, + "exampleSetFlag" : false } } } @@ -153,38 +175,50 @@ "schema" : { "type" : "integer", "format" : "int32", - "nullable" : false + "nullable" : false, + "exampleSetFlag" : false, + "types" : [ "integer" ] } }, { "name" : "p1", "in" : "query", "schema" : { - "type" : "string" + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] } }, { "name" : "p2", "in" : "query", "schema" : { - "type" : "number" + "type" : "number", + "exampleSetFlag" : false, + "types" : [ "number" ] } }, { "name" : "p3", "in" : "query", "schema" : { "type" : "integer", - "format" : "int32" + "format" : "int32", + "exampleSetFlag" : false, + "types" : [ "integer" ] } }, { "name" : "p4", "in" : "query", "schema" : { - "type" : "number" + "type" : "number", + "exampleSetFlag" : false, + "types" : [ "number" ] } }, { "name" : "body", "in" : "query", "schema" : { - "type" : "string" + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] } } ], "responses" : { @@ -193,8 +227,11 @@ "content" : { "application/json" : { "schema" : { - "type" : "string" - } + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] + }, + "exampleSetFlag" : false } } } @@ -211,7 +248,9 @@ "in" : "path", "required" : true, "schema" : { - "type" : "string" + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] } } ], "responses" : { @@ -221,10 +260,14 @@ "application/json" : { "schema" : { "type" : "array", + "exampleSetFlag" : false, "items" : { - "$ref" : "#/components/schemas/Baz" - } - } + "$ref" : "#/components/schemas/Baz", + "exampleSetFlag" : false + }, + "types" : [ "array" ] + }, + "exampleSetFlag" : false } } } @@ -242,7 +285,9 @@ "required" : true, "schema" : { "type" : "integer", - "format" : "int64" + "format" : "int64", + "exampleSetFlag" : false, + "types" : [ "integer" ] } } ], "responses" : { @@ -251,8 +296,10 @@ "content" : { "application/json" : { "schema" : { - "$ref" : "#/components/schemas/Baz" - } + "$ref" : "#/components/schemas/Baz", + "exampleSetFlag" : false + }, + "exampleSetFlag" : false } } } @@ -268,8 +315,10 @@ "content" : { "application/json" : { "schema" : { - "$ref" : "#/components/schemas/HelloDto" - } + "$ref" : "#/components/schemas/HelloDto", + "exampleSetFlag" : false + }, + "exampleSetFlag" : false } }, "required" : true @@ -280,8 +329,10 @@ "content" : { "application/json" : { "schema" : { - "$ref" : "#/components/schemas/HelloDto" - } + "$ref" : "#/components/schemas/HelloDto", + "exampleSetFlag" : false + }, + "exampleSetFlag" : false } } } @@ -300,10 +351,14 @@ "application/json" : { "schema" : { "type" : "array", + "exampleSetFlag" : false, "items" : { - "$ref" : "#/components/schemas/HelloDto" - } - } + "$ref" : "#/components/schemas/HelloDto", + "exampleSetFlag" : false + }, + "types" : [ "array" ] + }, + "exampleSetFlag" : false } } } @@ -321,13 +376,17 @@ "description" : "The name to search for", "required" : true, "schema" : { - "type" : "string" + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] } }, { "name" : "myParam", "in" : "query", "schema" : { - "type" : "string" + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] } } ], "responses" : { @@ -337,10 +396,14 @@ "application/json" : { "schema" : { "type" : "array", + "exampleSetFlag" : false, "items" : { - "$ref" : "#/components/schemas/HelloDto" - } - } + "$ref" : "#/components/schemas/HelloDto", + "exampleSetFlag" : false + }, + "types" : [ "array" ] + }, + "exampleSetFlag" : false } } } @@ -358,8 +421,11 @@ "content" : { "text/plain" : { "schema" : { - "type" : "string" - } + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] + }, + "exampleSetFlag" : false } } } @@ -378,16 +444,24 @@ "type" : "object", "properties" : { "name" : { - "type" : "string" + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] }, "email" : { - "type" : "string" + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] }, "url" : { - "type" : "string" + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] } - } - } + }, + "exampleSetFlag" : false + }, + "exampleSetFlag" : false } }, "required" : true @@ -410,7 +484,9 @@ "description" : "The hello doo id", "required" : true, "schema" : { - "type" : "string" + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] } } ], "requestBody" : { @@ -418,8 +494,10 @@ "content" : { "application/json" : { "schema" : { - "$ref" : "#/components/schemas/HelloDto" - } + "$ref" : "#/components/schemas/HelloDto", + "exampleSetFlag" : false + }, + "exampleSetFlag" : false } }, "required" : true @@ -440,8 +518,10 @@ "content" : { "application/x-www-form-urlencoded" : { "schema" : { - "$ref" : "#/components/schemas/HelloForm" - } + "$ref" : "#/components/schemas/HelloForm", + "exampleSetFlag" : false + }, + "exampleSetFlag" : false } }, "required" : true @@ -465,16 +545,24 @@ "type" : "object", "properties" : { "name" : { - "type" : "string" + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] }, "email" : { - "type" : "string" + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] }, "url" : { - "type" : "string" + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] } - } - } + }, + "exampleSetFlag" : false + }, + "exampleSetFlag" : false } }, "required" : true @@ -495,8 +583,10 @@ "content" : { "application/x-www-form-urlencoded" : { "schema" : { - "$ref" : "#/components/schemas/HelloForm" - } + "$ref" : "#/components/schemas/HelloForm", + "exampleSetFlag" : false + }, + "exampleSetFlag" : false } }, "required" : true @@ -507,8 +597,10 @@ "content" : { "application/json" : { "schema" : { - "$ref" : "#/components/schemas/HelloDto" - } + "$ref" : "#/components/schemas/HelloDto", + "exampleSetFlag" : false + }, + "exampleSetFlag" : false } } } @@ -525,21 +617,27 @@ "in" : "path", "required" : true, "schema" : { - "type" : "string" + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] } }, { "name" : "nam0", "in" : "path", "required" : true, "schema" : { - "type" : "string" + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] } }, { "name" : "nam1", "in" : "path", "required" : true, "schema" : { - "type" : "string" + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] } } ], "responses" : { @@ -548,8 +646,11 @@ "content" : { "text/plain" : { "schema" : { - "type" : "string" - } + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] + }, + "exampleSetFlag" : false } } } @@ -568,34 +669,44 @@ "schema" : { "type" : "integer", "format" : "int32", - "nullable" : false + "nullable" : false, + "exampleSetFlag" : false, + "types" : [ "integer" ] } }, { "name" : "author", "in" : "path", "required" : true, "schema" : { - "type" : "string" + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] } }, { "name" : "country", "in" : "path", "required" : true, "schema" : { - "type" : "string" + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] } }, { "name" : "other", "in" : "path", "required" : true, "schema" : { - "type" : "string" + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] } }, { "name" : "extra", "in" : "query", "schema" : { - "type" : "string" + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] } } ], "responses" : { @@ -604,8 +715,11 @@ "content" : { "text/plain" : { "schema" : { - "type" : "string" - } + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] + }, + "exampleSetFlag" : false } } } @@ -621,7 +735,8 @@ "name" : "bean", "in" : "bean", "schema" : { - "$ref" : "#/components/schemas/GetBeanForm" + "$ref" : "#/components/schemas/GetBeanForm", + "exampleSetFlag" : false } } ], "responses" : { @@ -630,8 +745,11 @@ "content" : { "text/plain" : { "schema" : { - "type" : "string" - } + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] + }, + "exampleSetFlag" : false } } } @@ -650,7 +768,9 @@ "schema" : { "type" : "integer", "format" : "int32", - "nullable" : false + "nullable" : false, + "exampleSetFlag" : false, + "types" : [ "integer" ] } } ], "responses" : { @@ -673,7 +793,9 @@ "schema" : { "type" : "integer", "format" : "int32", - "nullable" : false + "nullable" : false, + "exampleSetFlag" : false, + "types" : [ "integer" ] } }, { "name" : "date", @@ -682,14 +804,18 @@ "required" : true, "schema" : { "type" : "string", - "format" : "date" + "format" : "date", + "exampleSetFlag" : false, + "types" : [ "string" ] } }, { "name" : "otherParam", "in" : "query", "description" : "Optional other parameter", "schema" : { - "type" : "string" + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] } } ], "responses" : { @@ -698,8 +824,10 @@ "content" : { "application/json" : { "schema" : { - "$ref" : "#/components/schemas/HelloDto" - } + "$ref" : "#/components/schemas/HelloDto", + "exampleSetFlag" : false + }, + "exampleSetFlag" : false } } } @@ -718,8 +846,10 @@ "content" : { "text/plain" : { "schema" : { - "$ref" : "#/components/schemas/ErrorResponse" - } + "$ref" : "#/components/schemas/ErrorResponse", + "exampleSetFlag" : false + }, + "exampleSetFlag" : false } } }, @@ -731,8 +861,11 @@ "content" : { "text/plain" : { "schema" : { - "type" : "string" - } + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] + }, + "exampleSetFlag" : false } } } @@ -750,8 +883,11 @@ "content" : { "text/plain" : { "schema" : { - "type" : "string" - } + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] + }, + "exampleSetFlag" : false } } } @@ -768,8 +904,10 @@ "content" : { "application/json" : { "schema" : { - "$ref" : "#/components/schemas/Person" - } + "$ref" : "#/components/schemas/Person", + "exampleSetFlag" : false + }, + "exampleSetFlag" : false } }, "required" : true @@ -780,8 +918,10 @@ "content" : { "application/json" : { "schema" : { - "$ref" : "#/components/schemas/Person" - } + "$ref" : "#/components/schemas/Person", + "exampleSetFlag" : false + }, + "exampleSetFlag" : false } } }, @@ -790,8 +930,10 @@ "content" : { "application/json" : { "schema" : { - "$ref" : "#/components/schemas/Person" - } + "$ref" : "#/components/schemas/Person", + "exampleSetFlag" : false + }, + "exampleSetFlag" : false } } }, @@ -803,8 +945,10 @@ "content" : { "application/json" : { "schema" : { - "$ref" : "#/components/schemas/ErrorResponse" - } + "$ref" : "#/components/schemas/ErrorResponse", + "exampleSetFlag" : false + }, + "exampleSetFlag" : false } } } @@ -822,10 +966,14 @@ "application/json" : { "schema" : { "type" : "array", + "exampleSetFlag" : false, "items" : { - "$ref" : "#/components/schemas/Person" - } - } + "$ref" : "#/components/schemas/Person", + "exampleSetFlag" : false + }, + "types" : [ "array" ] + }, + "exampleSetFlag" : false } }, "required" : true @@ -839,8 +987,10 @@ "content" : { "application/json" : { "schema" : { - "$ref" : "#/components/schemas/ErrorResponse" - } + "$ref" : "#/components/schemas/ErrorResponse", + "exampleSetFlag" : false + }, + "exampleSetFlag" : false } } }, @@ -849,8 +999,10 @@ "content" : { "application/json" : { "schema" : { - "$ref" : "#/components/schemas/Person" - } + "$ref" : "#/components/schemas/Person", + "exampleSetFlag" : false + }, + "exampleSetFlag" : false } } } @@ -869,8 +1021,11 @@ "content" : { "text/plain" : { "schema" : { - "type" : "string" - } + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] + }, + "exampleSetFlag" : false } } }, @@ -879,8 +1034,11 @@ "content" : { "text/plain" : { "schema" : { - "type" : "string" - } + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] + }, + "exampleSetFlag" : false } } } @@ -898,8 +1056,11 @@ "content" : { "text/plain" : { "schema" : { - "type" : "string" - } + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] + }, + "exampleSetFlag" : false } } } @@ -917,8 +1078,11 @@ "content" : { "application/json" : { "schema" : { - "type" : "string" - } + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] + }, + "exampleSetFlag" : false } } } @@ -939,8 +1103,11 @@ "content" : { "application/json" : { "schema" : { - "type" : "string" - } + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] + }, + "exampleSetFlag" : false } } } @@ -961,8 +1128,11 @@ "content" : { "text/plain" : { "schema" : { - "type" : "string" - } + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] + }, + "exampleSetFlag" : false } } } @@ -980,8 +1150,10 @@ "content" : { "application/json" : { "schema" : { - "$ref" : "#/components/schemas/HelloDto" - } + "$ref" : "#/components/schemas/HelloDto", + "exampleSetFlag" : false + }, + "exampleSetFlag" : false } } } @@ -1000,10 +1172,14 @@ "image/png" : { "schema" : { "type" : "array", + "exampleSetFlag" : false, "items" : { - "$ref" : "#/components/schemas/byte" - } - } + "$ref" : "#/components/schemas/byte", + "exampleSetFlag" : false + }, + "types" : [ "array" ] + }, + "exampleSetFlag" : false } } } @@ -1034,16 +1210,24 @@ "type" : "object", "properties" : { "name" : { - "type" : "string" + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] }, "email" : { - "type" : "string" + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] }, "url" : { - "type" : "string" + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] } - } - } + }, + "exampleSetFlag" : false + }, + "exampleSetFlag" : false } }, "required" : true @@ -1054,8 +1238,11 @@ "content" : { "application/json" : { "schema" : { - "type" : "string" - } + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] + }, + "exampleSetFlag" : false } } } @@ -1071,8 +1258,10 @@ "content" : { "application/x-www-form-urlencoded" : { "schema" : { - "$ref" : "#/components/schemas/MyForm" - } + "$ref" : "#/components/schemas/MyForm", + "exampleSetFlag" : false + }, + "exampleSetFlag" : false } }, "required" : true @@ -1083,8 +1272,11 @@ "content" : { "application/json" : { "schema" : { - "type" : "string" - } + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] + }, + "exampleSetFlag" : false } } } @@ -1100,7 +1292,9 @@ "name" : "head", "in" : "header", "schema" : { - "type" : "string" + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] } } ], "responses" : { @@ -1109,8 +1303,11 @@ "content" : { "application/json" : { "schema" : { - "type" : "string" - } + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] + }, + "exampleSetFlag" : false } } } @@ -1128,8 +1325,11 @@ "content" : { "text/plain" : { "schema" : { - "type" : "string" - } + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] + }, + "exampleSetFlag" : false } } } @@ -1149,8 +1349,11 @@ "schema" : { "type" : "integer", "format" : "int32", - "nullable" : false - } + "nullable" : false, + "exampleSetFlag" : false, + "types" : [ "integer" ] + }, + "exampleSetFlag" : false } } } @@ -1170,8 +1373,11 @@ "schema" : { "type" : "integer", "format" : "int64", - "nullable" : false - } + "nullable" : false, + "exampleSetFlag" : false, + "types" : [ "integer" ] + }, + "exampleSetFlag" : false } } } @@ -1187,8 +1393,10 @@ "content" : { "application/json" : { "schema" : { - "$ref" : "#/components/schemas/Person" - } + "$ref" : "#/components/schemas/Person", + "exampleSetFlag" : false + }, + "exampleSetFlag" : false } }, "required" : true @@ -1199,8 +1407,10 @@ "content" : { "application/json" : { "schema" : { - "$ref" : "#/components/schemas/Person" - } + "$ref" : "#/components/schemas/Person", + "exampleSetFlag" : false + }, + "exampleSetFlag" : false } } } @@ -1217,10 +1427,14 @@ "application/json" : { "schema" : { "type" : "array", + "exampleSetFlag" : false, "items" : { - "$ref" : "#/components/schemas/Person" - } - } + "$ref" : "#/components/schemas/Person", + "exampleSetFlag" : false + }, + "types" : [ "array" ] + }, + "exampleSetFlag" : false } }, "required" : true @@ -1231,8 +1445,11 @@ "content" : { "application/json" : { "schema" : { - "type" : "string" - } + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] + }, + "exampleSetFlag" : false } } } @@ -1249,7 +1466,9 @@ "in" : "path", "required" : true, "schema" : { - "type" : "string" + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] } } ], "responses" : { @@ -1258,8 +1477,10 @@ "content" : { "application/json" : { "schema" : { - "$ref" : "#/components/schemas/Person" - } + "$ref" : "#/components/schemas/Person", + "exampleSetFlag" : false + }, + "exampleSetFlag" : false } } } @@ -1276,7 +1497,9 @@ "in" : "path", "required" : true, "schema" : { - "type" : "string" + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] } } ], "responses" : { @@ -1286,10 +1509,14 @@ "application/json" : { "schema" : { "type" : "array", + "exampleSetFlag" : false, "items" : { - "$ref" : "#/components/schemas/Person" - } - } + "$ref" : "#/components/schemas/Person", + "exampleSetFlag" : false + }, + "types" : [ "array" ] + }, + "exampleSetFlag" : false } } } @@ -1306,7 +1533,9 @@ "in" : "path", "required" : true, "schema" : { - "type" : "string" + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] } } ], "responses" : { @@ -1317,9 +1546,13 @@ "schema" : { "type" : "object", "additionalProperties" : { - "$ref" : "#/components/schemas/Person" - } - } + "$ref" : "#/components/schemas/Person", + "exampleSetFlag" : false + }, + "exampleSetFlag" : false, + "types" : [ "object" ] + }, + "exampleSetFlag" : false } } } @@ -1336,7 +1569,9 @@ "in" : "path", "required" : true, "schema" : { - "type" : "string" + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] } } ], "responses" : { @@ -1346,10 +1581,14 @@ "application/json" : { "schema" : { "type" : "array", + "exampleSetFlag" : false, "items" : { - "$ref" : "#/components/schemas/Person" - } - } + "$ref" : "#/components/schemas/Person", + "exampleSetFlag" : false + }, + "types" : [ "array" ] + }, + "exampleSetFlag" : false } } } @@ -1366,35 +1605,45 @@ "in" : "path", "required" : true, "schema" : { - "type" : "string" + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] } }, { "name" : "category", "in" : "path", "required" : true, "schema" : { - "type" : "string" + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] } }, { "name" : "vendor", "in" : "path", "required" : true, "schema" : { - "type" : "string" + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] } }, { "name" : "range", "in" : "path", "required" : true, "schema" : { - "type" : "string" + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] } }, { "name" : "style", "in" : "path", "required" : true, "schema" : { - "type" : "string" + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] } } ], "responses" : { @@ -1413,39 +1662,59 @@ "id" : { "type" : "integer", "format" : "int64", - "nullable" : false + "nullable" : false, + "exampleSetFlag" : false, + "types" : [ "integer" ] }, "name" : { - "type" : "string" + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] } - } + }, + "exampleSetFlag" : false, + "types" : [ "object" ] }, "Baz" : { "type" : "object", "properties" : { "id" : { "type" : "integer", - "format" : "int64" + "format" : "int64", + "exampleSetFlag" : false, + "types" : [ "integer" ] }, "name" : { - "type" : "string" + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] }, "startDate" : { "type" : "string", - "format" : "date" + "format" : "date", + "exampleSetFlag" : false, + "types" : [ "string" ] } - } + }, + "exampleSetFlag" : false, + "types" : [ "object" ] }, "ErrorResponse" : { "type" : "object", "properties" : { "id" : { - "type" : "string" + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] }, "text" : { - "type" : "string" + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] } - } + }, + "exampleSetFlag" : false, + "types" : [ "object" ] }, "GetBeanForm" : { "type" : "object", @@ -1454,14 +1723,20 @@ "maxLength" : 150, "minLength" : 2, "type" : "string", - "nullable" : false + "nullable" : false, + "exampleSetFlag" : false, + "types" : [ "string" ] }, "email" : { "maxLength" : 100, "type" : "string", - "format" : "email" + "format" : "email", + "exampleSetFlag" : false, + "types" : [ "string" ] } - } + }, + "exampleSetFlag" : false, + "types" : [ "object" ] }, "HelloDto" : { "type" : "object", @@ -1469,25 +1744,37 @@ "id" : { "type" : "integer", "format" : "int32", - "nullable" : false + "nullable" : false, + "exampleSetFlag" : false, + "types" : [ "integer" ] }, "name" : { "type" : "string", - "description" : "This is a comment" + "description" : "This is a comment", + "exampleSetFlag" : false, + "types" : [ "string" ] }, "otherParam" : { "type" : "string", - "description" : "This is a comment" + "description" : "This is a comment", + "exampleSetFlag" : false, + "types" : [ "string" ] }, "gid" : { "type" : "string", - "format" : "uuid" + "format" : "uuid", + "exampleSetFlag" : false, + "types" : [ "string" ] }, "whenAction" : { "type" : "string", - "format" : "date-time" + "format" : "date-time", + "exampleSetFlag" : false, + "types" : [ "string" ] } - } + }, + "exampleSetFlag" : false, + "types" : [ "object" ] }, "HelloForm" : { "type" : "object", @@ -1496,35 +1783,53 @@ "maxLength" : 150, "minLength" : 2, "type" : "string", - "nullable" : false + "nullable" : false, + "exampleSetFlag" : false, + "types" : [ "string" ] }, "email" : { "maxLength" : 100, "type" : "string", - "format" : "email" + "format" : "email", + "exampleSetFlag" : false, + "types" : [ "string" ] }, "url" : { - "type" : "string" + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] }, "startDate" : { "type" : "string", - "format" : "date" + "format" : "date", + "exampleSetFlag" : false, + "types" : [ "string" ] } - } + }, + "exampleSetFlag" : false, + "types" : [ "object" ] }, "MyForm" : { "type" : "object", "properties" : { "name" : { - "type" : "string" + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] }, "email" : { - "type" : "string" + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] }, "url" : { - "type" : "string" + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] } - } + }, + "exampleSetFlag" : false, + "types" : [ "object" ] }, "Person" : { "type" : "object", @@ -1532,15 +1837,23 @@ "id" : { "type" : "integer", "format" : "int64", - "nullable" : false + "nullable" : false, + "exampleSetFlag" : false, + "types" : [ "integer" ] }, "name" : { - "type" : "string" + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] } - } + }, + "exampleSetFlag" : false, + "types" : [ "object" ] }, "byte" : { - "type" : "object" + "type" : "object", + "exampleSetFlag" : false, + "types" : [ "object" ] } }, "securitySchemes" : { diff --git a/tests/test-javalin-jsonb/src/test/resources/expectedInheritedOpenApi.json b/tests/test-javalin-jsonb/src/test/resources/expectedInheritedOpenApi.json index 95cec1ab1..28a17d806 100644 --- a/tests/test-javalin-jsonb/src/test/resources/expectedInheritedOpenApi.json +++ b/tests/test-javalin-jsonb/src/test/resources/expectedInheritedOpenApi.json @@ -20,8 +20,10 @@ "content" : { "text/plain" : { "schema" : { - "$ref" : "#/components/schemas/ErrorResponse" - } + "$ref" : "#/components/schemas/ErrorResponse", + "exampleSetFlag" : false + }, + "exampleSetFlag" : false } } }, @@ -33,8 +35,11 @@ "content" : { "text/plain" : { "schema" : { - "type" : "string" - } + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] + }, + "exampleSetFlag" : false } } } @@ -48,12 +53,18 @@ "type" : "object", "properties" : { "id" : { - "type" : "string" + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] }, "text" : { - "type" : "string" + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] } - } + }, + "exampleSetFlag" : false, + "types" : [ "object" ] } } } diff --git a/tests/test-javalin-jsonb/src/test/resources/expectedOpenApi.json b/tests/test-javalin-jsonb/src/test/resources/expectedOpenApi.json index 51a998431..a4e181151 100644 --- a/tests/test-javalin-jsonb/src/test/resources/expectedOpenApi.json +++ b/tests/test-javalin-jsonb/src/test/resources/expectedOpenApi.json @@ -21,8 +21,11 @@ "content" : { "text/plain" : { "schema" : { - "type" : "string" - } + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] + }, + "exampleSetFlag" : false } } } @@ -39,8 +42,10 @@ "content" : { "application/json" : { "schema" : { - "$ref" : "#/components/schemas/Person" - } + "$ref" : "#/components/schemas/Person", + "exampleSetFlag" : false + }, + "exampleSetFlag" : false } }, "required" : true @@ -51,8 +56,10 @@ "content" : { "application/json" : { "schema" : { - "$ref" : "#/components/schemas/Person" - } + "$ref" : "#/components/schemas/Person", + "exampleSetFlag" : false + }, + "exampleSetFlag" : false } } }, @@ -61,8 +68,10 @@ "content" : { "application/json" : { "schema" : { - "$ref" : "#/components/schemas/Person" - } + "$ref" : "#/components/schemas/Person", + "exampleSetFlag" : false + }, + "exampleSetFlag" : false } } }, @@ -74,8 +83,10 @@ "content" : { "application/json" : { "schema" : { - "$ref" : "#/components/schemas/ErrorResponse" - } + "$ref" : "#/components/schemas/ErrorResponse", + "exampleSetFlag" : false + }, + "exampleSetFlag" : false } } } @@ -93,10 +104,14 @@ "application/json" : { "schema" : { "type" : "array", + "exampleSetFlag" : false, "items" : { - "$ref" : "#/components/schemas/Person" - } - } + "$ref" : "#/components/schemas/Person", + "exampleSetFlag" : false + }, + "types" : [ "array" ] + }, + "exampleSetFlag" : false } }, "required" : true @@ -110,8 +125,10 @@ "content" : { "application/json" : { "schema" : { - "$ref" : "#/components/schemas/ErrorResponse" - } + "$ref" : "#/components/schemas/ErrorResponse", + "exampleSetFlag" : false + }, + "exampleSetFlag" : false } } }, @@ -120,8 +137,10 @@ "content" : { "application/json" : { "schema" : { - "$ref" : "#/components/schemas/Person" - } + "$ref" : "#/components/schemas/Person", + "exampleSetFlag" : false + }, + "exampleSetFlag" : false } } } @@ -140,8 +159,11 @@ "content" : { "text/plain" : { "schema" : { - "type" : "string" - } + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] + }, + "exampleSetFlag" : false } } }, @@ -150,8 +172,11 @@ "content" : { "text/plain" : { "schema" : { - "type" : "string" - } + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] + }, + "exampleSetFlag" : false } } } @@ -165,12 +190,18 @@ "type" : "object", "properties" : { "id" : { - "type" : "string" + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] }, "text" : { - "type" : "string" + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] } - } + }, + "exampleSetFlag" : false, + "types" : [ "object" ] }, "Person" : { "type" : "object", @@ -178,12 +209,18 @@ "id" : { "type" : "integer", "format" : "int64", - "nullable" : false + "nullable" : false, + "exampleSetFlag" : false, + "types" : [ "integer" ] }, "name" : { - "type" : "string" + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] } - } + }, + "exampleSetFlag" : false, + "types" : [ "object" ] } } } diff --git a/tests/test-javalin/src/main/resources/public/openapi.json b/tests/test-javalin/src/main/resources/public/openapi.json index ebea982df..99b56c5ac 100644 --- a/tests/test-javalin/src/main/resources/public/openapi.json +++ b/tests/test-javalin/src/main/resources/public/openapi.json @@ -17,8 +17,11 @@ "content" : { "text/plain" : { "schema" : { - "type" : "string" - } + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] + }, + "exampleSetFlag" : false } } } @@ -35,7 +38,9 @@ "in" : "path", "required" : true, "schema" : { - "type" : "string" + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] } } ], "responses" : { @@ -45,10 +50,14 @@ "application/json" : { "schema" : { "type" : "array", + "exampleSetFlag" : false, "items" : { - "$ref" : "#/components/schemas/Bar" - } - } + "$ref" : "#/components/schemas/Bar", + "exampleSetFlag" : false + }, + "types" : [ "array" ] + }, + "exampleSetFlag" : false } } } @@ -67,7 +76,9 @@ "schema" : { "type" : "integer", "format" : "int64", - "nullable" : false + "nullable" : false, + "exampleSetFlag" : false, + "types" : [ "integer" ] } } ], "responses" : { @@ -76,8 +87,10 @@ "content" : { "application/json" : { "schema" : { - "$ref" : "#/components/schemas/Bar" - } + "$ref" : "#/components/schemas/Bar", + "exampleSetFlag" : false + }, + "exampleSetFlag" : false } } } @@ -96,10 +109,14 @@ "application/json" : { "schema" : { "type" : "array", + "exampleSetFlag" : false, "items" : { - "$ref" : "#/components/schemas/Baz" - } - } + "$ref" : "#/components/schemas/Baz", + "exampleSetFlag" : false + }, + "types" : [ "array" ] + }, + "exampleSetFlag" : false } } } @@ -113,8 +130,10 @@ "content" : { "application/json" : { "schema" : { - "$ref" : "#/components/schemas/Baz" - } + "$ref" : "#/components/schemas/Baz", + "exampleSetFlag" : false + }, + "exampleSetFlag" : false } }, "required" : true @@ -126,8 +145,11 @@ "application/json" : { "schema" : { "type" : "integer", - "format" : "int64" - } + "format" : "int64", + "exampleSetFlag" : false, + "types" : [ "integer" ] + }, + "exampleSetFlag" : false } } } @@ -146,38 +168,50 @@ "schema" : { "type" : "integer", "format" : "int32", - "nullable" : false + "nullable" : false, + "exampleSetFlag" : false, + "types" : [ "integer" ] } }, { "name" : "p1", "in" : "query", "schema" : { - "type" : "string" + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] } }, { "name" : "p2", "in" : "query", "schema" : { - "type" : "number" + "type" : "number", + "exampleSetFlag" : false, + "types" : [ "number" ] } }, { "name" : "p3", "in" : "query", "schema" : { "type" : "integer", - "format" : "int32" + "format" : "int32", + "exampleSetFlag" : false, + "types" : [ "integer" ] } }, { "name" : "p4", "in" : "query", "schema" : { - "type" : "number" + "type" : "number", + "exampleSetFlag" : false, + "types" : [ "number" ] } }, { "name" : "body", "in" : "query", "schema" : { - "type" : "string" + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] } } ], "responses" : { @@ -186,8 +220,11 @@ "content" : { "application/json" : { "schema" : { - "type" : "string" - } + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] + }, + "exampleSetFlag" : false } } } @@ -204,7 +241,9 @@ "in" : "path", "required" : true, "schema" : { - "type" : "string" + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] } } ], "responses" : { @@ -214,10 +253,14 @@ "application/json" : { "schema" : { "type" : "array", + "exampleSetFlag" : false, "items" : { - "$ref" : "#/components/schemas/Baz" - } - } + "$ref" : "#/components/schemas/Baz", + "exampleSetFlag" : false + }, + "types" : [ "array" ] + }, + "exampleSetFlag" : false } } } @@ -235,7 +278,9 @@ "required" : true, "schema" : { "type" : "integer", - "format" : "int64" + "format" : "int64", + "exampleSetFlag" : false, + "types" : [ "integer" ] } } ], "responses" : { @@ -244,8 +289,10 @@ "content" : { "application/json" : { "schema" : { - "$ref" : "#/components/schemas/Baz" - } + "$ref" : "#/components/schemas/Baz", + "exampleSetFlag" : false + }, + "exampleSetFlag" : false } } } @@ -261,8 +308,10 @@ "content" : { "application/json" : { "schema" : { - "$ref" : "#/components/schemas/HelloDto" - } + "$ref" : "#/components/schemas/HelloDto", + "exampleSetFlag" : false + }, + "exampleSetFlag" : false } }, "required" : true @@ -273,8 +322,10 @@ "content" : { "application/json" : { "schema" : { - "$ref" : "#/components/schemas/HelloDto" - } + "$ref" : "#/components/schemas/HelloDto", + "exampleSetFlag" : false + }, + "exampleSetFlag" : false } } } @@ -293,10 +344,14 @@ "application/json" : { "schema" : { "type" : "array", + "exampleSetFlag" : false, "items" : { - "$ref" : "#/components/schemas/HelloDto" - } - } + "$ref" : "#/components/schemas/HelloDto", + "exampleSetFlag" : false + }, + "types" : [ "array" ] + }, + "exampleSetFlag" : false } } } @@ -314,13 +369,17 @@ "description" : "The name to search for", "required" : true, "schema" : { - "type" : "string" + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] } }, { "name" : "myParam", "in" : "query", "schema" : { - "type" : "string" + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] } } ], "responses" : { @@ -330,10 +389,14 @@ "application/json" : { "schema" : { "type" : "array", + "exampleSetFlag" : false, "items" : { - "$ref" : "#/components/schemas/HelloDto" - } - } + "$ref" : "#/components/schemas/HelloDto", + "exampleSetFlag" : false + }, + "types" : [ "array" ] + }, + "exampleSetFlag" : false } } } @@ -351,8 +414,11 @@ "content" : { "text/plain" : { "schema" : { - "type" : "string" - } + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] + }, + "exampleSetFlag" : false } } } @@ -371,16 +437,24 @@ "type" : "object", "properties" : { "name" : { - "type" : "string" + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] }, "email" : { - "type" : "string" + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] }, "url" : { - "type" : "string" + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] } - } - } + }, + "exampleSetFlag" : false + }, + "exampleSetFlag" : false } }, "required" : true @@ -403,7 +477,9 @@ "description" : "The hello doo id", "required" : true, "schema" : { - "type" : "string" + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] } } ], "requestBody" : { @@ -411,8 +487,10 @@ "content" : { "application/json" : { "schema" : { - "$ref" : "#/components/schemas/HelloDto" - } + "$ref" : "#/components/schemas/HelloDto", + "exampleSetFlag" : false + }, + "exampleSetFlag" : false } }, "required" : true @@ -433,8 +511,10 @@ "content" : { "application/x-www-form-urlencoded" : { "schema" : { - "$ref" : "#/components/schemas/HelloForm" - } + "$ref" : "#/components/schemas/HelloForm", + "exampleSetFlag" : false + }, + "exampleSetFlag" : false } }, "required" : true @@ -458,16 +538,24 @@ "type" : "object", "properties" : { "name" : { - "type" : "string" + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] }, "email" : { - "type" : "string" + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] }, "url" : { - "type" : "string" + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] } - } - } + }, + "exampleSetFlag" : false + }, + "exampleSetFlag" : false } }, "required" : true @@ -488,8 +576,10 @@ "content" : { "application/x-www-form-urlencoded" : { "schema" : { - "$ref" : "#/components/schemas/HelloForm" - } + "$ref" : "#/components/schemas/HelloForm", + "exampleSetFlag" : false + }, + "exampleSetFlag" : false } }, "required" : true @@ -500,8 +590,10 @@ "content" : { "application/json" : { "schema" : { - "$ref" : "#/components/schemas/HelloDto" - } + "$ref" : "#/components/schemas/HelloDto", + "exampleSetFlag" : false + }, + "exampleSetFlag" : false } } } @@ -518,21 +610,27 @@ "in" : "path", "required" : true, "schema" : { - "type" : "string" + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] } }, { "name" : "nam0", "in" : "path", "required" : true, "schema" : { - "type" : "string" + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] } }, { "name" : "nam1", "in" : "path", "required" : true, "schema" : { - "type" : "string" + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] } } ], "responses" : { @@ -541,8 +639,11 @@ "content" : { "text/plain" : { "schema" : { - "type" : "string" - } + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] + }, + "exampleSetFlag" : false } } } @@ -561,34 +662,44 @@ "schema" : { "type" : "integer", "format" : "int32", - "nullable" : false + "nullable" : false, + "exampleSetFlag" : false, + "types" : [ "integer" ] } }, { "name" : "author", "in" : "path", "required" : true, "schema" : { - "type" : "string" + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] } }, { "name" : "country", "in" : "path", "required" : true, "schema" : { - "type" : "string" + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] } }, { "name" : "other", "in" : "path", "required" : true, "schema" : { - "type" : "string" + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] } }, { "name" : "extra", "in" : "query", "schema" : { - "type" : "string" + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] } } ], "responses" : { @@ -597,8 +708,11 @@ "content" : { "text/plain" : { "schema" : { - "type" : "string" - } + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] + }, + "exampleSetFlag" : false } } } @@ -614,7 +728,8 @@ "name" : "bean", "in" : "bean", "schema" : { - "$ref" : "#/components/schemas/GetBeanForm" + "$ref" : "#/components/schemas/GetBeanForm", + "exampleSetFlag" : false } } ], "responses" : { @@ -623,8 +738,11 @@ "content" : { "text/plain" : { "schema" : { - "type" : "string" - } + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] + }, + "exampleSetFlag" : false } } } @@ -643,7 +761,9 @@ "schema" : { "type" : "integer", "format" : "int32", - "nullable" : false + "nullable" : false, + "exampleSetFlag" : false, + "types" : [ "integer" ] } } ], "responses" : { @@ -666,7 +786,9 @@ "schema" : { "type" : "integer", "format" : "int32", - "nullable" : false + "nullable" : false, + "exampleSetFlag" : false, + "types" : [ "integer" ] } }, { "name" : "date", @@ -675,14 +797,18 @@ "required" : true, "schema" : { "type" : "string", - "format" : "date" + "format" : "date", + "exampleSetFlag" : false, + "types" : [ "string" ] } }, { "name" : "otherParam", "in" : "query", "description" : "Optional other parameter", "schema" : { - "type" : "string" + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] } } ], "responses" : { @@ -691,8 +817,10 @@ "content" : { "application/json" : { "schema" : { - "$ref" : "#/components/schemas/HelloDto" - } + "$ref" : "#/components/schemas/HelloDto", + "exampleSetFlag" : false + }, + "exampleSetFlag" : false } } } @@ -711,8 +839,11 @@ "content" : { "text/plain" : { "schema" : { - "type" : "string" - } + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] + }, + "exampleSetFlag" : false } } } @@ -728,28 +859,42 @@ "id" : { "type" : "integer", "format" : "int64", - "nullable" : false + "nullable" : false, + "exampleSetFlag" : false, + "types" : [ "integer" ] }, "name" : { - "type" : "string" + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] } - } + }, + "exampleSetFlag" : false, + "types" : [ "object" ] }, "Baz" : { "type" : "object", "properties" : { "id" : { "type" : "integer", - "format" : "int64" + "format" : "int64", + "exampleSetFlag" : false, + "types" : [ "integer" ] }, "name" : { - "type" : "string" + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] }, "startDate" : { "type" : "string", - "format" : "date" + "format" : "date", + "exampleSetFlag" : false, + "types" : [ "string" ] } - } + }, + "exampleSetFlag" : false, + "types" : [ "object" ] }, "GetBeanForm" : { "type" : "object", @@ -758,14 +903,20 @@ "maxLength" : 150, "minLength" : 2, "type" : "string", - "nullable" : false + "nullable" : false, + "exampleSetFlag" : false, + "types" : [ "string" ] }, "email" : { "maxLength" : 100, "type" : "string", - "format" : "email" + "format" : "email", + "exampleSetFlag" : false, + "types" : [ "string" ] } - } + }, + "exampleSetFlag" : false, + "types" : [ "object" ] }, "HelloDto" : { "type" : "object", @@ -773,23 +924,35 @@ "id" : { "type" : "integer", "format" : "int32", - "nullable" : false + "nullable" : false, + "exampleSetFlag" : false, + "types" : [ "integer" ] }, "name" : { - "type" : "string" + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] }, "otherParam" : { - "type" : "string" + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] }, "gid" : { "type" : "string", - "format" : "uuid" + "format" : "uuid", + "exampleSetFlag" : false, + "types" : [ "string" ] }, "whenAction" : { "type" : "string", - "format" : "date-time" + "format" : "date-time", + "exampleSetFlag" : false, + "types" : [ "string" ] } - } + }, + "exampleSetFlag" : false, + "types" : [ "object" ] }, "HelloForm" : { "type" : "object", @@ -798,21 +961,31 @@ "maxLength" : 150, "minLength" : 2, "type" : "string", - "nullable" : false + "nullable" : false, + "exampleSetFlag" : false, + "types" : [ "string" ] }, "email" : { "maxLength" : 100, "type" : "string", - "format" : "email" + "format" : "email", + "exampleSetFlag" : false, + "types" : [ "string" ] }, "url" : { - "type" : "string" + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] }, "startDate" : { "type" : "string", - "format" : "date" + "format" : "date", + "exampleSetFlag" : false, + "types" : [ "string" ] } - } + }, + "exampleSetFlag" : false, + "types" : [ "object" ] } } } diff --git a/tests/test-jex/src/main/resources/public/openapi.json b/tests/test-jex/src/main/resources/public/openapi.json index aa864f845..282b25911 100644 --- a/tests/test-jex/src/main/resources/public/openapi.json +++ b/tests/test-jex/src/main/resources/public/openapi.json @@ -16,8 +16,10 @@ "content" : { "application/json" : { "schema" : { - "$ref" : "#/components/schemas/HelloDto" - } + "$ref" : "#/components/schemas/HelloDto", + "exampleSetFlag" : false + }, + "exampleSetFlag" : false } } } @@ -31,8 +33,10 @@ "content" : { "application/json" : { "schema" : { - "$ref" : "#/components/schemas/HelloDto" - } + "$ref" : "#/components/schemas/HelloDto", + "exampleSetFlag" : false + }, + "exampleSetFlag" : false } }, "required" : true @@ -54,7 +58,9 @@ "in" : "path", "required" : true, "schema" : { - "type" : "string" + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] } } ], "responses" : { @@ -63,8 +69,11 @@ "content" : { "text/plain" : { "schema" : { - "type" : "string" - } + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] + }, + "exampleSetFlag" : false } } } @@ -82,8 +91,11 @@ "content" : { "text/plain" : { "schema" : { - "type" : "string" - } + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] + }, + "exampleSetFlag" : false } } } @@ -100,7 +112,9 @@ "in" : "path", "required" : true, "schema" : { - "type" : "string" + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] } } ], "responses" : { @@ -109,8 +123,11 @@ "content" : { "text/plain" : { "schema" : { - "type" : "string" - } + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] + }, + "exampleSetFlag" : false } } } @@ -127,21 +144,27 @@ "in" : "path", "required" : true, "schema" : { - "type" : "string" + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] } }, { "name" : "nam0", "in" : "path", "required" : true, "schema" : { - "type" : "string" + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] } }, { "name" : "nam1", "in" : "path", "required" : true, "schema" : { - "type" : "string" + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] } } ], "responses" : { @@ -150,8 +173,11 @@ "content" : { "text/plain" : { "schema" : { - "type" : "string" - } + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] + }, + "exampleSetFlag" : false } } } @@ -168,13 +194,17 @@ "in" : "path", "required" : true, "schema" : { - "type" : "string" + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] } }, { "name" : "limit", "in" : "query", "schema" : { - "type" : "string" + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] } } ], "responses" : { @@ -183,8 +213,11 @@ "content" : { "text/plain" : { "schema" : { - "type" : "string" - } + "type" : "string", + "exampleSetFlag" : false, + "types" : [ "string" ] + }, + "exampleSetFlag" : false } } } @@ -200,13 +233,19 @@ "id" : { "type" : "integer", "format" : "int32", - "nullable" : false + "nullable" : false, + "exampleSetFlag" : false, + "types" : [ "integer" ] }, "name" : { "type" : "string", - "nullable" : false + "nullable" : false, + "exampleSetFlag" : false, + "types" : [ "string" ] } - } + }, + "exampleSetFlag" : false, + "types" : [ "object" ] } } } From 4aa8598e36347c4cca3aab71c9b936aa12581177 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Mon, 20 Feb 2023 13:11:24 -0500 Subject: [PATCH 0613/1323] fix serialization --- http-generator-core/pom.xml | 5 - .../generator/core/openapi/DocContext.java | 48 +- .../core/openapi/OpenAPISerializer.java | 16 +- .../src/main/java/module-info.java | 3 - .../src/main/resources/public/openapi.json | 3579 ++++++++--------- .../resources/expectedInheritedOpenApi.json | 134 +- .../src/test/resources/expectedOpenApi.json | 426 +- .../src/main/resources/public/openapi.json | 1892 +++++---- .../src/main/resources/public/openapi.json | 487 ++- 9 files changed, 3149 insertions(+), 3441 deletions(-) diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 866970b38..818e5e39b 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -38,11 +38,6 @@ swagger-models ${swagger.version} - - com.fasterxml.jackson.core - jackson-databind - ${jackson.version} - jakarta.validation diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/DocContext.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/DocContext.java index d73416a6b..acbc8f5d9 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/DocContext.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/DocContext.java @@ -1,30 +1,11 @@ package io.avaje.http.generator.core.openapi; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.core.util.DefaultPrettyPrinter; -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.SerializationFeature; -import io.avaje.http.generator.core.OpenAPIDefinitionPrism; -import io.avaje.http.generator.core.SecuritySchemePrism; -import io.avaje.http.generator.core.SecuritySchemesPrism; -import io.avaje.http.generator.core.TagPrism; -import io.avaje.http.generator.core.TagsPrism; -import io.swagger.v3.oas.models.Components; -import io.swagger.v3.oas.models.OpenAPI; -import io.swagger.v3.oas.models.Operation; -import io.swagger.v3.oas.models.PathItem; -import io.swagger.v3.oas.models.Paths; -import io.swagger.v3.oas.models.info.Info; -import io.swagger.v3.oas.models.media.Content; -import io.swagger.v3.oas.models.media.Schema; -import io.swagger.v3.oas.models.security.SecurityScheme; -import io.swagger.v3.oas.models.tags.Tag; import java.io.IOException; import java.io.Writer; import java.util.List; import java.util.Map; import java.util.TreeMap; + import javax.annotation.processing.Filer; import javax.annotation.processing.Messager; import javax.annotation.processing.ProcessingEnvironment; @@ -36,6 +17,22 @@ import javax.tools.FileObject; import javax.tools.StandardLocation; +import io.avaje.http.generator.core.OpenAPIDefinitionPrism; +import io.avaje.http.generator.core.SecuritySchemePrism; +import io.avaje.http.generator.core.SecuritySchemesPrism; +import io.avaje.http.generator.core.TagPrism; +import io.avaje.http.generator.core.TagsPrism; +import io.swagger.v3.oas.models.Components; +import io.swagger.v3.oas.models.OpenAPI; +import io.swagger.v3.oas.models.Operation; +import io.swagger.v3.oas.models.PathItem; +import io.swagger.v3.oas.models.Paths; +import io.swagger.v3.oas.models.info.Info; +import io.swagger.v3.oas.models.media.Content; +import io.swagger.v3.oas.models.media.Schema; +import io.swagger.v3.oas.models.security.SecurityScheme; +import io.swagger.v3.oas.models.tags.Tag; + /** Context for building the OpenAPI documentation. */ public class DocContext { @@ -210,15 +207,10 @@ public void readApiDefinition(Element element) { } public void writeApi() { - final var openAPI = getApiForWriting(); try (var metaWriter = createMetaWriter()) { - var mapper = new ObjectMapper(); - mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); - mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false); - mapper.configure(SerializationFeature.WRITE_ENUMS_USING_TO_STRING, true); - mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); - mapper.writer(new DefaultPrettyPrinter()).writeValue(metaWriter, openAPI); + final var json = OpenAPISerializer.serialize(getApiForWriting()); + JsonFormatter.prettyPrintJson(metaWriter, json); + } catch (final Exception e) { logError(null, "Error writing openapi file" + e.getMessage()); e.printStackTrace(); diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/OpenAPISerializer.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/OpenAPISerializer.java index 0f69ada46..681e08336 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/OpenAPISerializer.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/OpenAPISerializer.java @@ -58,14 +58,20 @@ static String serialize(Object obj) throws IllegalAccessException { } else { sb.append("{"); - if (obj instanceof String) { - System.out.println(); - } final var fields = getAllFields(cls); var firstField = true; for (final Field field : fields) { + + // skip JsonIgnored fields + if ("BIND_TYPE_AND_TYPES".equals(field.getName()) + || "exampleSetFlag".equals(field.getName()) + || "types".equals(field.getName()) + || "specVersion".equals(field.getName())) { + continue; + } + field.setAccessible(true); final var value = field.get(obj); if (value != null) { @@ -168,6 +174,10 @@ static void write(StringBuilder sb, Object value) throws IllegalAccessException sb.append(value.toString().replace("\"", "\\\"")); sb.append("\""); } + } else if (value.getClass().isEnum()) { + sb.append("\""); + sb.append(value.toString().replace("\"", "\\\"")); + sb.append("\""); } else { // Recursively handle other object types sb.append(serialize(value)); diff --git a/http-generator-core/src/main/java/module-info.java b/http-generator-core/src/main/java/module-info.java index 61c8ca012..9e895411f 100644 --- a/http-generator-core/src/main/java/module-info.java +++ b/http-generator-core/src/main/java/module-info.java @@ -6,9 +6,6 @@ requires java.sql; requires java.compiler; - requires com.fasterxml.jackson.annotation; - requires com.fasterxml.jackson.core; - requires com.fasterxml.jackson.databind; // SHADED: All content after this line will be removed at package time requires static io.avaje.prism; diff --git a/tests/test-javalin-jsonb/src/main/resources/public/openapi.json b/tests/test-javalin-jsonb/src/main/resources/public/openapi.json index 9e5bc2505..ea671217d 100644 --- a/tests/test-javalin-jsonb/src/main/resources/public/openapi.json +++ b/tests/test-javalin-jsonb/src/main/resources/public/openapi.json @@ -1,1868 +1,1715 @@ { - "openapi" : "3.0.1", - "info" : { - "title" : "Example service", - "description" : "Example Javalin controllers with Java and Maven", - "version" : "" - }, - "tags" : [ { - "name" : "tag1", - "description" : "it's somethin" - }, { - "name" : "tag1", - "description" : "this is added to openapi tags" - } ], - "paths" : { - "/bars" : { - "get" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "responses" : { - "200" : { - "description" : "", - "content" : { - "text/plain" : { - "schema" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - }, - "exampleSetFlag" : false - } - } - } - } - } - }, - "/bars/find/{code}" : { - "get" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "parameters" : [ { - "name" : "code", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - } - } ], - "responses" : { - "200" : { - "description" : "", - "content" : { - "application/json" : { - "schema" : { - "type" : "array", - "exampleSetFlag" : false, - "items" : { - "$ref" : "#/components/schemas/Bar", - "exampleSetFlag" : false - }, - "types" : [ "array" ] - }, - "exampleSetFlag" : false - } - } - } - } - } - }, - "/bars/{id}" : { - "get" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "parameters" : [ { - "name" : "id", - "in" : "path", - "required" : true, - "schema" : { - "type" : "integer", - "format" : "int64", - "nullable" : false, - "exampleSetFlag" : false, - "types" : [ "integer" ] - } - } ], - "responses" : { - "200" : { - "description" : "", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/Bar", - "exampleSetFlag" : false - }, - "exampleSetFlag" : false - } - } - } - } - } - }, - "/baz" : { - "get" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "responses" : { - "200" : { - "description" : "", - "content" : { - "application/json" : { - "schema" : { - "type" : "array", - "exampleSetFlag" : false, - "items" : { - "$ref" : "#/components/schemas/Baz", - "exampleSetFlag" : false - }, - "types" : [ "array" ] - }, - "exampleSetFlag" : false - } - } - } - } - }, - "post" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "requestBody" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/Baz", - "exampleSetFlag" : false - }, - "exampleSetFlag" : false - } - }, - "required" : true - }, - "responses" : { - "201" : { - "description" : "", - "content" : { - "application/json" : { - "schema" : { - "type" : "integer", - "format" : "int64", - "exampleSetFlag" : false, - "types" : [ "integer" ] - }, - "exampleSetFlag" : false - } - } - } - } - } - }, - "/baz/checkparams/{id}" : { - "get" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "parameters" : [ { - "name" : "id", - "in" : "path", - "required" : true, - "schema" : { - "type" : "integer", - "format" : "int32", - "nullable" : false, - "exampleSetFlag" : false, - "types" : [ "integer" ] - } - }, { - "name" : "p1", - "in" : "query", - "schema" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - } - }, { - "name" : "p2", - "in" : "query", - "schema" : { - "type" : "number", - "exampleSetFlag" : false, - "types" : [ "number" ] - } - }, { - "name" : "p3", - "in" : "query", - "schema" : { - "type" : "integer", - "format" : "int32", - "exampleSetFlag" : false, - "types" : [ "integer" ] - } - }, { - "name" : "p4", - "in" : "query", - "schema" : { - "type" : "number", - "exampleSetFlag" : false, - "types" : [ "number" ] - } - }, { - "name" : "body", - "in" : "query", - "schema" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - } - } ], - "responses" : { - "200" : { - "description" : "", - "content" : { - "application/json" : { - "schema" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - }, - "exampleSetFlag" : false - } - } - } - } - } - }, - "/baz/findbyname/{name}" : { - "get" : { - "tags" : [ ], - "summary" : "Find the baz by name", - "description" : "This is some more comments about this method.", - "parameters" : [ { - "name" : "name", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - } - } ], - "responses" : { - "200" : { - "description" : "The list of baz", - "content" : { - "application/json" : { - "schema" : { - "type" : "array", - "exampleSetFlag" : false, - "items" : { - "$ref" : "#/components/schemas/Baz", - "exampleSetFlag" : false - }, - "types" : [ "array" ] - }, - "exampleSetFlag" : false - } - } - } - } - } - }, - "/baz/{id}" : { - "get" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "parameters" : [ { - "name" : "id", - "in" : "path", - "required" : true, - "schema" : { - "type" : "integer", - "format" : "int64", - "exampleSetFlag" : false, - "types" : [ "integer" ] - } - } ], - "responses" : { - "200" : { - "description" : "", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/Baz", - "exampleSetFlag" : false - }, - "exampleSetFlag" : false - } - } - } - } - } - }, - "/hello" : { - "post" : { - "tags" : [ ], - "summary" : "Simple example post with JSON body response", - "description" : "", - "requestBody" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/HelloDto", - "exampleSetFlag" : false - }, - "exampleSetFlag" : false - } - }, - "required" : true - }, - "responses" : { - "201" : { - "description" : "", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/HelloDto", - "exampleSetFlag" : false - }, - "exampleSetFlag" : false - } - } - } - } - } - }, - "/hello/async" : { - "get" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "responses" : { - "200" : { - "description" : "", - "content" : { - "application/json" : { - "schema" : { - "type" : "array", - "exampleSetFlag" : false, - "items" : { - "$ref" : "#/components/schemas/HelloDto", - "exampleSetFlag" : false - }, - "types" : [ "array" ] - }, - "exampleSetFlag" : false - } - } - } - } - } - }, - "/hello/findbyname/{name}" : { - "get" : { - "tags" : [ ], - "summary" : "Find Hellos by name", - "description" : "", - "parameters" : [ { - "name" : "name", - "in" : "path", - "description" : "The name to search for", - "required" : true, - "schema" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - } - }, { - "name" : "myParam", - "in" : "query", - "schema" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - } - } ], - "responses" : { - "200" : { - "description" : "The Hellos that we found.", - "content" : { - "application/json" : { - "schema" : { - "type" : "array", - "exampleSetFlag" : false, - "items" : { - "$ref" : "#/components/schemas/HelloDto", - "exampleSetFlag" : false - }, - "types" : [ "array" ] - }, - "exampleSetFlag" : false - } - } - } - } - } - }, - "/hello/message" : { - "get" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "responses" : { - "200" : { - "description" : "", - "content" : { - "text/plain" : { - "schema" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - }, - "exampleSetFlag" : false - } - } - } - } - } - }, - "/hello/mySave" : { - "post" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "requestBody" : { - "content" : { - "application/x-www-form-urlencoded" : { - "schema" : { - "type" : "object", - "properties" : { - "name" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - }, - "email" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - }, - "url" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - } - }, - "exampleSetFlag" : false - }, - "exampleSetFlag" : false - } - }, - "required" : true - }, - "responses" : { - "201" : { - "description" : "No content" - } - } - } - }, - "/hello/savebean/{foo}" : { - "post" : { - "tags" : [ ], - "summary" : "Save the hello using json body", - "description" : "", - "parameters" : [ { - "name" : "foo", - "in" : "path", - "description" : "The hello doo id", - "required" : true, - "schema" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - } - } ], - "requestBody" : { - "description" : "The hello body as json", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/HelloDto", - "exampleSetFlag" : false - }, - "exampleSetFlag" : false - } - }, - "required" : true - }, - "responses" : { - "201" : { - "description" : "No content" - } - } - } - }, - "/hello/saveform" : { - "post" : { - "tags" : [ ], - "summary" : "Create the new Hello using a form", - "description" : "", - "requestBody" : { - "content" : { - "application/x-www-form-urlencoded" : { - "schema" : { - "$ref" : "#/components/schemas/HelloForm", - "exampleSetFlag" : false - }, - "exampleSetFlag" : false - } - }, - "required" : true - }, - "responses" : { - "201" : { - "description" : "No content" - } - } - } - }, - "/hello/saveform2" : { - "post" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "requestBody" : { - "content" : { - "application/x-www-form-urlencoded" : { - "schema" : { - "type" : "object", - "properties" : { - "name" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - }, - "email" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - }, - "url" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - } - }, - "exampleSetFlag" : false - }, - "exampleSetFlag" : false - } - }, - "required" : true - }, - "responses" : { - "201" : { - "description" : "No content" - } - } - } - }, - "/hello/saveform3" : { - "post" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "requestBody" : { - "content" : { - "application/x-www-form-urlencoded" : { - "schema" : { - "$ref" : "#/components/schemas/HelloForm", - "exampleSetFlag" : false - }, - "exampleSetFlag" : false - } - }, - "required" : true - }, - "responses" : { - "201" : { - "description" : "", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/HelloDto", - "exampleSetFlag" : false - }, - "exampleSetFlag" : false - } - } - } - } - } - }, - "/hello/slash/{name}//other/" : { - "get" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "parameters" : [ { - "name" : "name", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - } - }, { - "name" : "nam0", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - } - }, { - "name" : "nam1", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - } - } ], - "responses" : { - "200" : { - "description" : "", - "content" : { - "text/plain" : { - "schema" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - }, - "exampleSetFlag" : false - } - } - } - } - } - }, - "/hello/withMatrix/{year_segment}/{other}" : { - "get" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "parameters" : [ { - "name" : "year", - "in" : "path", - "required" : true, - "schema" : { - "type" : "integer", - "format" : "int32", - "nullable" : false, - "exampleSetFlag" : false, - "types" : [ "integer" ] - } - }, { - "name" : "author", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - } - }, { - "name" : "country", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - } - }, { - "name" : "other", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - } - }, { - "name" : "extra", - "in" : "query", - "schema" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - } - } ], - "responses" : { - "200" : { - "description" : "", - "content" : { - "text/plain" : { - "schema" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - }, - "exampleSetFlag" : false - } - } - } - } - } - }, - "/hello/withValidBean" : { - "get" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "parameters" : [ { - "name" : "bean", - "in" : "bean", - "schema" : { - "$ref" : "#/components/schemas/GetBeanForm", - "exampleSetFlag" : false - } - } ], - "responses" : { - "200" : { - "description" : "", - "content" : { - "text/plain" : { - "schema" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - }, - "exampleSetFlag" : false - } - } - } - } - } - }, - "/hello/{id}" : { - "delete" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "parameters" : [ { - "name" : "id", - "in" : "path", - "required" : true, - "schema" : { - "type" : "integer", - "format" : "int32", - "nullable" : false, - "exampleSetFlag" : false, - "types" : [ "integer" ] - } - } ], - "responses" : { - "204" : { - "description" : "No content" - } - } - } - }, - "/hello/{id}/{date}" : { - "get" : { - "tags" : [ ], - "summary" : "Return the Hello DTO", - "description" : "", - "parameters" : [ { - "name" : "id", - "in" : "path", - "description" : "The hello Id.", - "required" : true, - "schema" : { - "type" : "integer", - "format" : "int32", - "nullable" : false, - "exampleSetFlag" : false, - "types" : [ "integer" ] - } - }, { - "name" : "date", - "in" : "path", - "description" : "The name of the hello", - "required" : true, - "schema" : { - "type" : "string", - "format" : "date", - "exampleSetFlag" : false, - "types" : [ "string" ] - } - }, { - "name" : "otherParam", - "in" : "query", - "description" : "Optional other parameter", - "schema" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - } - } ], - "responses" : { - "200" : { - "description" : "The Hello DTO given the id and name.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/HelloDto", - "exampleSetFlag" : false - }, - "exampleSetFlag" : false - } - } - } - }, - "deprecated" : true - } - }, - "/javalin/health" : { - "get" : { - "tags" : [ "tag1" ], - "summary" : "Standard Get", - "description" : "", - "responses" : { - "500" : { - "description" : "a health check", - "content" : { - "text/plain" : { - "schema" : { - "$ref" : "#/components/schemas/ErrorResponse", - "exampleSetFlag" : false - }, - "exampleSetFlag" : false - } - } - }, - "403" : { - "description" : "Not Authorized" - }, - "200" : { - "description" : "a health check", - "content" : { - "text/plain" : { - "schema" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - }, - "exampleSetFlag" : false - } - } - } - } - } - }, - "/openapi/get" : { - "get" : { - "tags" : [ ], - "summary" : "Example of Open API Get (up to the first period is the summary)", - "description" : "When using Javalin Context only This Javadoc description is added to the generated openapi.json", - "responses" : { - "200" : { - "description" : "funny phrase (this part of the javadoc is added to the response desc)", - "content" : { - "text/plain" : { - "schema" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - }, - "exampleSetFlag" : false - } - } - } - } - } - }, - "/openapi/post" : { - "post" : { - "tags" : [ "tag1" ], - "summary" : "Standard Post", - "description" : "uses tag annotation to add tags to openapi json", - "requestBody" : { - "description" : "the body (this is used for generated request body desc)", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/Person", - "exampleSetFlag" : false - }, - "exampleSetFlag" : false - } - }, - "required" : true - }, - "responses" : { - "200" : { - "description" : "overrides @return javadoc description", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/Person", - "exampleSetFlag" : false - }, - "exampleSetFlag" : false - } - } - }, - "201" : { - "description" : "the response body (from javadoc)", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/Person", - "exampleSetFlag" : false - }, - "exampleSetFlag" : false - } - } - }, - "400" : { - "description" : "User not found (Will not have an associated response schema)" - }, - "500" : { - "description" : "Some other Error (Will have this error class as the response class)", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ErrorResponse", - "exampleSetFlag" : false - }, - "exampleSetFlag" : false - } - } - } - } - } - }, - "/openapi/post1" : { - "post" : { - "tags" : [ ], - "summary" : "Standard Post", - "description" : "The Deprecated annotation adds \"deprecacted:true\" to the generated json", - "requestBody" : { - "description" : "the body", - "content" : { - "application/json" : { - "schema" : { - "type" : "array", - "exampleSetFlag" : false, - "items" : { - "$ref" : "#/components/schemas/Person", - "exampleSetFlag" : false - }, - "types" : [ "array" ] - }, - "exampleSetFlag" : false - } - }, - "required" : true - }, - "responses" : { - "400" : { - "description" : "User not found" - }, - "500" : { - "description" : "Some other Error", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ErrorResponse", - "exampleSetFlag" : false - }, - "exampleSetFlag" : false - } - } - }, - "201" : { - "description" : "the response body (from javadoc)", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/Person", - "exampleSetFlag" : false - }, - "exampleSetFlag" : false - } - } - } - }, - "deprecated" : true - } - }, - "/openapi/put" : { - "put" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "responses" : { - "204" : { - "description" : "", - "content" : { - "text/plain" : { - "schema" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - }, - "exampleSetFlag" : false - } - } - }, - "203" : { - "description" : "", - "content" : { - "text/plain" : { - "schema" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - }, - "exampleSetFlag" : false - } - } - } - } - } - }, - "/req-scoped" : { - "get" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "responses" : { - "200" : { - "description" : "", - "content" : { - "text/plain" : { - "schema" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - }, - "exampleSetFlag" : false - } - } - } - } - } - }, - "/security/first" : { - "get" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "responses" : { - "200" : { - "description" : "", - "content" : { - "application/json" : { - "schema" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - }, - "exampleSetFlag" : false - } - } - } - }, - "security" : [ { - "JWT" : [ ] - } ] - } - }, - "/security/second" : { - "get" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "responses" : { - "200" : { - "description" : "", - "content" : { - "application/json" : { - "schema" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - }, - "exampleSetFlag" : false - } - } - } - }, - "security" : [ { - "JWT" : [ ] - } ] - } - }, - "/test" : { - "get" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "responses" : { - "200" : { - "description" : "", - "content" : { - "text/plain" : { - "schema" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - }, - "exampleSetFlag" : false - } - } - } - } - } - }, - "/test/async" : { - "get" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "responses" : { - "200" : { - "description" : "", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/HelloDto", - "exampleSetFlag" : false - }, - "exampleSetFlag" : false - } - } - } - } - } - }, - "/test/byte" : { - "get" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "responses" : { - "200" : { - "description" : "", - "content" : { - "image/png" : { - "schema" : { - "type" : "array", - "exampleSetFlag" : false, - "items" : { - "$ref" : "#/components/schemas/byte", - "exampleSetFlag" : false - }, - "types" : [ "array" ] - }, - "exampleSetFlag" : false - } - } - } - } - } - }, - "/test/ctx" : { - "get" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "responses" : { - "200" : { - "description" : "No content" - } - } - } - }, - "/test/form" : { - "post" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "requestBody" : { - "content" : { - "application/x-www-form-urlencoded" : { - "schema" : { - "type" : "object", - "properties" : { - "name" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - }, - "email" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - }, - "url" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - } - }, - "exampleSetFlag" : false - }, - "exampleSetFlag" : false - } - }, - "required" : true - }, - "responses" : { - "201" : { - "description" : "", - "content" : { - "application/json" : { - "schema" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - }, - "exampleSetFlag" : false - } - } - } - } - } - }, - "/test/formBean" : { - "post" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "requestBody" : { - "content" : { - "application/x-www-form-urlencoded" : { - "schema" : { - "$ref" : "#/components/schemas/MyForm", - "exampleSetFlag" : false - }, - "exampleSetFlag" : false - } - }, - "required" : true - }, - "responses" : { - "201" : { - "description" : "", - "content" : { - "application/json" : { - "schema" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - }, - "exampleSetFlag" : false - } - } - } - } - } - }, - "/test/header" : { - "get" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "parameters" : [ { - "name" : "head", - "in" : "header", - "schema" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - } - } ], - "responses" : { - "200" : { - "description" : "", - "content" : { - "application/json" : { - "schema" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - }, - "exampleSetFlag" : false - } - } - } - } - } - }, - "/test/hey" : { - "get" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "responses" : { - "200" : { - "description" : "", - "content" : { - "text/plain" : { - "schema" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - }, - "exampleSetFlag" : false - } - } - } - } - } - }, - "/test/int" : { - "put" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "responses" : { - "200" : { - "description" : "", - "content" : { - "application/json" : { - "schema" : { - "type" : "integer", - "format" : "int32", - "nullable" : false, - "exampleSetFlag" : false, - "types" : [ "integer" ] - }, - "exampleSetFlag" : false - } - } - } - } - } - }, - "/test/long" : { - "put" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "responses" : { - "200" : { - "description" : "", - "content" : { - "application/json" : { - "schema" : { - "type" : "integer", - "format" : "int64", - "nullable" : false, - "exampleSetFlag" : false, - "types" : [ "integer" ] - }, - "exampleSetFlag" : false - } - } - } - } - } - }, - "/test/person" : { - "post" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "requestBody" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/Person", - "exampleSetFlag" : false - }, - "exampleSetFlag" : false - } - }, - "required" : true - }, - "responses" : { - "201" : { - "description" : "", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/Person", - "exampleSetFlag" : false - }, - "exampleSetFlag" : false - } - } - } - } - } - }, - "/test/person/update" : { - "put" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "requestBody" : { - "content" : { - "application/json" : { - "schema" : { - "type" : "array", - "exampleSetFlag" : false, - "items" : { - "$ref" : "#/components/schemas/Person", - "exampleSetFlag" : false - }, - "types" : [ "array" ] - }, - "exampleSetFlag" : false - } - }, - "required" : true - }, - "responses" : { - "200" : { - "description" : "", - "content" : { - "application/json" : { - "schema" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - }, - "exampleSetFlag" : false - } - } - } - } - } - }, - "/test/person/{name}" : { - "get" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "parameters" : [ { - "name" : "name", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - } - } ], - "responses" : { - "200" : { - "description" : "", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/Person", - "exampleSetFlag" : false - }, - "exampleSetFlag" : false - } - } - } - } - } - }, - "/test/person/{sortBy}/list" : { - "get" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "parameters" : [ { - "name" : "sortBy", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - } - } ], - "responses" : { - "200" : { - "description" : "", - "content" : { - "application/json" : { - "schema" : { - "type" : "array", - "exampleSetFlag" : false, - "items" : { - "$ref" : "#/components/schemas/Person", - "exampleSetFlag" : false - }, - "types" : [ "array" ] - }, - "exampleSetFlag" : false - } - } - } - } - } - }, - "/test/person/{sortBy}/map" : { - "get" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "parameters" : [ { - "name" : "sortBy", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - } - } ], - "responses" : { - "200" : { - "description" : "", - "content" : { - "application/json" : { - "schema" : { - "type" : "object", - "additionalProperties" : { - "$ref" : "#/components/schemas/Person", - "exampleSetFlag" : false - }, - "exampleSetFlag" : false, - "types" : [ "object" ] - }, - "exampleSetFlag" : false - } - } - } - } - } - }, - "/test/person/{sortBy}/set" : { - "get" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "parameters" : [ { - "name" : "sortBy", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - } - } ], - "responses" : { - "200" : { - "description" : "", - "content" : { - "application/json" : { - "schema" : { - "type" : "array", - "exampleSetFlag" : false, - "items" : { - "$ref" : "#/components/schemas/Person", - "exampleSetFlag" : false - }, - "types" : [ "array" ] - }, - "exampleSetFlag" : false - } - } - } - } - } - }, - "/test/withMatrixParam/{type-1_segment}/{range_segment}" : { - "get" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "parameters" : [ { - "name" : "type", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - } - }, { - "name" : "category", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - } - }, { - "name" : "vendor", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - } - }, { - "name" : "range", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - } - }, { - "name" : "style", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - } - } ], - "responses" : { - "200" : { - "description" : "No content" - } - } - } - } - }, - "components" : { - "schemas" : { - "Bar" : { - "type" : "object", - "properties" : { - "id" : { - "type" : "integer", - "format" : "int64", - "nullable" : false, - "exampleSetFlag" : false, - "types" : [ "integer" ] - }, - "name" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - } - }, - "exampleSetFlag" : false, - "types" : [ "object" ] - }, - "Baz" : { - "type" : "object", - "properties" : { - "id" : { - "type" : "integer", - "format" : "int64", - "exampleSetFlag" : false, - "types" : [ "integer" ] - }, - "name" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - }, - "startDate" : { - "type" : "string", - "format" : "date", - "exampleSetFlag" : false, - "types" : [ "string" ] - } - }, - "exampleSetFlag" : false, - "types" : [ "object" ] - }, - "ErrorResponse" : { - "type" : "object", - "properties" : { - "id" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - }, - "text" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - } - }, - "exampleSetFlag" : false, - "types" : [ "object" ] - }, - "GetBeanForm" : { - "type" : "object", - "properties" : { - "name" : { - "maxLength" : 150, - "minLength" : 2, - "type" : "string", - "nullable" : false, - "exampleSetFlag" : false, - "types" : [ "string" ] - }, - "email" : { - "maxLength" : 100, - "type" : "string", - "format" : "email", - "exampleSetFlag" : false, - "types" : [ "string" ] - } - }, - "exampleSetFlag" : false, - "types" : [ "object" ] - }, - "HelloDto" : { - "type" : "object", - "properties" : { - "id" : { - "type" : "integer", - "format" : "int32", - "nullable" : false, - "exampleSetFlag" : false, - "types" : [ "integer" ] - }, - "name" : { - "type" : "string", - "description" : "This is a comment", - "exampleSetFlag" : false, - "types" : [ "string" ] - }, - "otherParam" : { - "type" : "string", - "description" : "This is a comment", - "exampleSetFlag" : false, - "types" : [ "string" ] - }, - "gid" : { - "type" : "string", - "format" : "uuid", - "exampleSetFlag" : false, - "types" : [ "string" ] - }, - "whenAction" : { - "type" : "string", - "format" : "date-time", - "exampleSetFlag" : false, - "types" : [ "string" ] - } - }, - "exampleSetFlag" : false, - "types" : [ "object" ] - }, - "HelloForm" : { - "type" : "object", - "properties" : { - "name" : { - "maxLength" : 150, - "minLength" : 2, - "type" : "string", - "nullable" : false, - "exampleSetFlag" : false, - "types" : [ "string" ] - }, - "email" : { - "maxLength" : 100, - "type" : "string", - "format" : "email", - "exampleSetFlag" : false, - "types" : [ "string" ] - }, - "url" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - }, - "startDate" : { - "type" : "string", - "format" : "date", - "exampleSetFlag" : false, - "types" : [ "string" ] - } - }, - "exampleSetFlag" : false, - "types" : [ "object" ] - }, - "MyForm" : { - "type" : "object", - "properties" : { - "name" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - }, - "email" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - }, - "url" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - } - }, - "exampleSetFlag" : false, - "types" : [ "object" ] - }, - "Person" : { - "type" : "object", - "properties" : { - "id" : { - "type" : "integer", - "format" : "int64", - "nullable" : false, - "exampleSetFlag" : false, - "types" : [ "integer" ] - }, - "name" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - } - }, - "exampleSetFlag" : false, - "types" : [ "object" ] - }, - "byte" : { - "type" : "object", - "exampleSetFlag" : false, - "types" : [ "object" ] - } - }, - "securitySchemes" : { - "JWT" : { - "type" : "apiKey", - "description" : "JSON Web Tokens are an open, industry standard RFC 7519 method for representing claims securely between two parties.", - "name" : "access_token", - "in" : "query" - } - } - } + "openapi" : "3.0.1", + "info" : { + "title" : "Example service", + "description" : "Example Javalin controllers with Java and Maven", + "version" : "" + }, + "tags" : [ + { + "name" : "tag1", + "description" : "it's somethin" + }, + { + "name" : "tag1", + "description" : "this is added to openapi tags" + } + ], + "paths" : { + "/bars" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/bars/find/{code}" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "parameters" : [ + { + "name" : "code", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "array", + "items" : { + "$ref" : "#/components/schemas/Bar" + } + } + } + } + } + } + } + }, + "/bars/{id}" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "parameters" : [ + { + "name" : "id", + "in" : "path", + "required" : true, + "schema" : { + "type" : "integer", + "format" : "int64", + "nullable" : false + } + } + ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Bar" + } + } + } + } + } + } + }, + "/baz" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "array", + "items" : { + "$ref" : "#/components/schemas/Baz" + } + } + } + } + } + } + }, + "post" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Baz" + } + } + }, + "required" : true + }, + "responses" : { + "201" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "integer", + "format" : "int64" + } + } + } + } + } + } + }, + "/baz/checkparams/{id}" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "parameters" : [ + { + "name" : "id", + "in" : "path", + "required" : true, + "schema" : { + "type" : "integer", + "format" : "int32", + "nullable" : false + } + }, + { + "name" : "p1", + "in" : "query", + "schema" : { + "type" : "string" + } + }, + { + "name" : "p2", + "in" : "query", + "schema" : { + "type" : "number" + } + }, + { + "name" : "p3", + "in" : "query", + "schema" : { + "type" : "integer", + "format" : "int32" + } + }, + { + "name" : "p4", + "in" : "query", + "schema" : { + "type" : "number" + } + }, + { + "name" : "body", + "in" : "query", + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/baz/findbyname/{name}" : { + "get" : { + "tags" : [ + + ], + "summary" : "Find the baz by name", + "description" : "This is some more comments about this method.", + "parameters" : [ + { + "name" : "name", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "description" : "The list of baz", + "content" : { + "application/json" : { + "schema" : { + "type" : "array", + "items" : { + "$ref" : "#/components/schemas/Baz" + } + } + } + } + } + } + } + }, + "/baz/{id}" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "parameters" : [ + { + "name" : "id", + "in" : "path", + "required" : true, + "schema" : { + "type" : "integer", + "format" : "int64" + } + } + ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Baz" + } + } + } + } + } + } + }, + "/hello" : { + "post" : { + "tags" : [ + + ], + "summary" : "Simple example post with JSON body response", + "description" : "", + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/HelloDto" + } + } + }, + "required" : true + }, + "responses" : { + "201" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/HelloDto" + } + } + } + } + } + } + }, + "/hello/async" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "array", + "items" : { + "$ref" : "#/components/schemas/HelloDto" + } + } + } + } + } + } + } + }, + "/hello/findbyname/{name}" : { + "get" : { + "tags" : [ + + ], + "summary" : "Find Hellos by name", + "description" : "", + "parameters" : [ + { + "name" : "name", + "in" : "path", + "description" : "The name to search for", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "name" : "myParam", + "in" : "query", + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "description" : "The Hellos that we found.", + "content" : { + "application/json" : { + "schema" : { + "type" : "array", + "items" : { + "$ref" : "#/components/schemas/HelloDto" + } + } + } + } + } + } + } + }, + "/hello/message" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/hello/mySave" : { + "post" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "requestBody" : { + "content" : { + "application/x-www-form-urlencoded" : { + "schema" : { + "type" : "object", + "properties" : { + "name" : { + "type" : "string" + }, + "email" : { + "type" : "string" + }, + "url" : { + "type" : "string" + } + } + } + } + }, + "required" : true + }, + "responses" : { + "201" : { + "description" : "No content" + } + } + } + }, + "/hello/savebean/{foo}" : { + "post" : { + "tags" : [ + + ], + "summary" : "Save the hello using json body", + "description" : "", + "parameters" : [ + { + "name" : "foo", + "in" : "path", + "description" : "The hello doo id", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "requestBody" : { + "description" : "The hello body as json", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/HelloDto" + } + } + }, + "required" : true + }, + "responses" : { + "201" : { + "description" : "No content" + } + } + } + }, + "/hello/saveform" : { + "post" : { + "tags" : [ + + ], + "summary" : "Create the new Hello using a form", + "description" : "", + "requestBody" : { + "content" : { + "application/x-www-form-urlencoded" : { + "schema" : { + "$ref" : "#/components/schemas/HelloForm" + } + } + }, + "required" : true + }, + "responses" : { + "201" : { + "description" : "No content" + } + } + } + }, + "/hello/saveform2" : { + "post" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "requestBody" : { + "content" : { + "application/x-www-form-urlencoded" : { + "schema" : { + "type" : "object", + "properties" : { + "name" : { + "type" : "string" + }, + "email" : { + "type" : "string" + }, + "url" : { + "type" : "string" + } + } + } + } + }, + "required" : true + }, + "responses" : { + "201" : { + "description" : "No content" + } + } + } + }, + "/hello/saveform3" : { + "post" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "requestBody" : { + "content" : { + "application/x-www-form-urlencoded" : { + "schema" : { + "$ref" : "#/components/schemas/HelloForm" + } + } + }, + "required" : true + }, + "responses" : { + "201" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/HelloDto" + } + } + } + } + } + } + }, + "/hello/slash/{name}//other/" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "parameters" : [ + { + "name" : "name", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "name" : "nam0", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "name" : "nam1", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/hello/withMatrix/{year_segment}/{other}" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "parameters" : [ + { + "name" : "year", + "in" : "path", + "required" : true, + "schema" : { + "type" : "integer", + "format" : "int32", + "nullable" : false + } + }, + { + "name" : "author", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "name" : "country", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "name" : "other", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "name" : "extra", + "in" : "query", + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/hello/withValidBean" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "parameters" : [ + { + "name" : "bean", + "in" : "bean", + "schema" : { + "$ref" : "#/components/schemas/GetBeanForm" + } + } + ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/hello/{id}" : { + "delete" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "parameters" : [ + { + "name" : "id", + "in" : "path", + "required" : true, + "schema" : { + "type" : "integer", + "format" : "int32", + "nullable" : false + } + } + ], + "responses" : { + "204" : { + "description" : "No content" + } + } + } + }, + "/hello/{id}/{date}" : { + "get" : { + "tags" : [ + + ], + "summary" : "Return the Hello DTO", + "description" : "", + "parameters" : [ + { + "name" : "id", + "in" : "path", + "description" : "The hello Id.", + "required" : true, + "schema" : { + "type" : "integer", + "format" : "int32", + "nullable" : false + } + }, + { + "name" : "date", + "in" : "path", + "description" : "The name of the hello", + "required" : true, + "schema" : { + "type" : "string", + "format" : "date" + } + }, + { + "name" : "otherParam", + "in" : "query", + "description" : "Optional other parameter", + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "description" : "The Hello DTO given the id and name.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/HelloDto" + } + } + } + } + }, + "deprecated" : true + } + }, + "/javalin/health" : { + "get" : { + "tags" : [ + "tag1" + ], + "summary" : "Standard Get", + "description" : "", + "responses" : { + "500" : { + "description" : "a health check", + "content" : { + "text/plain" : { + "schema" : { + "$ref" : "#/components/schemas/ErrorResponse" + } + } + } + }, + "403" : { + "description" : "Not Authorized" + }, + "200" : { + "description" : "a health check", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/openapi/get" : { + "get" : { + "tags" : [ + + ], + "summary" : "Example of Open API Get (up to the first period is the summary)", + "description" : "When using Javalin Context only This Javadoc description is added to the generated openapi.json", + "responses" : { + "200" : { + "description" : "funny phrase (this part of the javadoc is added to the response desc)", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/openapi/post" : { + "post" : { + "tags" : [ + "tag1" + ], + "summary" : "Standard Post", + "description" : "uses tag annotation to add tags to openapi json", + "requestBody" : { + "description" : "the body (this is used for generated request body desc)", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Person" + } + } + }, + "required" : true + }, + "responses" : { + "200" : { + "description" : "overrides @return javadoc description", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Person" + } + } + } + }, + "201" : { + "description" : "the response body (from javadoc)", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Person" + } + } + } + }, + "400" : { + "description" : "User not found (Will not have an associated response schema)" + }, + "500" : { + "description" : "Some other Error (Will have this error class as the response class)", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ErrorResponse" + } + } + } + } + } + } + }, + "/openapi/post1" : { + "post" : { + "tags" : [ + + ], + "summary" : "Standard Post", + "description" : "The Deprecated annotation adds \"deprecacted:true\" to the generated json", + "requestBody" : { + "description" : "the body", + "content" : { + "application/json" : { + "schema" : { + "type" : "array", + "items" : { + "$ref" : "#/components/schemas/Person" + } + } + } + }, + "required" : true + }, + "responses" : { + "400" : { + "description" : "User not found" + }, + "500" : { + "description" : "Some other Error", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ErrorResponse" + } + } + } + }, + "201" : { + "description" : "the response body (from javadoc)", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Person" + } + } + } + } + }, + "deprecated" : true + } + }, + "/openapi/put" : { + "put" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "responses" : { + "204" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + }, + "203" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/req-scoped" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/security/first" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "string" + } + } + } + } + }, + "security" : [ + { + "JWT" : [ + + ] + } + ] + } + }, + "/security/second" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "string" + } + } + } + } + }, + "security" : [ + { + "JWT" : [ + + ] + } + ] + } + }, + "/test" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/test/async" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/HelloDto" + } + } + } + } + } + } + }, + "/test/byte" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "", + "content" : { + "image/png" : { + "schema" : { + "type" : "array", + "items" : { + "$ref" : "#/components/schemas/byte" + } + } + } + } + } + } + } + }, + "/test/ctx" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "No content" + } + } + } + }, + "/test/form" : { + "post" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "requestBody" : { + "content" : { + "application/x-www-form-urlencoded" : { + "schema" : { + "type" : "object", + "properties" : { + "name" : { + "type" : "string" + }, + "email" : { + "type" : "string" + }, + "url" : { + "type" : "string" + } + } + } + } + }, + "required" : true + }, + "responses" : { + "201" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/test/formBean" : { + "post" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "requestBody" : { + "content" : { + "application/x-www-form-urlencoded" : { + "schema" : { + "$ref" : "#/components/schemas/MyForm" + } + } + }, + "required" : true + }, + "responses" : { + "201" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/test/header" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "parameters" : [ + { + "name" : "head", + "in" : "header", + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/test/hey" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/test/int" : { + "put" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "integer", + "format" : "int32", + "nullable" : false + } + } + } + } + } + } + }, + "/test/long" : { + "put" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "integer", + "format" : "int64", + "nullable" : false + } + } + } + } + } + } + }, + "/test/person" : { + "post" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Person" + } + } + }, + "required" : true + }, + "responses" : { + "201" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Person" + } + } + } + } + } + } + }, + "/test/person/update" : { + "put" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "type" : "array", + "items" : { + "$ref" : "#/components/schemas/Person" + } + } + } + }, + "required" : true + }, + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/test/person/{name}" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "parameters" : [ + { + "name" : "name", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Person" + } + } + } + } + } + } + }, + "/test/person/{sortBy}/list" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "parameters" : [ + { + "name" : "sortBy", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "array", + "items" : { + "$ref" : "#/components/schemas/Person" + } + } + } + } + } + } + } + }, + "/test/person/{sortBy}/map" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "parameters" : [ + { + "name" : "sortBy", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "object", + "additionalProperties" : { + "$ref" : "#/components/schemas/Person" + } + } + } + } + } + } + } + }, + "/test/person/{sortBy}/set" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "parameters" : [ + { + "name" : "sortBy", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "array", + "items" : { + "$ref" : "#/components/schemas/Person" + } + } + } + } + } + } + } + }, + "/test/withMatrixParam/{type-1_segment}/{range_segment}" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "parameters" : [ + { + "name" : "type", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "name" : "category", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "name" : "vendor", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "name" : "range", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "name" : "style", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "description" : "No content" + } + } + } + } + }, + "components" : { + "COMPONENTS_SCHEMAS_REF" : "#/components/schemas/", + "schemas" : { + "Bar" : { + "type" : "object", + "properties" : { + "id" : { + "type" : "integer", + "format" : "int64", + "nullable" : false + }, + "name" : { + "type" : "string" + } + } + }, + "Baz" : { + "type" : "object", + "properties" : { + "id" : { + "type" : "integer", + "format" : "int64" + }, + "name" : { + "type" : "string" + }, + "startDate" : { + "type" : "string", + "format" : "date" + } + } + }, + "ErrorResponse" : { + "type" : "object", + "properties" : { + "id" : { + "type" : "string" + }, + "text" : { + "type" : "string" + } + } + }, + "GetBeanForm" : { + "type" : "object", + "properties" : { + "name" : { + "maxLength" : 150, + "minLength" : 2, + "type" : "string", + "nullable" : false + }, + "email" : { + "maxLength" : 100, + "type" : "string", + "format" : "email" + } + } + }, + "HelloDto" : { + "type" : "object", + "properties" : { + "id" : { + "type" : "integer", + "format" : "int32", + "nullable" : false + }, + "name" : { + "type" : "string", + "description" : "This is a comment" + }, + "otherParam" : { + "type" : "string", + "description" : "This is a comment" + }, + "gid" : { + "type" : "string", + "format" : "uuid" + }, + "whenAction" : { + "type" : "string", + "format" : "date-time" + } + } + }, + "HelloForm" : { + "type" : "object", + "properties" : { + "name" : { + "maxLength" : 150, + "minLength" : 2, + "type" : "string", + "nullable" : false + }, + "email" : { + "maxLength" : 100, + "type" : "string", + "format" : "email" + }, + "url" : { + "type" : "string" + }, + "startDate" : { + "type" : "string", + "format" : "date" + } + } + }, + "MyForm" : { + "type" : "object", + "properties" : { + "name" : { + "type" : "string" + }, + "email" : { + "type" : "string" + }, + "url" : { + "type" : "string" + } + } + }, + "Person" : { + "type" : "object", + "properties" : { + "id" : { + "type" : "integer", + "format" : "int64", + "nullable" : false + }, + "name" : { + "type" : "string" + } + } + }, + "byte" : { + "type" : "object" + } + }, + "securitySchemes" : { + "JWT" : { + "type" : "apiKey", + "description" : "JSON Web Tokens are an open, industry standard RFC 7519 method for representing claims securely between two parties.", + "name" : "access_token", + "in" : "query" + } + } + } } \ No newline at end of file diff --git a/tests/test-javalin-jsonb/src/test/resources/expectedInheritedOpenApi.json b/tests/test-javalin-jsonb/src/test/resources/expectedInheritedOpenApi.json index 28a17d806..03d3a1731 100644 --- a/tests/test-javalin-jsonb/src/test/resources/expectedInheritedOpenApi.json +++ b/tests/test-javalin-jsonb/src/test/resources/expectedInheritedOpenApi.json @@ -1,71 +1,65 @@ { - "openapi" : "3.0.1", - "info" : { - "title" : "Example service showing off the Path extension method of controller", - "version" : "" - }, - "tags" : [ { - "name" : "tag1", - "description" : "it's somethin" - } ], - "paths" : { - "/javalin/health" : { - "get" : { - "tags" : [ "tag1" ], - "summary" : "Standard Get", - "description" : "", - "responses" : { - "500" : { - "description" : "a health check", - "content" : { - "text/plain" : { - "schema" : { - "$ref" : "#/components/schemas/ErrorResponse", - "exampleSetFlag" : false - }, - "exampleSetFlag" : false - } - } - }, - "403" : { - "description" : "Not Authorized" - }, - "200" : { - "description" : "a health check", - "content" : { - "text/plain" : { - "schema" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - }, - "exampleSetFlag" : false - } - } - } - } - } - } - }, - "components" : { - "schemas" : { - "ErrorResponse" : { - "type" : "object", - "properties" : { - "id" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - }, - "text" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - } - }, - "exampleSetFlag" : false, - "types" : [ "object" ] - } - } - } -} \ No newline at end of file + "openapi" : "3.0.1", + "info" : { + "title" : "Example service showing off the Path extension method of controller", + "version" : "" + }, + "tags" : [ + { + "name" : "tag1", + "description" : "it's somethin" + } + ], + "paths" : { + "/javalin/health" : { + "get" : { + "tags" : [ + "tag1" + ], + "summary" : "Standard Get", + "description" : "", + "responses" : { + "500" : { + "description" : "a health check", + "content" : { + "text/plain" : { + "schema" : { + "$ref" : "#/components/schemas/ErrorResponse" + } + } + } + }, + "403" : { + "description" : "Not Authorized" + }, + "200" : { + "description" : "a health check", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + } + }, + "components" : { + "COMPONENTS_SCHEMAS_REF" : "#/components/schemas/", + "schemas" : { + "ErrorResponse" : { + "type" : "object", + "properties" : { + "id" : { + "type" : "string" + }, + "text" : { + "type" : "string" + } + } + } + } + } +} diff --git a/tests/test-javalin-jsonb/src/test/resources/expectedOpenApi.json b/tests/test-javalin-jsonb/src/test/resources/expectedOpenApi.json index a4e181151..44826c3a4 100644 --- a/tests/test-javalin-jsonb/src/test/resources/expectedOpenApi.json +++ b/tests/test-javalin-jsonb/src/test/resources/expectedOpenApi.json @@ -1,227 +1,201 @@ { - "openapi" : "3.0.1", - "info" : { - "title" : "Example service", - "description" : "Example Javalin controllers with Java and Maven", - "version" : "" - }, - "tags" : [ { - "name" : "tag1", - "description" : "this is added to openapi tags" - } ], - "paths" : { - "/openapi/get" : { - "get" : { - "tags" : [ ], - "summary" : "Example of Open API Get (up to the first period is the summary)", - "description" : "When using Javalin Context only This Javadoc description is added to the generated openapi.json", - "responses" : { - "200" : { - "description" : "funny phrase (this part of the javadoc is added to the response desc)", - "content" : { - "text/plain" : { - "schema" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - }, - "exampleSetFlag" : false - } - } - } - } - } - }, - "/openapi/post" : { - "post" : { - "tags" : [ "tag1" ], - "summary" : "Standard Post", - "description" : "uses tag annotation to add tags to openapi json", - "requestBody" : { - "description" : "the body (this is used for generated request body desc)", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/Person", - "exampleSetFlag" : false - }, - "exampleSetFlag" : false - } - }, - "required" : true - }, - "responses" : { - "200" : { - "description" : "overrides @return javadoc description", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/Person", - "exampleSetFlag" : false - }, - "exampleSetFlag" : false - } - } - }, - "201" : { - "description" : "the response body (from javadoc)", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/Person", - "exampleSetFlag" : false - }, - "exampleSetFlag" : false - } - } - }, - "400" : { - "description" : "User not found (Will not have an associated response schema)" - }, - "500" : { - "description" : "Some other Error (Will have this error class as the response class)", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ErrorResponse", - "exampleSetFlag" : false - }, - "exampleSetFlag" : false - } - } - } - } - } - }, - "/openapi/post1" : { - "post" : { - "tags" : [ ], - "summary" : "Standard Post", - "description" : "The Deprecated annotation adds \"deprecacted:true\" to the generated json", - "requestBody" : { - "description" : "the body", - "content" : { - "application/json" : { - "schema" : { - "type" : "array", - "exampleSetFlag" : false, - "items" : { - "$ref" : "#/components/schemas/Person", - "exampleSetFlag" : false - }, - "types" : [ "array" ] - }, - "exampleSetFlag" : false - } - }, - "required" : true - }, - "responses" : { - "400" : { - "description" : "User not found" - }, - "500" : { - "description" : "Some other Error", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ErrorResponse", - "exampleSetFlag" : false - }, - "exampleSetFlag" : false - } - } - }, - "201" : { - "description" : "the response body (from javadoc)", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/Person", - "exampleSetFlag" : false - }, - "exampleSetFlag" : false - } - } - } - }, - "deprecated" : true - } - }, - "/openapi/put" : { - "put" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "responses" : { - "204" : { - "description" : "", - "content" : { - "text/plain" : { - "schema" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - }, - "exampleSetFlag" : false - } - } - }, - "203" : { - "description" : "", - "content" : { - "text/plain" : { - "schema" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - }, - "exampleSetFlag" : false - } - } - } - } - } - } - }, - "components" : { - "schemas" : { - "ErrorResponse" : { - "type" : "object", - "properties" : { - "id" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - }, - "text" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - } - }, - "exampleSetFlag" : false, - "types" : [ "object" ] - }, - "Person" : { - "type" : "object", - "properties" : { - "id" : { - "type" : "integer", - "format" : "int64", - "nullable" : false, - "exampleSetFlag" : false, - "types" : [ "integer" ] - }, - "name" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - } - }, - "exampleSetFlag" : false, - "types" : [ "object" ] - } - } - } -} \ No newline at end of file + "openapi" : "3.0.1", + "info" : { + "title" : "Example service", + "description" : "Example Javalin controllers with Java and Maven", + "version" : "" + }, + "tags" : [ + { + "name" : "tag1", + "description" : "this is added to openapi tags" + } + ], + "paths" : { + "/openapi/get" : { + "get" : { + "tags" : [ + + ], + "summary" : "Example of Open API Get (up to the first period is the summary)", + "description" : "When using Javalin Context only This Javadoc description is added to the generated openapi.json", + "responses" : { + "200" : { + "description" : "funny phrase (this part of the javadoc is added to the response desc)", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/openapi/post" : { + "post" : { + "tags" : [ + "tag1" + ], + "summary" : "Standard Post", + "description" : "uses tag annotation to add tags to openapi json", + "requestBody" : { + "description" : "the body (this is used for generated request body desc)", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Person" + } + } + }, + "required" : true + }, + "responses" : { + "200" : { + "description" : "overrides @return javadoc description", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Person" + } + } + } + }, + "201" : { + "description" : "the response body (from javadoc)", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Person" + } + } + } + }, + "400" : { + "description" : "User not found (Will not have an associated response schema)" + }, + "500" : { + "description" : "Some other Error (Will have this error class as the response class)", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ErrorResponse" + } + } + } + } + } + } + }, + "/openapi/post1" : { + "post" : { + "tags" : [ + + ], + "summary" : "Standard Post", + "description" : "The Deprecated annotation adds \"deprecacted:true\" to the generated json", + "requestBody" : { + "description" : "the body", + "content" : { + "application/json" : { + "schema" : { + "type" : "array", + "items" : { + "$ref" : "#/components/schemas/Person" + } + } + } + }, + "required" : true + }, + "responses" : { + "400" : { + "description" : "User not found" + }, + "500" : { + "description" : "Some other Error", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ErrorResponse" + } + } + } + }, + "201" : { + "description" : "the response body (from javadoc)", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Person" + } + } + } + } + }, + "deprecated" : true + } + }, + "/openapi/put" : { + "put" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "responses" : { + "204" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + }, + "203" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + } + }, + "components" : { + "COMPONENTS_SCHEMAS_REF" : "#/components/schemas/", + "schemas" : { + "ErrorResponse" : { + "type" : "object", + "properties" : { + "id" : { + "type" : "string" + }, + "text" : { + "type" : "string" + } + } + }, + "Person" : { + "type" : "object", + "properties" : { + "id" : { + "type" : "integer", + "format" : "int64", + "nullable" : false + }, + "name" : { + "type" : "string" + } + } + } + } + } +} diff --git a/tests/test-javalin/src/main/resources/public/openapi.json b/tests/test-javalin/src/main/resources/public/openapi.json index 99b56c5ac..6e66b07fe 100644 --- a/tests/test-javalin/src/main/resources/public/openapi.json +++ b/tests/test-javalin/src/main/resources/public/openapi.json @@ -1,992 +1,904 @@ { - "openapi" : "3.0.1", - "info" : { - "title" : "Example service", - "description" : "Example Javalin controllers with Java and Maven", - "version" : "" - }, - "paths" : { - "/bars" : { - "get" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "responses" : { - "200" : { - "description" : "", - "content" : { - "text/plain" : { - "schema" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - }, - "exampleSetFlag" : false - } - } - } - } - } - }, - "/bars/find/{code}" : { - "get" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "parameters" : [ { - "name" : "code", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - } - } ], - "responses" : { - "200" : { - "description" : "", - "content" : { - "application/json" : { - "schema" : { - "type" : "array", - "exampleSetFlag" : false, - "items" : { - "$ref" : "#/components/schemas/Bar", - "exampleSetFlag" : false - }, - "types" : [ "array" ] - }, - "exampleSetFlag" : false - } - } - } - } - } - }, - "/bars/{id}" : { - "get" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "parameters" : [ { - "name" : "id", - "in" : "path", - "required" : true, - "schema" : { - "type" : "integer", - "format" : "int64", - "nullable" : false, - "exampleSetFlag" : false, - "types" : [ "integer" ] - } - } ], - "responses" : { - "200" : { - "description" : "", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/Bar", - "exampleSetFlag" : false - }, - "exampleSetFlag" : false - } - } - } - } - } - }, - "/baz" : { - "get" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "responses" : { - "200" : { - "description" : "", - "content" : { - "application/json" : { - "schema" : { - "type" : "array", - "exampleSetFlag" : false, - "items" : { - "$ref" : "#/components/schemas/Baz", - "exampleSetFlag" : false - }, - "types" : [ "array" ] - }, - "exampleSetFlag" : false - } - } - } - } - }, - "post" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "requestBody" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/Baz", - "exampleSetFlag" : false - }, - "exampleSetFlag" : false - } - }, - "required" : true - }, - "responses" : { - "201" : { - "description" : "", - "content" : { - "application/json" : { - "schema" : { - "type" : "integer", - "format" : "int64", - "exampleSetFlag" : false, - "types" : [ "integer" ] - }, - "exampleSetFlag" : false - } - } - } - } - } - }, - "/baz/checkparams/{id}" : { - "get" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "parameters" : [ { - "name" : "id", - "in" : "path", - "required" : true, - "schema" : { - "type" : "integer", - "format" : "int32", - "nullable" : false, - "exampleSetFlag" : false, - "types" : [ "integer" ] - } - }, { - "name" : "p1", - "in" : "query", - "schema" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - } - }, { - "name" : "p2", - "in" : "query", - "schema" : { - "type" : "number", - "exampleSetFlag" : false, - "types" : [ "number" ] - } - }, { - "name" : "p3", - "in" : "query", - "schema" : { - "type" : "integer", - "format" : "int32", - "exampleSetFlag" : false, - "types" : [ "integer" ] - } - }, { - "name" : "p4", - "in" : "query", - "schema" : { - "type" : "number", - "exampleSetFlag" : false, - "types" : [ "number" ] - } - }, { - "name" : "body", - "in" : "query", - "schema" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - } - } ], - "responses" : { - "200" : { - "description" : "", - "content" : { - "application/json" : { - "schema" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - }, - "exampleSetFlag" : false - } - } - } - } - } - }, - "/baz/findbyname/{name}" : { - "get" : { - "tags" : [ ], - "summary" : "Find the baz by name", - "description" : "This is some more comments about this method.", - "parameters" : [ { - "name" : "name", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - } - } ], - "responses" : { - "200" : { - "description" : "The list of baz", - "content" : { - "application/json" : { - "schema" : { - "type" : "array", - "exampleSetFlag" : false, - "items" : { - "$ref" : "#/components/schemas/Baz", - "exampleSetFlag" : false - }, - "types" : [ "array" ] - }, - "exampleSetFlag" : false - } - } - } - } - } - }, - "/baz/{id}" : { - "get" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "parameters" : [ { - "name" : "id", - "in" : "path", - "required" : true, - "schema" : { - "type" : "integer", - "format" : "int64", - "exampleSetFlag" : false, - "types" : [ "integer" ] - } - } ], - "responses" : { - "200" : { - "description" : "", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/Baz", - "exampleSetFlag" : false - }, - "exampleSetFlag" : false - } - } - } - } - } - }, - "/hello" : { - "post" : { - "tags" : [ ], - "summary" : "Simple example post with JSON body response", - "description" : "", - "requestBody" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/HelloDto", - "exampleSetFlag" : false - }, - "exampleSetFlag" : false - } - }, - "required" : true - }, - "responses" : { - "201" : { - "description" : "", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/HelloDto", - "exampleSetFlag" : false - }, - "exampleSetFlag" : false - } - } - } - } - } - }, - "/hello/async" : { - "get" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "responses" : { - "200" : { - "description" : "", - "content" : { - "application/json" : { - "schema" : { - "type" : "array", - "exampleSetFlag" : false, - "items" : { - "$ref" : "#/components/schemas/HelloDto", - "exampleSetFlag" : false - }, - "types" : [ "array" ] - }, - "exampleSetFlag" : false - } - } - } - } - } - }, - "/hello/findbyname/{name}" : { - "get" : { - "tags" : [ ], - "summary" : "Find Hellos by name", - "description" : "", - "parameters" : [ { - "name" : "name", - "in" : "path", - "description" : "The name to search for", - "required" : true, - "schema" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - } - }, { - "name" : "myParam", - "in" : "query", - "schema" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - } - } ], - "responses" : { - "200" : { - "description" : "The Hellos that we found.", - "content" : { - "application/json" : { - "schema" : { - "type" : "array", - "exampleSetFlag" : false, - "items" : { - "$ref" : "#/components/schemas/HelloDto", - "exampleSetFlag" : false - }, - "types" : [ "array" ] - }, - "exampleSetFlag" : false - } - } - } - } - } - }, - "/hello/message" : { - "get" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "responses" : { - "200" : { - "description" : "", - "content" : { - "text/plain" : { - "schema" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - }, - "exampleSetFlag" : false - } - } - } - } - } - }, - "/hello/mySave" : { - "post" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "requestBody" : { - "content" : { - "application/x-www-form-urlencoded" : { - "schema" : { - "type" : "object", - "properties" : { - "name" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - }, - "email" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - }, - "url" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - } - }, - "exampleSetFlag" : false - }, - "exampleSetFlag" : false - } - }, - "required" : true - }, - "responses" : { - "201" : { - "description" : "No content" - } - } - } - }, - "/hello/savebean/{foo}" : { - "post" : { - "tags" : [ ], - "summary" : "Save the hello using json body", - "description" : "", - "parameters" : [ { - "name" : "foo", - "in" : "path", - "description" : "The hello doo id", - "required" : true, - "schema" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - } - } ], - "requestBody" : { - "description" : "The hello body as json", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/HelloDto", - "exampleSetFlag" : false - }, - "exampleSetFlag" : false - } - }, - "required" : true - }, - "responses" : { - "201" : { - "description" : "No content" - } - } - } - }, - "/hello/saveform" : { - "post" : { - "tags" : [ ], - "summary" : "Create the new Hello using a form", - "description" : "", - "requestBody" : { - "content" : { - "application/x-www-form-urlencoded" : { - "schema" : { - "$ref" : "#/components/schemas/HelloForm", - "exampleSetFlag" : false - }, - "exampleSetFlag" : false - } - }, - "required" : true - }, - "responses" : { - "201" : { - "description" : "No content" - } - } - } - }, - "/hello/saveform2" : { - "post" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "requestBody" : { - "content" : { - "application/x-www-form-urlencoded" : { - "schema" : { - "type" : "object", - "properties" : { - "name" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - }, - "email" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - }, - "url" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - } - }, - "exampleSetFlag" : false - }, - "exampleSetFlag" : false - } - }, - "required" : true - }, - "responses" : { - "201" : { - "description" : "No content" - } - } - } - }, - "/hello/saveform3" : { - "post" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "requestBody" : { - "content" : { - "application/x-www-form-urlencoded" : { - "schema" : { - "$ref" : "#/components/schemas/HelloForm", - "exampleSetFlag" : false - }, - "exampleSetFlag" : false - } - }, - "required" : true - }, - "responses" : { - "201" : { - "description" : "", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/HelloDto", - "exampleSetFlag" : false - }, - "exampleSetFlag" : false - } - } - } - } - } - }, - "/hello/slash/{name}//other/" : { - "get" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "parameters" : [ { - "name" : "name", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - } - }, { - "name" : "nam0", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - } - }, { - "name" : "nam1", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - } - } ], - "responses" : { - "200" : { - "description" : "", - "content" : { - "text/plain" : { - "schema" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - }, - "exampleSetFlag" : false - } - } - } - } - } - }, - "/hello/withMatrix/{year_segment}/{other}" : { - "get" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "parameters" : [ { - "name" : "year", - "in" : "path", - "required" : true, - "schema" : { - "type" : "integer", - "format" : "int32", - "nullable" : false, - "exampleSetFlag" : false, - "types" : [ "integer" ] - } - }, { - "name" : "author", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - } - }, { - "name" : "country", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - } - }, { - "name" : "other", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - } - }, { - "name" : "extra", - "in" : "query", - "schema" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - } - } ], - "responses" : { - "200" : { - "description" : "", - "content" : { - "text/plain" : { - "schema" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - }, - "exampleSetFlag" : false - } - } - } - } - } - }, - "/hello/withValidBean" : { - "get" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "parameters" : [ { - "name" : "bean", - "in" : "bean", - "schema" : { - "$ref" : "#/components/schemas/GetBeanForm", - "exampleSetFlag" : false - } - } ], - "responses" : { - "200" : { - "description" : "", - "content" : { - "text/plain" : { - "schema" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - }, - "exampleSetFlag" : false - } - } - } - } - } - }, - "/hello/{id}" : { - "delete" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "parameters" : [ { - "name" : "id", - "in" : "path", - "required" : true, - "schema" : { - "type" : "integer", - "format" : "int32", - "nullable" : false, - "exampleSetFlag" : false, - "types" : [ "integer" ] - } - } ], - "responses" : { - "204" : { - "description" : "No content" - } - } - } - }, - "/hello/{id}/{date}" : { - "get" : { - "tags" : [ ], - "summary" : "Return the Hello DTO", - "description" : "", - "parameters" : [ { - "name" : "id", - "in" : "path", - "description" : "The hello Id.", - "required" : true, - "schema" : { - "type" : "integer", - "format" : "int32", - "nullable" : false, - "exampleSetFlag" : false, - "types" : [ "integer" ] - } - }, { - "name" : "date", - "in" : "path", - "description" : "The name of the hello", - "required" : true, - "schema" : { - "type" : "string", - "format" : "date", - "exampleSetFlag" : false, - "types" : [ "string" ] - } - }, { - "name" : "otherParam", - "in" : "query", - "description" : "Optional other parameter", - "schema" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - } - } ], - "responses" : { - "200" : { - "description" : "The Hello DTO given the id and name.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/HelloDto", - "exampleSetFlag" : false - }, - "exampleSetFlag" : false - } - } - } - }, - "deprecated" : true - } - }, - "/req-scoped" : { - "get" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "responses" : { - "200" : { - "description" : "", - "content" : { - "text/plain" : { - "schema" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - }, - "exampleSetFlag" : false - } - } - } - } - } - } - }, - "components" : { - "schemas" : { - "Bar" : { - "type" : "object", - "properties" : { - "id" : { - "type" : "integer", - "format" : "int64", - "nullable" : false, - "exampleSetFlag" : false, - "types" : [ "integer" ] - }, - "name" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - } - }, - "exampleSetFlag" : false, - "types" : [ "object" ] - }, - "Baz" : { - "type" : "object", - "properties" : { - "id" : { - "type" : "integer", - "format" : "int64", - "exampleSetFlag" : false, - "types" : [ "integer" ] - }, - "name" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - }, - "startDate" : { - "type" : "string", - "format" : "date", - "exampleSetFlag" : false, - "types" : [ "string" ] - } - }, - "exampleSetFlag" : false, - "types" : [ "object" ] - }, - "GetBeanForm" : { - "type" : "object", - "properties" : { - "name" : { - "maxLength" : 150, - "minLength" : 2, - "type" : "string", - "nullable" : false, - "exampleSetFlag" : false, - "types" : [ "string" ] - }, - "email" : { - "maxLength" : 100, - "type" : "string", - "format" : "email", - "exampleSetFlag" : false, - "types" : [ "string" ] - } - }, - "exampleSetFlag" : false, - "types" : [ "object" ] - }, - "HelloDto" : { - "type" : "object", - "properties" : { - "id" : { - "type" : "integer", - "format" : "int32", - "nullable" : false, - "exampleSetFlag" : false, - "types" : [ "integer" ] - }, - "name" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - }, - "otherParam" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - }, - "gid" : { - "type" : "string", - "format" : "uuid", - "exampleSetFlag" : false, - "types" : [ "string" ] - }, - "whenAction" : { - "type" : "string", - "format" : "date-time", - "exampleSetFlag" : false, - "types" : [ "string" ] - } - }, - "exampleSetFlag" : false, - "types" : [ "object" ] - }, - "HelloForm" : { - "type" : "object", - "properties" : { - "name" : { - "maxLength" : 150, - "minLength" : 2, - "type" : "string", - "nullable" : false, - "exampleSetFlag" : false, - "types" : [ "string" ] - }, - "email" : { - "maxLength" : 100, - "type" : "string", - "format" : "email", - "exampleSetFlag" : false, - "types" : [ "string" ] - }, - "url" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - }, - "startDate" : { - "type" : "string", - "format" : "date", - "exampleSetFlag" : false, - "types" : [ "string" ] - } - }, - "exampleSetFlag" : false, - "types" : [ "object" ] - } - } - } + "openapi" : "3.0.1", + "info" : { + "title" : "Example service", + "description" : "Example Javalin controllers with Java and Maven", + "version" : "" + }, + "paths" : { + "/bars" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/bars/find/{code}" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "parameters" : [ + { + "name" : "code", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "array", + "items" : { + "$ref" : "#/components/schemas/Bar" + } + } + } + } + } + } + } + }, + "/bars/{id}" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "parameters" : [ + { + "name" : "id", + "in" : "path", + "required" : true, + "schema" : { + "type" : "integer", + "format" : "int64", + "nullable" : false + } + } + ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Bar" + } + } + } + } + } + } + }, + "/baz" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "array", + "items" : { + "$ref" : "#/components/schemas/Baz" + } + } + } + } + } + } + }, + "post" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Baz" + } + } + }, + "required" : true + }, + "responses" : { + "201" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "integer", + "format" : "int64" + } + } + } + } + } + } + }, + "/baz/checkparams/{id}" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "parameters" : [ + { + "name" : "id", + "in" : "path", + "required" : true, + "schema" : { + "type" : "integer", + "format" : "int32", + "nullable" : false + } + }, + { + "name" : "p1", + "in" : "query", + "schema" : { + "type" : "string" + } + }, + { + "name" : "p2", + "in" : "query", + "schema" : { + "type" : "number" + } + }, + { + "name" : "p3", + "in" : "query", + "schema" : { + "type" : "integer", + "format" : "int32" + } + }, + { + "name" : "p4", + "in" : "query", + "schema" : { + "type" : "number" + } + }, + { + "name" : "body", + "in" : "query", + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/baz/findbyname/{name}" : { + "get" : { + "tags" : [ + + ], + "summary" : "Find the baz by name", + "description" : "This is some more comments about this method.", + "parameters" : [ + { + "name" : "name", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "description" : "The list of baz", + "content" : { + "application/json" : { + "schema" : { + "type" : "array", + "items" : { + "$ref" : "#/components/schemas/Baz" + } + } + } + } + } + } + } + }, + "/baz/{id}" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "parameters" : [ + { + "name" : "id", + "in" : "path", + "required" : true, + "schema" : { + "type" : "integer", + "format" : "int64" + } + } + ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Baz" + } + } + } + } + } + } + }, + "/hello" : { + "post" : { + "tags" : [ + + ], + "summary" : "Simple example post with JSON body response", + "description" : "", + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/HelloDto" + } + } + }, + "required" : true + }, + "responses" : { + "201" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/HelloDto" + } + } + } + } + } + } + }, + "/hello/async" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "array", + "items" : { + "$ref" : "#/components/schemas/HelloDto" + } + } + } + } + } + } + } + }, + "/hello/findbyname/{name}" : { + "get" : { + "tags" : [ + + ], + "summary" : "Find Hellos by name", + "description" : "", + "parameters" : [ + { + "name" : "name", + "in" : "path", + "description" : "The name to search for", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "name" : "myParam", + "in" : "query", + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "description" : "The Hellos that we found.", + "content" : { + "application/json" : { + "schema" : { + "type" : "array", + "items" : { + "$ref" : "#/components/schemas/HelloDto" + } + } + } + } + } + } + } + }, + "/hello/message" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/hello/mySave" : { + "post" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "requestBody" : { + "content" : { + "application/x-www-form-urlencoded" : { + "schema" : { + "type" : "object", + "properties" : { + "name" : { + "type" : "string" + }, + "email" : { + "type" : "string" + }, + "url" : { + "type" : "string" + } + } + } + } + }, + "required" : true + }, + "responses" : { + "201" : { + "description" : "No content" + } + } + } + }, + "/hello/savebean/{foo}" : { + "post" : { + "tags" : [ + + ], + "summary" : "Save the hello using json body", + "description" : "", + "parameters" : [ + { + "name" : "foo", + "in" : "path", + "description" : "The hello doo id", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "requestBody" : { + "description" : "The hello body as json", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/HelloDto" + } + } + }, + "required" : true + }, + "responses" : { + "201" : { + "description" : "No content" + } + } + } + }, + "/hello/saveform" : { + "post" : { + "tags" : [ + + ], + "summary" : "Create the new Hello using a form", + "description" : "", + "requestBody" : { + "content" : { + "application/x-www-form-urlencoded" : { + "schema" : { + "$ref" : "#/components/schemas/HelloForm" + } + } + }, + "required" : true + }, + "responses" : { + "201" : { + "description" : "No content" + } + } + } + }, + "/hello/saveform2" : { + "post" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "requestBody" : { + "content" : { + "application/x-www-form-urlencoded" : { + "schema" : { + "type" : "object", + "properties" : { + "name" : { + "type" : "string" + }, + "email" : { + "type" : "string" + }, + "url" : { + "type" : "string" + } + } + } + } + }, + "required" : true + }, + "responses" : { + "201" : { + "description" : "No content" + } + } + } + }, + "/hello/saveform3" : { + "post" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "requestBody" : { + "content" : { + "application/x-www-form-urlencoded" : { + "schema" : { + "$ref" : "#/components/schemas/HelloForm" + } + } + }, + "required" : true + }, + "responses" : { + "201" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/HelloDto" + } + } + } + } + } + } + }, + "/hello/slash/{name}//other/" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "parameters" : [ + { + "name" : "name", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "name" : "nam0", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "name" : "nam1", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/hello/withMatrix/{year_segment}/{other}" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "parameters" : [ + { + "name" : "year", + "in" : "path", + "required" : true, + "schema" : { + "type" : "integer", + "format" : "int32", + "nullable" : false + } + }, + { + "name" : "author", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "name" : "country", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "name" : "other", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "name" : "extra", + "in" : "query", + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/hello/withValidBean" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "parameters" : [ + { + "name" : "bean", + "in" : "bean", + "schema" : { + "$ref" : "#/components/schemas/GetBeanForm" + } + } + ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/hello/{id}" : { + "delete" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "parameters" : [ + { + "name" : "id", + "in" : "path", + "required" : true, + "schema" : { + "type" : "integer", + "format" : "int32", + "nullable" : false + } + } + ], + "responses" : { + "204" : { + "description" : "No content" + } + } + } + }, + "/hello/{id}/{date}" : { + "get" : { + "tags" : [ + + ], + "summary" : "Return the Hello DTO", + "description" : "", + "parameters" : [ + { + "name" : "id", + "in" : "path", + "description" : "The hello Id.", + "required" : true, + "schema" : { + "type" : "integer", + "format" : "int32", + "nullable" : false + } + }, + { + "name" : "date", + "in" : "path", + "description" : "The name of the hello", + "required" : true, + "schema" : { + "type" : "string", + "format" : "date" + } + }, + { + "name" : "otherParam", + "in" : "query", + "description" : "Optional other parameter", + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "description" : "The Hello DTO given the id and name.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/HelloDto" + } + } + } + } + }, + "deprecated" : true + } + }, + "/req-scoped" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + } + }, + "components" : { + "COMPONENTS_SCHEMAS_REF" : "#/components/schemas/", + "schemas" : { + "Bar" : { + "type" : "object", + "properties" : { + "id" : { + "type" : "integer", + "format" : "int64", + "nullable" : false + }, + "name" : { + "type" : "string" + } + } + }, + "Baz" : { + "type" : "object", + "properties" : { + "id" : { + "type" : "integer", + "format" : "int64" + }, + "name" : { + "type" : "string" + }, + "startDate" : { + "type" : "string", + "format" : "date" + } + } + }, + "GetBeanForm" : { + "type" : "object", + "properties" : { + "name" : { + "maxLength" : 150, + "minLength" : 2, + "type" : "string", + "nullable" : false + }, + "email" : { + "maxLength" : 100, + "type" : "string", + "format" : "email" + } + } + }, + "HelloDto" : { + "type" : "object", + "properties" : { + "id" : { + "type" : "integer", + "format" : "int32", + "nullable" : false + }, + "name" : { + "type" : "string" + }, + "otherParam" : { + "type" : "string" + }, + "gid" : { + "type" : "string", + "format" : "uuid" + }, + "whenAction" : { + "type" : "string", + "format" : "date-time" + } + } + }, + "HelloForm" : { + "type" : "object", + "properties" : { + "name" : { + "maxLength" : 150, + "minLength" : 2, + "type" : "string", + "nullable" : false + }, + "email" : { + "maxLength" : 100, + "type" : "string", + "format" : "email" + }, + "url" : { + "type" : "string" + }, + "startDate" : { + "type" : "string", + "format" : "date" + } + } + } + } + } } \ No newline at end of file diff --git a/tests/test-jex/src/main/resources/public/openapi.json b/tests/test-jex/src/main/resources/public/openapi.json index 282b25911..ad0d0f71d 100644 --- a/tests/test-jex/src/main/resources/public/openapi.json +++ b/tests/test-jex/src/main/resources/public/openapi.json @@ -1,252 +1,239 @@ { - "openapi" : "3.0.1", - "info" : { - "title" : "", - "version" : "" - }, - "paths" : { - "/" : { - "get" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "responses" : { - "200" : { - "description" : "", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/HelloDto", - "exampleSetFlag" : false - }, - "exampleSetFlag" : false - } - } - } - } - }, - "put" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "requestBody" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/HelloDto", - "exampleSetFlag" : false - }, - "exampleSetFlag" : false - } - }, - "required" : true - }, - "responses" : { - "204" : { - "description" : "No content" - } - } - } - }, - "/other/{name}" : { - "get" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "parameters" : [ { - "name" : "name", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - } - } ], - "responses" : { - "200" : { - "description" : "", - "content" : { - "text/plain" : { - "schema" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - }, - "exampleSetFlag" : false - } - } - } - } - } - }, - "/plain" : { - "get" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "responses" : { - "200" : { - "description" : "", - "content" : { - "text/plain" : { - "schema" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - }, - "exampleSetFlag" : false - } - } - } - } - } - }, - "/splat/{name}//other/" : { - "get" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "parameters" : [ { - "name" : "name", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - } - } ], - "responses" : { - "200" : { - "description" : "", - "content" : { - "text/plain" : { - "schema" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - }, - "exampleSetFlag" : false - } - } - } - } - } - }, - "/splat2/{name}//other/" : { - "get" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "parameters" : [ { - "name" : "name", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - } - }, { - "name" : "nam0", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - } - }, { - "name" : "nam1", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - } - } ], - "responses" : { - "200" : { - "description" : "", - "content" : { - "text/plain" : { - "schema" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - }, - "exampleSetFlag" : false - } - } - } - } - } - }, - "/withDefault/{name}" : { - "get" : { - "tags" : [ ], - "summary" : "", - "description" : "", - "parameters" : [ { - "name" : "name", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - } - }, { - "name" : "limit", - "in" : "query", - "schema" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - } - } ], - "responses" : { - "200" : { - "description" : "", - "content" : { - "text/plain" : { - "schema" : { - "type" : "string", - "exampleSetFlag" : false, - "types" : [ "string" ] - }, - "exampleSetFlag" : false - } - } - } - } - } - } - }, - "components" : { - "schemas" : { - "HelloDto" : { - "type" : "object", - "properties" : { - "id" : { - "type" : "integer", - "format" : "int32", - "nullable" : false, - "exampleSetFlag" : false, - "types" : [ "integer" ] - }, - "name" : { - "type" : "string", - "nullable" : false, - "exampleSetFlag" : false, - "types" : [ "string" ] - } - }, - "exampleSetFlag" : false, - "types" : [ "object" ] - } - } - } + "openapi" : "3.0.1", + "info" : { + "title" : "", + "version" : "" + }, + "paths" : { + "/" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/HelloDto" + } + } + } + } + } + }, + "put" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/HelloDto" + } + } + }, + "required" : true + }, + "responses" : { + "204" : { + "description" : "No content" + } + } + } + }, + "/other/{name}" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "parameters" : [ + { + "name" : "name", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/plain" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/splat/{name}//other/" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "parameters" : [ + { + "name" : "name", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/splat2/{name}//other/" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "parameters" : [ + { + "name" : "name", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "name" : "nam0", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "name" : "nam1", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/withDefault/{name}" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "parameters" : [ + { + "name" : "name", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "name" : "limit", + "in" : "query", + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + } + }, + "components" : { + "COMPONENTS_SCHEMAS_REF" : "#/components/schemas/", + "schemas" : { + "HelloDto" : { + "type" : "object", + "properties" : { + "id" : { + "type" : "integer", + "format" : "int32", + "nullable" : false + }, + "name" : { + "type" : "string", + "nullable" : false + } + } + } + } + } } \ No newline at end of file From 6a36d98027df2c1697babc33c69ef69ceed12dc4 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Mon, 20 Feb 2023 13:20:05 -0500 Subject: [PATCH 0614/1323] components --- .../io/avaje/http/generator/core/openapi/OpenAPISerializer.java | 1 + tests/test-javalin-jsonb/src/main/resources/public/openapi.json | 1 - .../src/test/resources/expectedInheritedOpenApi.json | 1 - tests/test-javalin-jsonb/src/test/resources/expectedOpenApi.json | 1 - tests/test-javalin/src/main/resources/public/openapi.json | 1 - tests/test-jex/src/main/resources/public/openapi.json | 1 - 6 files changed, 1 insertion(+), 5 deletions(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/OpenAPISerializer.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/OpenAPISerializer.java index 681e08336..e2f751316 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/OpenAPISerializer.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/OpenAPISerializer.java @@ -66,6 +66,7 @@ static String serialize(Object obj) throws IllegalAccessException { // skip JsonIgnored fields if ("BIND_TYPE_AND_TYPES".equals(field.getName()) + || "COMPONENTS_SCHEMAS_REF".equals(field.getName()) || "exampleSetFlag".equals(field.getName()) || "types".equals(field.getName()) || "specVersion".equals(field.getName())) { diff --git a/tests/test-javalin-jsonb/src/main/resources/public/openapi.json b/tests/test-javalin-jsonb/src/main/resources/public/openapi.json index ea671217d..f56485ba9 100644 --- a/tests/test-javalin-jsonb/src/main/resources/public/openapi.json +++ b/tests/test-javalin-jsonb/src/main/resources/public/openapi.json @@ -1565,7 +1565,6 @@ } }, "components" : { - "COMPONENTS_SCHEMAS_REF" : "#/components/schemas/", "schemas" : { "Bar" : { "type" : "object", diff --git a/tests/test-javalin-jsonb/src/test/resources/expectedInheritedOpenApi.json b/tests/test-javalin-jsonb/src/test/resources/expectedInheritedOpenApi.json index 03d3a1731..4b1490dac 100644 --- a/tests/test-javalin-jsonb/src/test/resources/expectedInheritedOpenApi.json +++ b/tests/test-javalin-jsonb/src/test/resources/expectedInheritedOpenApi.json @@ -47,7 +47,6 @@ } }, "components" : { - "COMPONENTS_SCHEMAS_REF" : "#/components/schemas/", "schemas" : { "ErrorResponse" : { "type" : "object", diff --git a/tests/test-javalin-jsonb/src/test/resources/expectedOpenApi.json b/tests/test-javalin-jsonb/src/test/resources/expectedOpenApi.json index 44826c3a4..287695919 100644 --- a/tests/test-javalin-jsonb/src/test/resources/expectedOpenApi.json +++ b/tests/test-javalin-jsonb/src/test/resources/expectedOpenApi.json @@ -170,7 +170,6 @@ } }, "components" : { - "COMPONENTS_SCHEMAS_REF" : "#/components/schemas/", "schemas" : { "ErrorResponse" : { "type" : "object", diff --git a/tests/test-javalin/src/main/resources/public/openapi.json b/tests/test-javalin/src/main/resources/public/openapi.json index 6e66b07fe..d158f7e76 100644 --- a/tests/test-javalin/src/main/resources/public/openapi.json +++ b/tests/test-javalin/src/main/resources/public/openapi.json @@ -805,7 +805,6 @@ } }, "components" : { - "COMPONENTS_SCHEMAS_REF" : "#/components/schemas/", "schemas" : { "Bar" : { "type" : "object", diff --git a/tests/test-jex/src/main/resources/public/openapi.json b/tests/test-jex/src/main/resources/public/openapi.json index ad0d0f71d..fb4378388 100644 --- a/tests/test-jex/src/main/resources/public/openapi.json +++ b/tests/test-jex/src/main/resources/public/openapi.json @@ -218,7 +218,6 @@ } }, "components" : { - "COMPONENTS_SCHEMAS_REF" : "#/components/schemas/", "schemas" : { "HelloDto" : { "type" : "object", From 23947e781214ae3c89226c00ee1dc0ea53eddb30 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Mon, 20 Feb 2023 13:27:04 -0500 Subject: [PATCH 0615/1323] validate security generation --- .../org/example/myapp/web/test/OpenAPIController.java | 4 ++++ .../src/test/resources/expectedOpenApi.json | 8 ++++++++ 2 files changed, 12 insertions(+) diff --git a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/OpenAPIController.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/OpenAPIController.java index 7fdfb03c6..3de0989c0 100644 --- a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/OpenAPIController.java +++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/OpenAPIController.java @@ -13,7 +13,10 @@ import io.avaje.http.api.Put; import io.javalin.http.Context; import io.swagger.v3.oas.annotations.OpenAPIDefinition; +import io.swagger.v3.oas.annotations.enums.SecuritySchemeIn; +import io.swagger.v3.oas.annotations.enums.SecuritySchemeType; import io.swagger.v3.oas.annotations.info.Info; +import io.swagger.v3.oas.annotations.security.SecurityScheme; import io.swagger.v3.oas.annotations.tags.Tag; @OpenAPIDefinition( @@ -23,6 +26,7 @@ description = "Example Javalin controllers with Java and Maven")) @Controller @Path("openapi/") +@SecurityScheme(type = SecuritySchemeType.APIKEY, in = SecuritySchemeIn.QUERY, name = "JWT", paramName = "access_token", description = "JSON Web Tokens are an open, industry standard RFC 7519 method for representing claims securely between two parties.") public class OpenAPIController { /** diff --git a/tests/test-javalin-jsonb/src/test/resources/expectedOpenApi.json b/tests/test-javalin-jsonb/src/test/resources/expectedOpenApi.json index 287695919..74f02b477 100644 --- a/tests/test-javalin-jsonb/src/test/resources/expectedOpenApi.json +++ b/tests/test-javalin-jsonb/src/test/resources/expectedOpenApi.json @@ -195,6 +195,14 @@ } } } + }, + "securitySchemes" : { + "JWT" : { + "type" : "apiKey", + "description" : "JSON Web Tokens are an open, industry standard RFC 7519 method for representing claims securely between two parties.", + "name" : "access_token", + "in" : "query" + } } } } From 281351e5db08dc53236a893e150dfd12f515ca3e Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Mon, 20 Feb 2023 13:28:21 -0500 Subject: [PATCH 0616/1323] Update pom.xml --- http-generator-core/pom.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 818e5e39b..fca84877d 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -32,6 +32,7 @@ io.swagger.core.v3 swagger-annotations ${swagger.version} + provided io.swagger.core.v3 From a9d3999c963d4171bc98e9800eeddb07d3341cc2 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Mon, 20 Feb 2023 14:04:10 -0500 Subject: [PATCH 0617/1323] shade security --- pom.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/pom.xml b/pom.xml index 6ae65d32d..8aec62826 100644 --- a/pom.xml +++ b/pom.xml @@ -104,7 +104,6 @@ io/swagger/v3/oas/models/callbacks/** io/swagger/v3/oas/models/examples/** - io/swagger/v3/oas/models/security/** io/swagger/v3/oas/models/servers/** From 6a182febccf54c29900021aeedf0c8b525317950 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Tue, 21 Feb 2023 12:32:14 -0500 Subject: [PATCH 0618/1323] Update pom.xml --- http-generator-core/pom.xml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index fca84877d..daaf393fd 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -37,7 +37,13 @@ io.swagger.core.v3 swagger-models - ${swagger.version} + ${swagger.version} + + + com.fasterxml.jackson.core + jackson-annotations + + From 6f70a95d47272cb9ca9a4d3c541ba0bba7c1fe5d Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Thu, 23 Feb 2023 00:34:41 -0500 Subject: [PATCH 0619/1323] discord --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index e04187713..7c2e188ba 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,7 @@ [![Build](https://github.com/avaje/avaje-http/actions/workflows/build.yml/badge.svg)](https://github.com/avaje/avaje-http/actions/workflows/build.yml) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://github.com/avaje/avaje-inject/blob/master/LICENSE) +[![Discord](https://img.shields.io/discord/1074074312421683250?color=%237289da&label=discord)](https://discord.gg/Qcqf9R27BR) HTTP server and client libraries via code generation. From c8ec99d5a8785bf01d6783f3404a8588c91a8cf5 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Fri, 24 Feb 2023 00:50:55 -0500 Subject: [PATCH 0620/1323] 1.4 --- http-generator-core/pom.xml | 13 +- .../http/generator/core/ControllerReader.java | 2 +- .../http/generator/core/ElementReader.java | 3 +- .../http/generator/core/JavaxInjectPrism.java | 152 ------------------ .../core/openapi/SchemaDocBuilder.java | 5 +- .../http/generator/core/package-info.java | 1 - .../src/main/java/module-info.java | 1 - .../src/main/resources/public/openapi.json | 6 +- 8 files changed, 9 insertions(+), 174 deletions(-) delete mode 100644 http-generator-core/src/main/java/io/avaje/http/generator/core/JavaxInjectPrism.java diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 2518d278f..c35a22e63 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -21,7 +21,7 @@ io.avaje avaje-prisms - 1.3 + 1.4 true provided @@ -62,15 +62,6 @@ provided - - jakarta.inject - jakarta.inject-api - 2.0.1 - true - provided - - - io.swagger.core.v3 swagger-annotations @@ -92,7 +83,7 @@ io.avaje avaje-prisms - 1.3 + 1.4 diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java index 24c928cac..4f3ed84d5 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java @@ -107,7 +107,7 @@ private List initInterfaces() { final Element ifaceElement = ctx.asElement(anInterface); final var controller = ControllerPrism.getInstanceOn(ifaceElement); if (controller != null && !controller.value().isBlank() - || PathPrism.getInstanceOn(ifaceElement) != null) { + || PathPrism.isPresent(ifaceElement)) { interfaces.add(ifaceElement); } } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java index 17be7aca6..456b0fc8e 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java @@ -62,8 +62,7 @@ private boolean useValidation() { } final var elementType = ctx.typeElement(rawType); return elementType != null - && (ValidPrism.getInstanceOn(elementType) != null - || JavaxValidPrism.getInstanceOn(elementType) != null); + && (ValidPrism.isPresent(elementType) || JavaxValidPrism.isPresent(elementType)); } private void readAnnotations(Element element, ParamType defaultType) { diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/JavaxInjectPrism.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/JavaxInjectPrism.java deleted file mode 100644 index e53d28fa4..000000000 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/JavaxInjectPrism.java +++ /dev/null @@ -1,152 +0,0 @@ -package io.avaje.http.generator.core; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import javax.lang.model.element.AnnotationMirror; -import javax.lang.model.element.AnnotationValue; -import javax.lang.model.element.Element; -import javax.lang.model.element.ExecutableElement; -import javax.lang.model.element.TypeElement; -import javax.lang.model.util.ElementFilter; - -/** - * A Prism representing an {@code @javax.inject.Inject} annotation.
- * Added manually because we can't have both javax and jakarta as dependecies - */ -public class JavaxInjectPrism { - public static final String PRISM_TYPE = "javax.inject.Inject"; - - /** - * An instance of the Values inner class whose methods return the AnnotationValues used to build - * this prism. Primarily intended to support using Messager. - */ - final Values values; - /** - * Return a prism representing the {@code @javax.inject.Inject} annotation on 'e'. similar to - * {@code e.getAnnotation(javax.inject.Inject.class)} except that an instance of this class rather - * than an instance of {@code javax.inject.Inject} is returned. - */ - static JavaxInjectPrism getInstanceOn(Element e) { - final var m = getMirror(PRISM_TYPE, e); - if (m == null) return null; - return getInstance(m); - } - - /** Return a prism of the {@code @javax.inject.Inject} annotation whose mirror is mirror. */ - static JavaxInjectPrism getInstance(AnnotationMirror mirror) { - if (mirror == null || !PRISM_TYPE.equals(mirror.getAnnotationType().toString())) return null; - - return new JavaxInjectPrism(mirror); - } - - private JavaxInjectPrism(AnnotationMirror mirror) { - for (final ExecutableElement key : mirror.getElementValues().keySet()) { - memberValues.put(key.getSimpleName().toString(), mirror.getElementValues().get(key)); - } - for (final ExecutableElement member : - ElementFilter.methodsIn(mirror.getAnnotationType().asElement().getEnclosedElements())) { - defaults.put(member.getSimpleName().toString(), member.getDefaultValue()); - } - this.values = new Values(memberValues); - this.mirror = mirror; - this.isValid = valid; - } - - /** - * Determine whether the underlying AnnotationMirror has no errors. True if the underlying - * AnnotationMirror has no errors. When true is returned, none of the methods will return null. - * When false is returned, a least one member will either return null, or another prism that is - * not valid. - */ - final boolean isValid; - - /** - * The underlying AnnotationMirror of the annotation represented by this Prism. Primarily intended - * to support using Messager. - */ - final AnnotationMirror mirror; - /** - * A class whose members corespond to those of javax.inject.Inject but which each return the - * AnnotationValue corresponding to that member in the model of the annotations. Returns null for - * defaulted members. Used for Messager, so default values are not useful. - */ - static class Values { - private final Map values; - - private Values(Map values) { - this.values = values; - } - } - - private final Map defaults = new HashMap<>(10); - private final Map memberValues = new HashMap<>(10); - private boolean valid = true; - - private T getValue(String name, Class clazz) { - final var result = JavaxInjectPrism.getValue(memberValues, defaults, name, clazz); - if (result == null) valid = false; - return result; - } - - private List getArrayValues(String name, final Class clazz) { - final List result = JavaxInjectPrism.getArrayValues(memberValues, defaults, name, clazz); - if (result == null) valid = false; - return result; - } - - private static AnnotationMirror getMirror(String fqn, Element target) { - for (final AnnotationMirror m : target.getAnnotationMirrors()) { - final CharSequence mfqn = - ((TypeElement) m.getAnnotationType().asElement()).getQualifiedName(); - if (fqn.contentEquals(mfqn)) return m; - } - return null; - } - - private static T getValue( - Map memberValues, - Map defaults, - String name, - Class clazz) { - var av = memberValues.get(name); - if (av == null) av = defaults.get(name); - if (av == null) { - return null; - } - if (clazz.isInstance(av.getValue())) return clazz.cast(av.getValue()); - return null; - } - - private static List getArrayValues( - Map memberValues, - Map defaults, - String name, - final Class clazz) { - var av = memberValues.get(name); - if (av == null) av = defaults.get(name); - if (av == null) { - return java.util.Collections.EMPTY_LIST; - } - if (av.getValue() instanceof List) { - final List result = new ArrayList<>(); - for (final AnnotationValue v : getValueAsList(av)) { - if (clazz.isInstance(v.getValue())) { - result.add(clazz.cast(v.getValue())); - } else { - return java.util.Collections.EMPTY_LIST; - } - } - return result; - } else { - return java.util.Collections.EMPTY_LIST; - } - } - - @SuppressWarnings("unchecked") - private static List getValueAsList(AnnotationValue av) { - return (List) av.getValue(); - } -} diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/SchemaDocBuilder.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/SchemaDocBuilder.java index 30da0fd5c..f7b07e1bd 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/SchemaDocBuilder.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/SchemaDocBuilder.java @@ -232,8 +232,7 @@ private void populateObjectSchema(TypeMirror objectType, Schema objectSch } private void setFormatFromValidation(Element element, Schema propSchema) { - if (EmailPrism.getOptionalOn(element).isPresent() - || JavaxEmailPrism.getOptionalOn(element).isPresent()) { + if (EmailPrism.isPresent(element) || JavaxEmailPrism.isPresent(element)) { propSchema.setFormat("email"); } } @@ -311,7 +310,7 @@ private boolean ignoreField(VariableElement field) { } private boolean isHiddenField(VariableElement field) { - if (HiddenPrism.getOptionalOn(field).isPresent()) { + if (HiddenPrism.isPresent(field)) { return true; } for (AnnotationMirror annotationMirror : field.getAnnotationMirrors()) { diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/package-info.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/package-info.java index 18896ff2e..9fac10bcd 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/package-info.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/package-info.java @@ -16,7 +16,6 @@ @GeneratePrism(value = io.avaje.http.api.Post.class, publicAccess = true) @GeneratePrism(value = io.avaje.http.api.Produces.class, publicAccess = true) @GeneratePrism(value = io.avaje.http.api.Put.class, publicAccess = true) -@GeneratePrism(value = jakarta.inject.Inject.class) @GeneratePrism(value = io.swagger.v3.oas.annotations.OpenAPIDefinition.class, publicAccess = true) @GeneratePrism(value = io.swagger.v3.oas.annotations.tags.Tag.class, publicAccess = true) @GeneratePrism(value = io.swagger.v3.oas.annotations.tags.Tags.class, publicAccess = true) diff --git a/http-generator-core/src/main/java/module-info.java b/http-generator-core/src/main/java/module-info.java index 9e895411f..0521e3adc 100644 --- a/http-generator-core/src/main/java/module-info.java +++ b/http-generator-core/src/main/java/module-info.java @@ -13,6 +13,5 @@ requires static transitive io.swagger.v3.oas.models; requires static transitive io.swagger.v3.oas.annotations; requires static transitive java.validation; - requires static transitive jakarta.inject; requires static transitive jakarta.validation; } diff --git a/tests/test-javalin-jsonb/src/main/resources/public/openapi.json b/tests/test-javalin-jsonb/src/main/resources/public/openapi.json index dfa9169c6..fad3caca3 100644 --- a/tests/test-javalin-jsonb/src/main/resources/public/openapi.json +++ b/tests/test-javalin-jsonb/src/main/resources/public/openapi.json @@ -1,18 +1,18 @@ { "openapi" : "3.0.1", "info" : { - "title" : "Example service showing off the Path extension method of controller", + "title" : "Example service", "description" : "Example Javalin controllers with Java and Maven", "version" : "" }, "tags" : [ { "name" : "tag1", - "description" : "this is added to openapi tags" + "description" : "it's somethin" }, { "name" : "tag1", - "description" : "it's somethin" + "description" : "this is added to openapi tags" } ], "paths" : { From 2c66a1865e59cf651b15bc7a882d00c4bbc6d166 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Fri, 24 Feb 2023 00:51:54 -0500 Subject: [PATCH 0621/1323] Update openapi.json --- .../src/main/resources/public/openapi.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/test-javalin-jsonb/src/main/resources/public/openapi.json b/tests/test-javalin-jsonb/src/main/resources/public/openapi.json index fad3caca3..dfa9169c6 100644 --- a/tests/test-javalin-jsonb/src/main/resources/public/openapi.json +++ b/tests/test-javalin-jsonb/src/main/resources/public/openapi.json @@ -1,18 +1,18 @@ { "openapi" : "3.0.1", "info" : { - "title" : "Example service", + "title" : "Example service showing off the Path extension method of controller", "description" : "Example Javalin controllers with Java and Maven", "version" : "" }, "tags" : [ { "name" : "tag1", - "description" : "it's somethin" + "description" : "this is added to openapi tags" }, { "name" : "tag1", - "description" : "this is added to openapi tags" + "description" : "it's somethin" } ], "paths" : { From 9fd2c18fa3378e96838cb2fed7c934c2e26bfd5e Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Fri, 24 Feb 2023 11:47:18 -0500 Subject: [PATCH 0622/1323] fix multiple tags --- .../http/generator/core/openapi/DocContext.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/DocContext.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/DocContext.java index acbc8f5d9..bb6b8f0d0 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/DocContext.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/DocContext.java @@ -152,22 +152,22 @@ public void addTagsDefinition(Element element) { } public void addTagDefinition(Element element) { - final var tag = TagPrism.getInstanceOn(element); - if (tag == null) return; - openAPI.addTagsItem(createTagItem(tag)); + for (var tag : TagPrism.getAllInstancesOn(element)) { + openAPI.addTagsItem(createTagItem(tag)); + } } public void addSecurityScheme(Element element) { - var schemes = SecuritySchemePrism.getAllInstancesOn(element); - if (schemes == null) { - return; - } - this.addSecuritySchemes(schemes); + + this.addSecuritySchemes(SecuritySchemePrism.getAllInstancesOn(element)); } public void addSecuritySchemes(Element element) { var schemes = SecuritySchemesPrism.getInstanceOn(element); + if (schemes == null) { + return; + } this.addSecuritySchemes(schemes.value()); } From a8c08f7ab9cccf1d05d6cfdc9fa9841428f689a7 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sun, 26 Feb 2023 16:16:13 -0500 Subject: [PATCH 0623/1323] Enum Query/Form Params --- .../http/generator/core/ElementReader.java | 17 ++++++++- .../io/avaje/http/generator/core/TypeMap.java | 14 +++++++ .../example/myapp/web/test/ServerType.java | 7 ++++ .../myapp/web/test/TestController.java | 1 - .../myapp/web/test/TestController2.java | 38 +++++++++++++++++++ 5 files changed, 75 insertions(+), 2 deletions(-) create mode 100644 tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/ServerType.java create mode 100644 tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController2.java diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java index 456b0fc8e..6563b9dec 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java @@ -2,7 +2,10 @@ import static io.avaje.http.generator.core.ParamType.RESPONSE_HANDLER; +import java.util.Optional; + import javax.lang.model.element.Element; +import javax.lang.model.element.ElementKind; import javax.lang.model.element.TypeElement; import io.avaje.http.generator.core.openapi.MethodDocBuilder; @@ -42,7 +45,19 @@ public class ElementReader { this.rawType = rawType; this.shortType = Util.shortName(rawType); this.contextType = ctx.platform().isContextType(rawType); - this.typeHandler = TypeMap.get(rawType); + + if (type != null + && (defaultType == ParamType.FORMPARAM || defaultType == ParamType.QUERYPARAM) + && Optional.ofNullable(ctx.typeElement(type.mainType())) + .map(TypeElement::getKind) + .filter(ElementKind.ENUM::equals) + .isPresent()) { + + this.typeHandler = TypeMap.enumParamHandler(type); + } else { + + this.typeHandler = TypeMap.get(rawType); + } this.formMarker = formMarker; this.varName = element.getSimpleName().toString(); this.snakeName = Util.snakeCase(varName); diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/TypeMap.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/TypeMap.java index 6c3c97a6a..2ee88554c 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/TypeMap.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/TypeMap.java @@ -43,6 +43,20 @@ static TypeHandler get(String type) { return types.get(type); } + static TypeHandler enumParamHandler(UType type) { + return new ObjectHandler(type.mainType(), type.shortName()) { + @Override + public String toMethod() { + return type.shortType() + ".valueOf("; + } + + @Override + public String asMethod() { + return "java.util. Objects.toString("; + } + }; + } + static class StringHandler extends JavaLangType { StringHandler() { super("String"); diff --git a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/ServerType.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/ServerType.java new file mode 100644 index 000000000..f77febe75 --- /dev/null +++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/ServerType.java @@ -0,0 +1,7 @@ +package org.example.myapp.web.test; + +public enum ServerType { + PROXY, + HIDE_N_SEEK, + FFA +} diff --git a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController.java index ea01ae879..704e4c504 100644 --- a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController.java +++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController.java @@ -129,5 +129,4 @@ void neo( CompletableFuture getAllAsync() { return CompletableFuture.supplyAsync(() -> new HelloDto(12, "Jim", "asd")); } - } diff --git a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController2.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController2.java new file mode 100644 index 000000000..475fd1173 --- /dev/null +++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController2.java @@ -0,0 +1,38 @@ +package org.example.myapp.web.test; + +import org.example.myapp.web.HelloDto; + +import io.avaje.http.api.Controller; +import io.avaje.http.api.Default; +import io.avaje.http.api.Form; +import io.avaje.http.api.FormParam; +import io.avaje.http.api.Get; +import io.avaje.http.api.Path; +import io.avaje.http.api.Post; +import io.avaje.http.api.QueryParam; + +@Path("test/") +@Controller +public class TestController2 { + + @Form + @Get("/enumForm") + String enumForm(String s, ServerType type) { + return type.name(); + } + + @Get("/enumFormParam") + String enumFormParam(@FormParam String s, @FormParam ServerType type) { + return type.name(); + } + + @Get("/enumQuery") + String enumQuery(@QueryParam @Default("FFA") ServerType type) { + return type.name(); + } + + @Post("/enumQueryImplied") + String enumQueryImplied(HelloDto s, ServerType type) { + return type.name(); + } +} From e071f53892f3a77bfc835845ec5b5d3af3b8d6d5 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sun, 26 Feb 2023 16:57:50 -0500 Subject: [PATCH 0624/1323] no anon classes --- .../io/avaje/http/generator/core/TypeMap.java | 37 ++++++++++++------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/TypeMap.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/TypeMap.java index 2ee88554c..a47199040 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/TypeMap.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/TypeMap.java @@ -44,17 +44,7 @@ static TypeHandler get(String type) { } static TypeHandler enumParamHandler(UType type) { - return new ObjectHandler(type.mainType(), type.shortName()) { - @Override - public String toMethod() { - return type.shortType() + ".valueOf("; - } - - @Override - public String asMethod() { - return "java.util. Objects.toString("; - } - }; + return new EnumHandler(type); } static class StringHandler extends JavaLangType { @@ -183,7 +173,7 @@ static class BoolHandler extends Primitive { } } - static abstract class JavaLangType implements TypeHandler { + abstract static class JavaLangType implements TypeHandler { final String shortName; @@ -207,7 +197,7 @@ public String importType() { } } - static abstract class Primitive implements TypeHandler { + abstract static class Primitive implements TypeHandler { private final String type; @@ -291,8 +281,27 @@ static class LocalDateTimeHandler extends ObjectHandler { } } + static class EnumHandler extends ObjectHandler { + private final UType type; - static abstract class ObjectHandler implements TypeHandler { + EnumHandler(UType type) { + + super(type.mainType(), type.shortName()); + this.type = type; + } + + @Override + public String toMethod() { + return type.shortType() + ".valueOf("; + } + + @Override + public String asMethod() { + return "java.util.Objects.toString("; + } + } + + abstract static class ObjectHandler implements TypeHandler { private final String importType; private final String shortName; From 803479b3483e32dba349a31497748ab90e9a443c Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sun, 26 Feb 2023 21:04:41 -0500 Subject: [PATCH 0625/1323] multivalue queryparams --- .../io/avaje/http/api/PathTypeConversion.java | 22 ++++- .../http/generator/core/ElementReader.java | 87 +++++++++++++------ .../http/generator/core/PlatformAdapter.java | 5 ++ .../http/generator/core/TypeHandler.java | 4 +- .../io/avaje/http/generator/core/TypeMap.java | 76 ++++++++++++++-- .../generator/javalin/JavalinAdapter.java | 11 +++ .../myapp/web/test/TestController2.java | 7 ++ .../java/org/example/HelloController.java | 6 ++ 8 files changed, 180 insertions(+), 38 deletions(-) diff --git a/http-api/src/main/java/io/avaje/http/api/PathTypeConversion.java b/http-api/src/main/java/io/avaje/http/api/PathTypeConversion.java index 33943a13a..04e14403c 100644 --- a/http-api/src/main/java/io/avaje/http/api/PathTypeConversion.java +++ b/http-api/src/main/java/io/avaje/http/api/PathTypeConversion.java @@ -2,7 +2,11 @@ import java.math.BigDecimal; import java.time.*; +import java.util.List; +import java.util.Set; import java.util.UUID; +import java.util.function.Function; +import java.util.stream.Collectors; /** * Helper type conversion methods. @@ -11,6 +15,8 @@ */ public final class PathTypeConversion { + private PathTypeConversion() {} + /** * Return the value if non-null and otherwise the default value. * @@ -22,6 +28,10 @@ public static String withDefault(String value, String defaultValue) { return value != null ? value : defaultValue; } + public static List withDefault(List value, String defaultValue) { + return value != null && !value.isEmpty() ? value : List.of(defaultValue); + } + /** * Check for null for a required property throwing RequiredArgumentException * if the value is null. @@ -41,9 +51,15 @@ private static void checkNull(String value) { } } - /** - * Convert to int. - */ + public static List list(Function func, List params) { + return params.stream().map(func).collect(Collectors.toList()); + } + + public static Set set(Function func, List params) { + return params.stream().map(func).collect(Collectors.toSet()); + } + + /** Convert to int. */ public static int asInt(String value) { checkNull(value); try { diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java index 6563b9dec..645cd5845 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java @@ -2,6 +2,7 @@ import static io.avaje.http.generator.core.ParamType.RESPONSE_HANDLER; +import java.util.Objects; import java.util.Optional; import javax.lang.model.element.Element; @@ -46,18 +47,7 @@ public class ElementReader { this.shortType = Util.shortName(rawType); this.contextType = ctx.platform().isContextType(rawType); - if (type != null - && (defaultType == ParamType.FORMPARAM || defaultType == ParamType.QUERYPARAM) - && Optional.ofNullable(ctx.typeElement(type.mainType())) - .map(TypeElement::getKind) - .filter(ElementKind.ENUM::equals) - .isPresent()) { - - this.typeHandler = TypeMap.enumParamHandler(type); - } else { - - this.typeHandler = TypeMap.get(rawType); - } + typeHandler = initTypeHandler(defaultType); this.formMarker = formMarker; this.varName = element.getSimpleName().toString(); this.snakeName = Util.snakeCase(varName); @@ -71,6 +61,46 @@ public class ElementReader { } } + TypeHandler initTypeHandler(ParamType paramType) { + if ((paramType == ParamType.FORMPARAM + || paramType == ParamType.QUERYPARAM + || paramType == ParamType.HEADER)) { + + final var typeOp = Optional.ofNullable(type); + + final var mainTypeEnum = + typeOp + .flatMap(t -> Optional.ofNullable(ctx.typeElement(t.mainType()))) + .map(TypeElement::getKind) + .filter(ElementKind.ENUM::equals) + .isPresent(); + + final var isCollection = + typeOp + .filter(t -> t.isGeneric() && !t.mainType().startsWith("java.util.Map")) + .isPresent(); + + if (mainTypeEnum) { + return TypeMap.enumParamHandler(type); + } else if (isCollection) { + + if (paramType == ParamType.FORMPARAM) { + throw new IllegalStateException("You can't have a single Form Parameter be a list"); + } + final var isEnumCollection = + typeOp + .flatMap(t -> Optional.ofNullable(ctx.typeElement(t.param0()))) + .map(TypeElement::getKind) + .filter(ElementKind.ENUM::equals) + .isPresent(); + + return TypeMap.collectionHandler(type, isEnumCollection); + } + } + + return TypeMap.get(rawType); + } + private boolean useValidation() { if (typeHandler != null) { return false; @@ -182,10 +212,8 @@ private String handlerShortType() { void addImports(ControllerReader bean) { if (typeHandler != null) { - String importType = typeHandler.importType(); - if (importType != null) { - bean.addImportType(rawType); - } + typeHandler.importTypes().stream().filter(Objects::nonNull).forEach(bean::addImportType); + } else { bean.addImportType(rawType); } @@ -285,19 +313,24 @@ private boolean setValue(Append writer, PathSegments segments, String shortType) // this is a body (POST, PATCH) writer.append(ctx.platform().bodyAsClass(type)); - } else { + } else if (type != null && type.isGeneric() && paramType == ParamType.QUERYPARAM) { if (hasParamDefault()) { - ctx.platform().writeReadParameter(writer, paramType, paramName, paramDefault); + ctx.platform().writeReadCollectionParameter(writer, paramType, paramName, paramDefault); } else { - boolean checkNull = notNullKotlin || (paramType == ParamType.FORMPARAM && typeHandler.isPrimitive()); - if (checkNull) { - writer.append("checkNull("); - } - ctx.platform().writeReadParameter(writer, paramType, paramName); - //writer.append("ctx.%s(\"%s\")", paramType, paramName); - if (checkNull) { - writer.append(", \"%s\")", paramName); - } + ctx.platform().writeReadCollectionParameter(writer, paramType, paramName); + } + } else if (hasParamDefault()) { + ctx.platform().writeReadParameter(writer, paramType, paramName, paramDefault); + } else { + final var checkNull = + notNullKotlin || (paramType == ParamType.FORMPARAM && typeHandler.isPrimitive()); + if (checkNull) { + writer.append("checkNull("); + } + ctx.platform().writeReadParameter(writer, paramType, paramName); + // writer.append("ctx.%s(\"%s\")", paramType, paramName); + if (checkNull) { + writer.append(", \"%s\")", paramName); } } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/PlatformAdapter.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/PlatformAdapter.java index fb135c9e2..ed072b3f2 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/PlatformAdapter.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/PlatformAdapter.java @@ -46,4 +46,9 @@ public interface PlatformAdapter { void writeReadParameter(Append writer, ParamType paramType, String paramName); void writeReadParameter(Append writer, ParamType paramType, String paramName, String paramDefault); + + void writeReadCollectionParameter(Append writer, ParamType paramType, String paramName); + + void writeReadCollectionParameter(Append writer, ParamType paramType, String paramName, String paramDefault); + } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/TypeHandler.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/TypeHandler.java index a6c6a0878..c5e05858b 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/TypeHandler.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/TypeHandler.java @@ -1,5 +1,7 @@ package io.avaje.http.generator.core; +import java.util.List; + /** * Handles type conversion for path and query parameters. */ @@ -18,7 +20,7 @@ interface TypeHandler { /** * The type for adding to imports. */ - String importType(); + List importTypes(); /** * The short name. diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/TypeMap.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/TypeMap.java index a47199040..6e6185ed7 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/TypeMap.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/TypeMap.java @@ -1,6 +1,7 @@ package io.avaje.http.generator.core; import java.util.HashMap; +import java.util.List; import java.util.Map; /** @@ -13,7 +14,7 @@ class TypeMap { private static final Map types = new HashMap<>(); private static void add(TypeHandler h) { - types.put(h.importType(), h); + types.put(h.importTypes().get(0), h); } static { @@ -43,6 +44,22 @@ static TypeHandler get(String type) { return types.get(type); } + static TypeHandler collectionHandler(UType type, boolean isEnum) { + final var handler = types.get(type.param0()); + + if (!isEnum && handler == null) { + return null; + } + + return types.computeIfAbsent( + type.full(), + k -> + new CollectionHandler( + isEnum ? enumParamHandler(type.paramRaw()) : handler, + type.mainType().startsWith("java.util.Set"), + isEnum)); + } + static TypeHandler enumParamHandler(UType type) { return new EnumHandler(type); } @@ -192,8 +209,8 @@ public String shortName() { } @Override - public String importType() { - return null; + public List importTypes() { + return List.of(); } } @@ -234,8 +251,8 @@ public String toMethod() { } @Override - public String importType() { - return null; + public List importTypes() { + return List.of(); } } @@ -301,6 +318,51 @@ public String asMethod() { } } + static class CollectionHandler implements TypeHandler { + + private final String importType; + private final String shortName; + private final String toMethod; + + CollectionHandler(TypeHandler handler, boolean set, boolean isEnum) { + + this.importType = handler.importTypes().get(0); + this.shortName = handler.shortName(); + this.toMethod = + (set ? "set" : "list") + + "(" + + (isEnum + ? handler.toMethod().replace(".", "::").replace("(", "") + : "PathTypeConversion::" + shortName) + + ", "; + } + + @Override + public boolean isPrimitive() { + return false; + } + + @Override + public List importTypes() { + return List.of("io.avaje.http.api.PathTypeConversion", importType); + } + + @Override + public String shortName() { + return shortName; + } + + @Override + public String asMethod() { + return null; + } + + @Override + public String toMethod() { + return toMethod; + } + } + abstract static class ObjectHandler implements TypeHandler { private final String importType; @@ -321,8 +383,8 @@ public boolean isPrimitive() { } @Override - public String importType() { - return importType; + public List importTypes() { + return List.of(importType); } @Override diff --git a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinAdapter.java b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinAdapter.java index 6db6c07df..be775382e 100644 --- a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinAdapter.java +++ b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinAdapter.java @@ -67,4 +67,15 @@ public void writeReadParameter(Append writer, ParamType paramType, String paramN public void writeReadParameter(Append writer, ParamType paramType, String paramName, String paramDefault) { writer.append("withDefault(ctx.%s(\"%s\"), \"%s\")", paramType, paramName, paramDefault); } + + @Override + public void writeReadCollectionParameter(Append writer, ParamType paramType, String paramName) { + writer.append("ctx.%s(\"%s\")", paramName); + } + + @Override + public void writeReadCollectionParameter( + Append writer, ParamType paramType, String paramName, String paramDefault) { + writer.append("withDefault(ctx.queryParams(\"%s\"), \"%s\")", paramName, paramDefault); + } } diff --git a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController2.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController2.java index 475fd1173..daaf6204e 100644 --- a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController2.java +++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController2.java @@ -1,5 +1,7 @@ package org.example.myapp.web.test; +import java.util.Set; + import org.example.myapp.web.HelloDto; import io.avaje.http.api.Controller; @@ -31,6 +33,11 @@ String enumQuery(@QueryParam @Default("FFA") ServerType type) { return type.name(); } + @Get("/enumQuery2") + String enumMultiQuery(@QueryParam @Default("FFA") Set type) { + return type.toString(); + } + @Post("/enumQueryImplied") String enumQueryImplied(HelloDto s, ServerType type) { return type.name(); diff --git a/tests/test-nima-jsonb/src/main/java/org/example/HelloController.java b/tests/test-nima-jsonb/src/main/java/org/example/HelloController.java index f58f0ba5b..2c9738d26 100644 --- a/tests/test-nima-jsonb/src/main/java/org/example/HelloController.java +++ b/tests/test-nima-jsonb/src/main/java/org/example/HelloController.java @@ -12,6 +12,7 @@ import io.avaje.http.api.Post; import io.avaje.http.api.Produces; import io.avaje.http.api.Put; +import io.avaje.http.api.QueryParam; import io.helidon.common.http.HttpMediaType; import io.helidon.nima.webserver.http.ServerRequest; import io.helidon.nima.webserver.http.ServerResponse; @@ -54,6 +55,11 @@ String testHeader(@Header String head) { return head; } + @Get("/param") + String testParam(@QueryParam String param) { + return param; + } + // curl -v localhost:8081/person/jack @Get("person/{name}") Person person(String name) { From ada8bff351ed0696ce02e0df8c331074de20a9c5 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sun, 26 Feb 2023 22:55:49 -0500 Subject: [PATCH 0626/1323] nima --- .../client/ClientPlatformAdapter.java | 13 +++++ .../http/generator/core/ElementReader.java | 19 +++++--- .../io/avaje/http/generator/core/TypeMap.java | 12 +++-- .../generator/javalin/JavalinAdapter.java | 13 ++++- .../helidon/nima/NimaPlatformAdapter.java | 39 +++++++++++++++ .../src/main/java/org/example/ServerType.java | 7 +++ .../main/java/org/example/TestController.java | 48 +++++++++++++++++++ 7 files changed, 139 insertions(+), 12 deletions(-) create mode 100644 tests/test-nima-jsonb/src/main/java/org/example/ServerType.java create mode 100644 tests/test-nima-jsonb/src/main/java/org/example/TestController.java diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientPlatformAdapter.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientPlatformAdapter.java index 0880fe3c7..2ebb2ae37 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientPlatformAdapter.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientPlatformAdapter.java @@ -54,4 +54,17 @@ public void writeReadParameter(Append writer, ParamType paramType, String paramN public void writeReadParameter(Append writer, ParamType paramType, String paramName, String paramDefault) { } + + @Override + public void writeReadCollectionParameter( + Append writer, ParamType paramType, String paramName) { + } + + @Override + public void writeReadCollectionParameter( + Append writer, + ParamType paramType, + String paramName, + String paramDefault) { + } } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java index 645cd5845..b071aa88b 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java @@ -25,6 +25,7 @@ public class ElementReader { private final boolean formMarker; private final boolean contextType; private final boolean useValidation; + private final boolean specialParam; private String paramName; private ParamType paramType; @@ -47,7 +48,14 @@ public class ElementReader { this.shortType = Util.shortName(rawType); this.contextType = ctx.platform().isContextType(rawType); - typeHandler = initTypeHandler(defaultType); + this.specialParam = + defaultType == ParamType.FORMPARAM + || defaultType == ParamType.QUERYPARAM + || defaultType == ParamType.HEADER + || defaultType == ParamType.COOKIE; + + typeHandler = initTypeHandler(); + this.formMarker = formMarker; this.varName = element.getSimpleName().toString(); this.snakeName = Util.snakeCase(varName); @@ -61,10 +69,9 @@ public class ElementReader { } } - TypeHandler initTypeHandler(ParamType paramType) { - if ((paramType == ParamType.FORMPARAM - || paramType == ParamType.QUERYPARAM - || paramType == ParamType.HEADER)) { + TypeHandler initTypeHandler() { + + if (specialParam) { final var typeOp = Optional.ofNullable(type); @@ -313,7 +320,7 @@ private boolean setValue(Append writer, PathSegments segments, String shortType) // this is a body (POST, PATCH) writer.append(ctx.platform().bodyAsClass(type)); - } else if (type != null && type.isGeneric() && paramType == ParamType.QUERYPARAM) { + } else if (type != null && type.isGeneric() && specialParam) { if (hasParamDefault()) { ctx.platform().writeReadCollectionParameter(writer, paramType, paramName, paramDefault); } else { diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/TypeMap.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/TypeMap.java index 6e6185ed7..f5a2dbf68 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/TypeMap.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/TypeMap.java @@ -320,13 +320,14 @@ public String asMethod() { static class CollectionHandler implements TypeHandler { - private final String importType; + private final List importTypes; private final String shortName; - private final String toMethod; + private String toMethod; CollectionHandler(TypeHandler handler, boolean set, boolean isEnum) { - this.importType = handler.importTypes().get(0); + this.importTypes = new ArrayList<>(handler.importTypes()); + importTypes.add("io.avaje.http.api.PathTypeConversion"); this.shortName = handler.shortName(); this.toMethod = (set ? "set" : "list") @@ -335,6 +336,8 @@ static class CollectionHandler implements TypeHandler { ? handler.toMethod().replace(".", "::").replace("(", "") : "PathTypeConversion::" + shortName) + ", "; + + this.toMethod = toMethod.replace("PathTypeConversion::String", "Object::toString"); } @Override @@ -344,7 +347,8 @@ public boolean isPrimitive() { @Override public List importTypes() { - return List.of("io.avaje.http.api.PathTypeConversion", importType); + + return importTypes; } @Override diff --git a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinAdapter.java b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinAdapter.java index be775382e..c29d5f418 100644 --- a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinAdapter.java +++ b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinAdapter.java @@ -64,18 +64,27 @@ public void writeReadParameter(Append writer, ParamType paramType, String paramN } @Override - public void writeReadParameter(Append writer, ParamType paramType, String paramName, String paramDefault) { + public void writeReadParameter( + Append writer, ParamType paramType, String paramName, String paramDefault) { writer.append("withDefault(ctx.%s(\"%s\"), \"%s\")", paramType, paramName, paramDefault); } @Override public void writeReadCollectionParameter(Append writer, ParamType paramType, String paramName) { - writer.append("ctx.%s(\"%s\")", paramName); + if (paramType != ParamType.QUERYPARAM) { + throw new UnsupportedOperationException( + "Only MultiValue Query Params are supported in Javalin"); + } + writer.append("ctx.queryParams(\"%s\")", paramName); } @Override public void writeReadCollectionParameter( Append writer, ParamType paramType, String paramName, String paramDefault) { + if (paramType != ParamType.QUERYPARAM) { + throw new UnsupportedOperationException( + "Only MultiValue Query Params are supported in Javalin"); + } writer.append("withDefault(ctx.queryParams(\"%s\"), \"%s\")", paramName, paramDefault); } } diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/NimaPlatformAdapter.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/NimaPlatformAdapter.java index 101d07cda..2a5ae3e36 100644 --- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/NimaPlatformAdapter.java +++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/NimaPlatformAdapter.java @@ -107,4 +107,43 @@ public void writeReadParameter(Append writer, ParamType paramType, String paramN writer.append("null // TODO req.%s().param(\"%s\")", paramType.type(), paramName); } } + + @Override + public void writeReadCollectionParameter(Append writer, ParamType paramType, String paramName) { + switch (paramType) { + case QUERYPARAM: + writer.append("req.query().all(\"%s\")", paramName); + break; + case HEADER: + writer.append("req.headers().all(\"%s\", () -> java.util.List.of())", paramName); + break; + case COOKIE: + writer.append("req.headers().cookies().all(\"%s\", () -> java.util.List.of())", paramName); + break; + default: + throw new UnsupportedOperationException("Unsupported MultiValue Parameter"); + } + } + + @Override + public void writeReadCollectionParameter( + Append writer, ParamType paramType, String paramName, String paramDefault) { + switch (paramType) { + case QUERYPARAM: + writer.append( + "req.query().all(\"%s\", () -> java.util.List.of(\"%s\"))", paramName, paramDefault); + break; + case HEADER: + writer.append( + "req.headers().all(\"%s\", () -> java.util.List.of(\"%s\"))", paramName, paramDefault); + break; + case COOKIE: + writer.append( + "req.headers().cookies().all(\"%s\", () -> java.util.List.of(\"%s\"))", + paramName, paramDefault); + break; + default: + throw new UnsupportedOperationException("Unsupported MultiValue Parameter"); + } + } } diff --git a/tests/test-nima-jsonb/src/main/java/org/example/ServerType.java b/tests/test-nima-jsonb/src/main/java/org/example/ServerType.java new file mode 100644 index 000000000..cb6151254 --- /dev/null +++ b/tests/test-nima-jsonb/src/main/java/org/example/ServerType.java @@ -0,0 +1,7 @@ +package org.example; + +public enum ServerType { + PROXY, + HIDE_N_SEEK, + FFA +} diff --git a/tests/test-nima-jsonb/src/main/java/org/example/TestController.java b/tests/test-nima-jsonb/src/main/java/org/example/TestController.java new file mode 100644 index 000000000..d9728fc38 --- /dev/null +++ b/tests/test-nima-jsonb/src/main/java/org/example/TestController.java @@ -0,0 +1,48 @@ +package org.example; + +import java.util.Set; + +import io.avaje.http.api.Controller; +import io.avaje.http.api.Default; +import io.avaje.http.api.Form; +import io.avaje.http.api.FormParam; +import io.avaje.http.api.Get; +import io.avaje.http.api.Path; +import io.avaje.http.api.Post; +import io.avaje.http.api.QueryParam; + +@Path("test/") +@Controller +public class TestController { + + @Get("/paramMulti") + String paramMulti(Set strings) { + return strings.toString(); + } + + @Form + @Get("/enumForm") + String enumForm(String s, ServerType type) { + return type.name(); + } + + @Get("/enumFormParam") + String enumFormParam(@FormParam String s, @FormParam ServerType type) { + return type.name(); + } + + @Get("/enumQuery") + String enumQuery(@QueryParam @Default("FFA") ServerType type) { + return type.name(); + } + + @Get("/enumQuery2") + String enumMultiQuery(@QueryParam @Default("FFA") Set type) { + return type.toString(); + } + + @Post("/enumQueryImplied") + String enumQueryImplied(Person s, @QueryParam ServerType type) { + return type.name(); + } +} From b57a48de15aaa71ba4ebf7b969c58ec434fda78d Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sun, 26 Feb 2023 23:33:58 -0500 Subject: [PATCH 0627/1323] http generators finished --- .../http/api/PathTypeConversionTest.java | 5 ++- .../io/avaje/http/generator/core/TypeMap.java | 1 + .../helidon/HelidonPlatformAdapter.java | 39 +++++++++++++++++++ .../avaje/http/generator/jex/JexAdapter.java | 19 +++++++++ .../src/main/java/org/example/ServerType.java | 7 ++++ .../main/java/org/example/TestController.java | 35 +++++++++++++++++ .../main/java/org/example/web/ServerType.java | 7 ++++ .../java/org/example/web/TestController.java | 35 +++++++++++++++++ 8 files changed, 147 insertions(+), 1 deletion(-) create mode 100644 tests/test-helidon/src/main/java/org/example/ServerType.java create mode 100644 tests/test-helidon/src/main/java/org/example/TestController.java create mode 100644 tests/test-jex/src/main/java/org/example/web/ServerType.java create mode 100644 tests/test-jex/src/main/java/org/example/web/TestController.java diff --git a/http-api/src/test/java/io/avaje/http/api/PathTypeConversionTest.java b/http-api/src/test/java/io/avaje/http/api/PathTypeConversionTest.java index ba11c8e1e..9f003f488 100644 --- a/http-api/src/test/java/io/avaje/http/api/PathTypeConversionTest.java +++ b/http-api/src/test/java/io/avaje/http/api/PathTypeConversionTest.java @@ -7,6 +7,7 @@ import java.time.LocalDateTime; import java.time.LocalTime; import java.time.OffsetDateTime; +import java.util.List; import java.util.UUID; import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat; @@ -19,7 +20,9 @@ class PathTypeConversionTest { void withDefault() { assertEquals("a", PathTypeConversion.withDefault("a", "myVal")); assertEquals("", PathTypeConversion.withDefault("", "myVal")); - assertEquals("myVal", PathTypeConversion.withDefault(null, "myVal")); + String nully = null; + assertEquals("myVal", PathTypeConversion.withDefault(nully, "myVal")); + assertThat(PathTypeConversion.withDefault(List.of(), "myVal")).anyMatch(s -> "myVal".equals(s)); } @Test diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/TypeMap.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/TypeMap.java index f5a2dbf68..1d0a481e3 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/TypeMap.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/TypeMap.java @@ -1,5 +1,6 @@ package io.avaje.http.generator.core; +import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; diff --git a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/HelidonPlatformAdapter.java b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/HelidonPlatformAdapter.java index 0648478c5..e4bb8a975 100644 --- a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/HelidonPlatformAdapter.java +++ b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/HelidonPlatformAdapter.java @@ -113,4 +113,43 @@ public void writeReadParameter(Append writer, ParamType paramType, String paramN writer.append("null // TODO req.%s().param(\"%s\")", paramType.type(), paramName); } } + + @Override + public void writeReadCollectionParameter(Append writer, ParamType paramType, String paramName) { + switch (paramType) { + case QUERYPARAM: + writer.append("req.queryParams().all(\"%s\")", paramName); + break; + case HEADER: + writer.append("req.headers().all(\"%s\")", paramName); + break; + case COOKIE: + writer.append("req.headers().cookies().all(\"%s\")", paramName); + break; + default: + throw new UnsupportedOperationException("Unsupported MultiValue Parameter"); + } + } + + @Override + public void writeReadCollectionParameter( + Append writer, ParamType paramType, String paramName, String paramDefault) { + switch (paramType) { + case QUERYPARAM: + writer.append( + "withDefault(req.queryParams().all(\"%s\"), \"%s\")", paramName, paramDefault); + break; + case HEADER: + writer.append( + "withDefault(req.headers().all(\"%s\"), \"%s\")", paramName, paramDefault); + break; + case COOKIE: + writer.append( + "withDefault(req.headers().cookies().all(\"%s\"), \"%s\")", + paramName, paramDefault); + break; + default: + throw new UnsupportedOperationException("Unsupported MultiValue Parameter"); + } + } } diff --git a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/JexAdapter.java b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/JexAdapter.java index fc8381e4b..1438316a3 100644 --- a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/JexAdapter.java +++ b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/JexAdapter.java @@ -62,4 +62,23 @@ public void writeReadParameter(Append writer, ParamType paramType, String paramN public void writeReadParameter(Append writer, ParamType paramType, String paramName, String paramDefault) { writer.append("withDefault(ctx.%s(\"%s\"), \"%s\")", paramType, paramName, paramDefault); } + + @Override + public void writeReadCollectionParameter(Append writer, ParamType paramType, String paramName) { + if (paramType != ParamType.QUERYPARAM) { + throw new UnsupportedOperationException( + "Only MultiValue Query Params are supported in Jex"); + } + writer.append("ctx.queryParams(\"%s\")", paramName); + } + + @Override + public void writeReadCollectionParameter( + Append writer, ParamType paramType, String paramName, String paramDefault) { + if (paramType != ParamType.QUERYPARAM) { + throw new UnsupportedOperationException( + "Only MultiValue Query Params are supported in Jex"); + } + writer.append("withDefault(ctx.queryParams(\"%s\"), \"%s\")", paramName, paramDefault); + } } diff --git a/tests/test-helidon/src/main/java/org/example/ServerType.java b/tests/test-helidon/src/main/java/org/example/ServerType.java new file mode 100644 index 000000000..cb6151254 --- /dev/null +++ b/tests/test-helidon/src/main/java/org/example/ServerType.java @@ -0,0 +1,7 @@ +package org.example; + +public enum ServerType { + PROXY, + HIDE_N_SEEK, + FFA +} diff --git a/tests/test-helidon/src/main/java/org/example/TestController.java b/tests/test-helidon/src/main/java/org/example/TestController.java new file mode 100644 index 000000000..8c40b29ab --- /dev/null +++ b/tests/test-helidon/src/main/java/org/example/TestController.java @@ -0,0 +1,35 @@ +package org.example; + +import java.util.Set; + +import io.avaje.http.api.Controller; +import io.avaje.http.api.Default; +import io.avaje.http.api.Get; +import io.avaje.http.api.Path; +import io.avaje.http.api.Post; +import io.avaje.http.api.QueryParam; + +@Path("test/") +@Controller +public class TestController { + + @Get("/paramMulti") + String paramMulti(Set strings) { + return strings.toString(); + } + + @Get("/enumQuery") + String enumQuery(@QueryParam @Default("FFA") ServerType type) { + return type.name(); + } + + @Get("/enumQuery2") + String enumMultiQuery(@QueryParam @Default("FFA") Set type) { + return type.toString(); + } + + @Post("/enumQueryImplied") + String enumQueryImplied(String s, @QueryParam ServerType type) { + return type.name(); + } +} diff --git a/tests/test-jex/src/main/java/org/example/web/ServerType.java b/tests/test-jex/src/main/java/org/example/web/ServerType.java new file mode 100644 index 000000000..9409dacc9 --- /dev/null +++ b/tests/test-jex/src/main/java/org/example/web/ServerType.java @@ -0,0 +1,7 @@ +package org.example.web; + +public enum ServerType { + PROXY, + HIDE_N_SEEK, + FFA +} diff --git a/tests/test-jex/src/main/java/org/example/web/TestController.java b/tests/test-jex/src/main/java/org/example/web/TestController.java new file mode 100644 index 000000000..ffc6c28b5 --- /dev/null +++ b/tests/test-jex/src/main/java/org/example/web/TestController.java @@ -0,0 +1,35 @@ +package org.example.web; + +import java.util.Set; + +import io.avaje.http.api.Controller; +import io.avaje.http.api.Default; +import io.avaje.http.api.Get; +import io.avaje.http.api.Path; +import io.avaje.http.api.Post; +import io.avaje.http.api.QueryParam; + +@Path("test/") +@Controller +public class TestController { + + @Get("/paramMulti") + String paramMulti(Set strings) { + return strings.toString(); + } + + @Get("/enumQuery") + String enumQuery(@QueryParam @Default("FFA") ServerType type) { + return type.name(); + } + + @Get("/enumQuery2") + String enumMultiQuery(@QueryParam @Default("FFA") Set type) { + return type.toString(); + } + + @Post("/enumQueryImplied") + String enumQueryImplied(HelloDto s, @QueryParam ServerType type) { + return type.name(); + } +} From 331f396166f481276e5d1553494f83c815029c29 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sun, 26 Feb 2023 23:54:41 -0500 Subject: [PATCH 0628/1323] BeanParam Support --- .../io/avaje/http/generator/core/ElementReader.java | 10 ++++++---- .../main/java/org/example/myapp/web/GetBeanForm.java | 12 ++++++++++++ 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java index b071aa88b..f201f15a1 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java @@ -34,6 +34,7 @@ public class ElementReader { private String paramDefault; private boolean notNullKotlin; + private boolean isParamCollection; //private boolean notNullJavax; ElementReader(Element element, ProcessingContext ctx, ParamType defaultType, boolean formMarker) { @@ -73,7 +74,8 @@ TypeHandler initTypeHandler() { if (specialParam) { - final var typeOp = Optional.ofNullable(type); + final var typeOp = + Optional.ofNullable(type).or(() -> Optional.of(UType.parse(element.asType()))); final var mainTypeEnum = typeOp @@ -90,7 +92,7 @@ TypeHandler initTypeHandler() { if (mainTypeEnum) { return TypeMap.enumParamHandler(type); } else if (isCollection) { - + this.isParamCollection = true; if (paramType == ParamType.FORMPARAM) { throw new IllegalStateException("You can't have a single Form Parameter be a list"); } @@ -101,7 +103,7 @@ TypeHandler initTypeHandler() { .filter(ElementKind.ENUM::equals) .isPresent(); - return TypeMap.collectionHandler(type, isEnumCollection); + return TypeMap.collectionHandler(typeOp.orElseThrow(), isEnumCollection); } } @@ -320,7 +322,7 @@ private boolean setValue(Append writer, PathSegments segments, String shortType) // this is a body (POST, PATCH) writer.append(ctx.platform().bodyAsClass(type)); - } else if (type != null && type.isGeneric() && specialParam) { + } else if (isParamCollection && specialParam) { if (hasParamDefault()) { ctx.platform().writeReadCollectionParameter(writer, paramType, paramName, paramDefault); } else { diff --git a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/GetBeanForm.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/GetBeanForm.java index 21eb47db3..fe0b552f0 100644 --- a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/GetBeanForm.java +++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/GetBeanForm.java @@ -1,5 +1,7 @@ package org.example.myapp.web; +import java.util.List; + import javax.validation.Valid; import javax.validation.constraints.Email; import javax.validation.constraints.NotNull; @@ -19,6 +21,8 @@ public class GetBeanForm { @Size(max = 100) private String email; + private List addresses; + public String getName() { return name; } @@ -44,4 +48,12 @@ public GetBeanForm(String name, String email) { public String toString() { return "HelloForm{" + "name='" + name + '\'' + ", email='" + email + '\'' + '}'; } + + public List getAddresses() { + return addresses; + } + + public void setAddresses(List addresses) { + this.addresses = addresses; + } } From fbe59f5d228eaa9414121a3d0c6135028393f05d Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Mon, 27 Feb 2023 00:19:23 -0500 Subject: [PATCH 0629/1323] client support multi value --- .../java/io/avaje/http/client/DHttpClientRequest.java | 8 ++++++++ .../src/main/java/io/avaje/http/client/UrlBuilder.java | 9 +++++++++ 2 files changed, 17 insertions(+) diff --git a/http-client/src/main/java/io/avaje/http/client/DHttpClientRequest.java b/http-client/src/main/java/io/avaje/http/client/DHttpClientRequest.java index dc468d631..a670f5495 100644 --- a/http-client/src/main/java/io/avaje/http/client/DHttpClientRequest.java +++ b/http-client/src/main/java/io/avaje/http/client/DHttpClientRequest.java @@ -125,6 +125,14 @@ public HttpClientRequest header(String name, String value) { @Override public HttpClientRequest header(String name, Object value) { + + if (value instanceof Collection) { + for (final var e : (Collection) value) { + header(name, e); + } + return this; + } + return value != null ? header(name, value.toString()) : this; } diff --git a/http-client/src/main/java/io/avaje/http/client/UrlBuilder.java b/http-client/src/main/java/io/avaje/http/client/UrlBuilder.java index 40e82d787..2ed93e78d 100644 --- a/http-client/src/main/java/io/avaje/http/client/UrlBuilder.java +++ b/http-client/src/main/java/io/avaje/http/client/UrlBuilder.java @@ -2,6 +2,7 @@ import java.net.URLEncoder; import java.nio.charset.StandardCharsets; +import java.util.Collection; import java.util.Map; /** @@ -84,6 +85,14 @@ public UrlBuilder queryParam(String name, String value) { * The name and value parameters are url encoded. */ public UrlBuilder queryParam(String name, Object value) { + + if (value instanceof Collection) { + for (var e : (Collection) value) { + queryParam(name, e); + } + return this; + } + if (value != null) { addQueryParam(name, value.toString()); } From 02b8db40976e7516b32a6e0122ff2a100648ff1e Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Mon, 27 Feb 2023 00:26:23 -0500 Subject: [PATCH 0630/1323] doc --- .../main/java/io/avaje/http/client/HttpClientRequest.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/http-client/src/main/java/io/avaje/http/client/HttpClientRequest.java b/http-client/src/main/java/io/avaje/http/client/HttpClientRequest.java index 22cc04417..db1f14ff8 100644 --- a/http-client/src/main/java/io/avaje/http/client/HttpClientRequest.java +++ b/http-client/src/main/java/io/avaje/http/client/HttpClientRequest.java @@ -109,9 +109,10 @@ public interface HttpClientRequest { HttpClientRequest header(String name, String value); /** - * Add the header to the request implicitly converting the value to a String. + * Add the header to the request implicitly converting the value to a String. If the value is a + * collection then it's values are appended with the same key * - * @param name The header name + * @param name The header name * @param value The header value * @return The request being built */ @@ -218,7 +219,7 @@ public interface HttpClientRequest { HttpClientRequest queryParam(String name, String value); /** - * Add a query parameter + * Add a query parameter, if value is a collection then it's values are appended with the same key * * @param name The name of the query parameter * @param value The value of the query parameter which can be null From efd8a2b0c4370703d34e4ed33dc3020d6d2723d5 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Mon, 27 Feb 2023 09:11:06 -0500 Subject: [PATCH 0631/1323] Update ElementReader.java --- .../main/java/io/avaje/http/generator/core/ElementReader.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java index f201f15a1..b45917b64 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java @@ -93,9 +93,6 @@ TypeHandler initTypeHandler() { return TypeMap.enumParamHandler(type); } else if (isCollection) { this.isParamCollection = true; - if (paramType == ParamType.FORMPARAM) { - throw new IllegalStateException("You can't have a single Form Parameter be a list"); - } final var isEnumCollection = typeOp .flatMap(t -> Optional.ofNullable(ctx.typeElement(t.param0()))) From 8387b097e73ead41bf4592dbbb77c72bdd7a80cb Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Mon, 27 Feb 2023 09:37:14 -0500 Subject: [PATCH 0632/1323] multi default --- http-api/src/main/java/io/avaje/http/api/Default.java | 7 ++----- .../java/io/avaje/http/api/PathTypeConversion.java | 4 ++-- .../java/io/avaje/http/api/PathTypeConversionTest.java | 2 +- .../http/generator/client/ClientPlatformAdapter.java | 2 +- .../io/avaje/http/generator/core/ElementReader.java | 5 +++-- .../io/avaje/http/generator/core/PlatformAdapter.java | 2 +- .../http/generator/helidon/HelidonPlatformAdapter.java | 10 +++++----- .../avaje/http/generator/javalin/JavalinAdapter.java | 4 ++-- .../java/io/avaje/http/generator/jex/JexAdapter.java | 4 ++-- .../generator/helidon/nima/NimaPlatformAdapter.java | 10 ++++++---- 10 files changed, 25 insertions(+), 25 deletions(-) diff --git a/http-api/src/main/java/io/avaje/http/api/Default.java b/http-api/src/main/java/io/avaje/http/api/Default.java index cb81b3e25..3dc421744 100644 --- a/http-api/src/main/java/io/avaje/http/api/Default.java +++ b/http-api/src/main/java/io/avaje/http/api/Default.java @@ -25,9 +25,6 @@ @Retention(value = RUNTIME) public @interface Default { - /** - * The default value. - */ - String value(); - + /** The default values. */ + String[] value(); } diff --git a/http-api/src/main/java/io/avaje/http/api/PathTypeConversion.java b/http-api/src/main/java/io/avaje/http/api/PathTypeConversion.java index 04e14403c..260f4310b 100644 --- a/http-api/src/main/java/io/avaje/http/api/PathTypeConversion.java +++ b/http-api/src/main/java/io/avaje/http/api/PathTypeConversion.java @@ -28,8 +28,8 @@ public static String withDefault(String value, String defaultValue) { return value != null ? value : defaultValue; } - public static List withDefault(List value, String defaultValue) { - return value != null && !value.isEmpty() ? value : List.of(defaultValue); + public static List withDefault(List value, List defaultValue) { + return value != null && !value.isEmpty() ? value : defaultValue; } /** diff --git a/http-api/src/test/java/io/avaje/http/api/PathTypeConversionTest.java b/http-api/src/test/java/io/avaje/http/api/PathTypeConversionTest.java index 9f003f488..f682d09e7 100644 --- a/http-api/src/test/java/io/avaje/http/api/PathTypeConversionTest.java +++ b/http-api/src/test/java/io/avaje/http/api/PathTypeConversionTest.java @@ -22,7 +22,7 @@ void withDefault() { assertEquals("", PathTypeConversion.withDefault("", "myVal")); String nully = null; assertEquals("myVal", PathTypeConversion.withDefault(nully, "myVal")); - assertThat(PathTypeConversion.withDefault(List.of(), "myVal")).anyMatch(s -> "myVal".equals(s)); + assertThat(PathTypeConversion.withDefault(List.of(), List.of("myVal"))).anyMatch(s -> "myVal".equals(s)); } @Test diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientPlatformAdapter.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientPlatformAdapter.java index 2ebb2ae37..ffa6a9857 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientPlatformAdapter.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientPlatformAdapter.java @@ -65,6 +65,6 @@ public void writeReadCollectionParameter( Append writer, ParamType paramType, String paramName, - String paramDefault) { + List paramDefault) { } } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java index b45917b64..c39f81e74 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java @@ -2,6 +2,7 @@ import static io.avaje.http.generator.core.ParamType.RESPONSE_HANDLER; +import java.util.List; import java.util.Objects; import java.util.Optional; @@ -31,7 +32,7 @@ public class ElementReader { private ParamType paramType; private String matrixParamName; private boolean impliedParamType; - private String paramDefault; + private List paramDefault; private boolean notNullKotlin; private boolean isParamCollection; @@ -326,7 +327,7 @@ private boolean setValue(Append writer, PathSegments segments, String shortType) ctx.platform().writeReadCollectionParameter(writer, paramType, paramName); } } else if (hasParamDefault()) { - ctx.platform().writeReadParameter(writer, paramType, paramName, paramDefault); + ctx.platform().writeReadParameter(writer, paramType, paramName, paramDefault.get(0)); } else { final var checkNull = notNullKotlin || (paramType == ParamType.FORMPARAM && typeHandler.isPrimitive()); diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/PlatformAdapter.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/PlatformAdapter.java index ed072b3f2..a327deb92 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/PlatformAdapter.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/PlatformAdapter.java @@ -49,6 +49,6 @@ public interface PlatformAdapter { void writeReadCollectionParameter(Append writer, ParamType paramType, String paramName); - void writeReadCollectionParameter(Append writer, ParamType paramType, String paramName, String paramDefault); + void writeReadCollectionParameter(Append writer, ParamType paramType, String paramName, List paramDefault); } diff --git a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/HelidonPlatformAdapter.java b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/HelidonPlatformAdapter.java index e4bb8a975..213356c27 100644 --- a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/HelidonPlatformAdapter.java +++ b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/HelidonPlatformAdapter.java @@ -133,20 +133,20 @@ public void writeReadCollectionParameter(Append writer, ParamType paramType, Str @Override public void writeReadCollectionParameter( - Append writer, ParamType paramType, String paramName, String paramDefault) { + Append writer, ParamType paramType, String paramName, List paramDefault) { switch (paramType) { case QUERYPARAM: writer.append( - "withDefault(req.queryParams().all(\"%s\"), \"%s\")", paramName, paramDefault); + "withDefault(req.queryParams().all(\"%s\"), java.util.List.of(\"%s\"))", paramName, String.join(",", paramDefault)); break; case HEADER: writer.append( - "withDefault(req.headers().all(\"%s\"), \"%s\")", paramName, paramDefault); + "withDefault(req.headers().all(\"%s\"), java.util.List.of(\"%s\"))", paramName, String.join(",", paramDefault)); break; case COOKIE: writer.append( - "withDefault(req.headers().cookies().all(\"%s\"), \"%s\")", - paramName, paramDefault); + "withDefault(req.headers().cookies().all(\"%s\"), java.util.List.of\"%s\"))", paramName, String.join(",", paramDefault) + ); break; default: throw new UnsupportedOperationException("Unsupported MultiValue Parameter"); diff --git a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinAdapter.java b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinAdapter.java index c29d5f418..cceb05932 100644 --- a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinAdapter.java +++ b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinAdapter.java @@ -80,11 +80,11 @@ public void writeReadCollectionParameter(Append writer, ParamType paramType, Str @Override public void writeReadCollectionParameter( - Append writer, ParamType paramType, String paramName, String paramDefault) { + Append writer, ParamType paramType, String paramName, List paramDefault) { if (paramType != ParamType.QUERYPARAM) { throw new UnsupportedOperationException( "Only MultiValue Query Params are supported in Javalin"); } - writer.append("withDefault(ctx.queryParams(\"%s\"), \"%s\")", paramName, paramDefault); + writer.append("withDefault(ctx.queryParams(\"%s\"), java.util.List.of(\"%s\"))", paramName, String.join(",", paramDefault)); } } diff --git a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/JexAdapter.java b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/JexAdapter.java index 1438316a3..157fd6f0f 100644 --- a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/JexAdapter.java +++ b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/JexAdapter.java @@ -74,11 +74,11 @@ public void writeReadCollectionParameter(Append writer, ParamType paramType, Str @Override public void writeReadCollectionParameter( - Append writer, ParamType paramType, String paramName, String paramDefault) { + Append writer, ParamType paramType, String paramName, List paramDefault) { if (paramType != ParamType.QUERYPARAM) { throw new UnsupportedOperationException( "Only MultiValue Query Params are supported in Jex"); } - writer.append("withDefault(ctx.queryParams(\"%s\"), \"%s\")", paramName, paramDefault); + writer.append("withDefault(ctx.queryParams(\"%s\"), java.util.List.of(\"%s\"))", paramName, String.join(",", paramDefault)); } } diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/NimaPlatformAdapter.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/NimaPlatformAdapter.java index 2a5ae3e36..9903ca724 100644 --- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/NimaPlatformAdapter.java +++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/NimaPlatformAdapter.java @@ -127,20 +127,22 @@ public void writeReadCollectionParameter(Append writer, ParamType paramType, Str @Override public void writeReadCollectionParameter( - Append writer, ParamType paramType, String paramName, String paramDefault) { + Append writer, ParamType paramType, String paramName, List paramDefault) { switch (paramType) { case QUERYPARAM: writer.append( - "req.query().all(\"%s\", () -> java.util.List.of(\"%s\"))", paramName, paramDefault); + "req.query().all(\"%s\", () -> java.util.List.of(\"%s\"))", + paramName, String.join(",", paramDefault)); break; case HEADER: writer.append( - "req.headers().all(\"%s\", () -> java.util.List.of(\"%s\"))", paramName, paramDefault); + "req.headers().all(\"%s\", () -> java.util.List.of(\"%s\"))", + paramName, String.join(",", paramDefault)); break; case COOKIE: writer.append( "req.headers().cookies().all(\"%s\", () -> java.util.List.of(\"%s\"))", - paramName, paramDefault); + paramName, String.join(",", paramDefault)); break; default: throw new UnsupportedOperationException("Unsupported MultiValue Parameter"); From c61c161540f596697adf1d8b79755f27f0183129 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Mon, 27 Feb 2023 09:46:43 -0500 Subject: [PATCH 0633/1323] Update PathTypeConversion.java --- .../src/main/java/io/avaje/http/api/PathTypeConversion.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/http-api/src/main/java/io/avaje/http/api/PathTypeConversion.java b/http-api/src/main/java/io/avaje/http/api/PathTypeConversion.java index 260f4310b..b7f0e9301 100644 --- a/http-api/src/main/java/io/avaje/http/api/PathTypeConversion.java +++ b/http-api/src/main/java/io/avaje/http/api/PathTypeConversion.java @@ -52,11 +52,11 @@ private static void checkNull(String value) { } public static List list(Function func, List params) { - return params.stream().map(func).collect(Collectors.toList()); + return params.stream().filter(Objects::nonNull).map(func).collect(Collectors.toList()); } public static Set set(Function func, List params) { - return params.stream().map(func).collect(Collectors.toSet()); + return params.stream().filter(Objects::nonNull).map(func).collect(Collectors.toSet()); } /** Convert to int. */ From 46fca58e7836189dcc03cf991cda1873e34de6d1 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Mon, 27 Feb 2023 09:48:04 -0500 Subject: [PATCH 0634/1323] Update PathTypeConversion.java --- http-api/src/main/java/io/avaje/http/api/PathTypeConversion.java | 1 + 1 file changed, 1 insertion(+) diff --git a/http-api/src/main/java/io/avaje/http/api/PathTypeConversion.java b/http-api/src/main/java/io/avaje/http/api/PathTypeConversion.java index b7f0e9301..24640a01b 100644 --- a/http-api/src/main/java/io/avaje/http/api/PathTypeConversion.java +++ b/http-api/src/main/java/io/avaje/http/api/PathTypeConversion.java @@ -3,6 +3,7 @@ import java.math.BigDecimal; import java.time.*; import java.util.List; +import java.util.Objects; import java.util.Set; import java.util.UUID; import java.util.function.Function; From 676176e1c705b619bdf9fcc87a5121cb2cfe88f7 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Mon, 27 Feb 2023 11:36:24 -0500 Subject: [PATCH 0635/1323] support Map parameters --- .../client/ClientPlatformAdapter.java | 13 ---------- .../http/generator/core/ElementReader.java | 12 +++++++++- .../http/generator/core/PlatformAdapter.java | 15 +++++++++--- .../helidon/HelidonPlatformAdapter.java | 24 +++++++++++++++---- .../generator/javalin/JavalinAdapter.java | 9 +++++++ .../helidon/nima/NimaPlatformAdapter.java | 17 ++++++++++--- .../main/java/org/example/TestController.java | 10 +++++++- .../myapp/web/test/TestController2.java | 13 ++++++---- .../java/org/example/web/TestController.java | 5 ++-- .../main/java/org/example/TestController.java | 4 ++-- 10 files changed, 89 insertions(+), 33 deletions(-) diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientPlatformAdapter.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientPlatformAdapter.java index ffa6a9857..0880fe3c7 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientPlatformAdapter.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientPlatformAdapter.java @@ -54,17 +54,4 @@ public void writeReadParameter(Append writer, ParamType paramType, String paramN public void writeReadParameter(Append writer, ParamType paramType, String paramName, String paramDefault) { } - - @Override - public void writeReadCollectionParameter( - Append writer, ParamType paramType, String paramName) { - } - - @Override - public void writeReadCollectionParameter( - Append writer, - ParamType paramType, - String paramName, - List paramDefault) { - } } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java index c39f81e74..143f0878c 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java @@ -36,7 +36,8 @@ public class ElementReader { private boolean notNullKotlin; private boolean isParamCollection; - //private boolean notNullJavax; + private boolean isParamMap; + // private boolean notNullJavax; ElementReader(Element element, ProcessingContext ctx, ParamType defaultType, boolean formMarker) { this(element, null, Util.typeDef(element.asType()), ctx, defaultType, formMarker); @@ -90,6 +91,9 @@ TypeHandler initTypeHandler() { .filter(t -> t.isGeneric() && !t.mainType().startsWith("java.util.Map")) .isPresent(); + final var isMap = + !isCollection && typeOp.filter(t -> t.mainType().startsWith("java.util.Map")).isPresent(); + if (mainTypeEnum) { return TypeMap.enumParamHandler(type); } else if (isCollection) { @@ -102,6 +106,10 @@ TypeHandler initTypeHandler() { .isPresent(); return TypeMap.collectionHandler(typeOp.orElseThrow(), isEnumCollection); + } else if (isMap) { + this.isParamMap = true; + + return new TypeMap.StringHandler(); } } @@ -326,6 +334,8 @@ private boolean setValue(Append writer, PathSegments segments, String shortType) } else { ctx.platform().writeReadCollectionParameter(writer, paramType, paramName); } + } else if (isParamMap) { + ctx.platform().writeReadMapParameter(writer, paramType); } else if (hasParamDefault()) { ctx.platform().writeReadParameter(writer, paramType, paramName, paramDefault.get(0)); } else { diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/PlatformAdapter.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/PlatformAdapter.java index a327deb92..5f71734b0 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/PlatformAdapter.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/PlatformAdapter.java @@ -45,10 +45,19 @@ public interface PlatformAdapter { void writeReadParameter(Append writer, ParamType paramType, String paramName); - void writeReadParameter(Append writer, ParamType paramType, String paramName, String paramDefault); + void writeReadParameter( + Append writer, ParamType paramType, String paramName, String paramDefault); - void writeReadCollectionParameter(Append writer, ParamType paramType, String paramName); + default void writeReadMapParameter(Append writer, ParamType paramType) { + throw new UnsupportedOperationException("Unsupported Map Parameter"); + } - void writeReadCollectionParameter(Append writer, ParamType paramType, String paramName, List paramDefault); + default void writeReadCollectionParameter(Append writer, ParamType paramType, String paramName) { + throw new UnsupportedOperationException("Unsupported MultiValue Parameter"); + } + default void writeReadCollectionParameter( + Append writer, ParamType paramType, String paramName, List paramDefault) { + throw new UnsupportedOperationException("Unsupported MultiValue Parameter"); + } } diff --git a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/HelidonPlatformAdapter.java b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/HelidonPlatformAdapter.java index 213356c27..62a569b11 100644 --- a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/HelidonPlatformAdapter.java +++ b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/HelidonPlatformAdapter.java @@ -114,6 +114,20 @@ public void writeReadParameter(Append writer, ParamType paramType, String paramN } } + @Override + public void writeReadMapParameter(Append writer, ParamType paramType) { + switch (paramType) { + case QUERYPARAM: + writer.append("req.queryParams().toMap()"); + break; + case COOKIE: + writer.append("req.headers().cookies().toMap()"); + break; + default: + throw new UnsupportedOperationException("Unsupported Map Parameter"); + } + } + @Override public void writeReadCollectionParameter(Append writer, ParamType paramType, String paramName) { switch (paramType) { @@ -137,16 +151,18 @@ public void writeReadCollectionParameter( switch (paramType) { case QUERYPARAM: writer.append( - "withDefault(req.queryParams().all(\"%s\"), java.util.List.of(\"%s\"))", paramName, String.join(",", paramDefault)); + "withDefault(req.queryParams().all(\"%s\"), java.util.List.of(\"%s\"))", + paramName, String.join(",", paramDefault)); break; case HEADER: writer.append( - "withDefault(req.headers().all(\"%s\"), java.util.List.of(\"%s\"))", paramName, String.join(",", paramDefault)); + "withDefault(req.headers().all(\"%s\"), java.util.List.of(\"%s\"))", + paramName, String.join(",", paramDefault)); break; case COOKIE: writer.append( - "withDefault(req.headers().cookies().all(\"%s\"), java.util.List.of\"%s\"))", paramName, String.join(",", paramDefault) - ); + "withDefault(req.headers().cookies().all(\"%s\"), java.util.List.of\"%s\"))", + paramName, String.join(",", paramDefault)); break; default: throw new UnsupportedOperationException("Unsupported MultiValue Parameter"); diff --git a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinAdapter.java b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinAdapter.java index cceb05932..f7fba9b85 100644 --- a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinAdapter.java +++ b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinAdapter.java @@ -69,6 +69,15 @@ public void writeReadParameter( writer.append("withDefault(ctx.%s(\"%s\"), \"%s\")", paramType, paramName, paramDefault); } + @Override + public void writeReadMapParameter(Append writer, ParamType paramType) { + if (paramType != ParamType.QUERYPARAM) { + throw new UnsupportedOperationException( + "Only Query Params have Map> supported in Javalin"); + } + writer.append("ctx.queryParamMap()"); + } + @Override public void writeReadCollectionParameter(Append writer, ParamType paramType, String paramName) { if (paramType != ParamType.QUERYPARAM) { diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/NimaPlatformAdapter.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/NimaPlatformAdapter.java index 9903ca724..72ee72a59 100644 --- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/NimaPlatformAdapter.java +++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/NimaPlatformAdapter.java @@ -100,14 +100,25 @@ public void writeReadParameter(Append writer, ParamType paramType, String paramN case COOKIE: writer.append("req.headers().cookies().first(\"%s\").orElse(\"%s\")", paramName, paramDefault); break; - case BODY: - case BEANPARAM: - case FORM: default: writer.append("null // TODO req.%s().param(\"%s\")", paramType.type(), paramName); } } + @Override + public void writeReadMapParameter(Append writer, ParamType paramType) { + switch (paramType) { + case QUERYPARAM: + writer.append("req.query().toMap()"); + break; + case COOKIE: + writer.append("req.headers().cookies().toMap()"); + break; + default: + throw new UnsupportedOperationException("Unsupported Map Parameter"); + } + } + @Override public void writeReadCollectionParameter(Append writer, ParamType paramType, String paramName) { switch (paramType) { diff --git a/tests/test-helidon/src/main/java/org/example/TestController.java b/tests/test-helidon/src/main/java/org/example/TestController.java index 8c40b29ab..04ba98201 100644 --- a/tests/test-helidon/src/main/java/org/example/TestController.java +++ b/tests/test-helidon/src/main/java/org/example/TestController.java @@ -1,8 +1,11 @@ package org.example; +import java.util.List; +import java.util.Map; import java.util.Set; import io.avaje.http.api.Controller; +import io.avaje.http.api.Cookie; import io.avaje.http.api.Default; import io.avaje.http.api.Get; import io.avaje.http.api.Path; @@ -24,7 +27,7 @@ String enumQuery(@QueryParam @Default("FFA") ServerType type) { } @Get("/enumQuery2") - String enumMultiQuery(@QueryParam @Default("FFA") Set type) { + String enumMultiQuery(@QueryParam @Default({"FFA", "PROXY"}) Set type) { return type.toString(); } @@ -32,4 +35,9 @@ String enumMultiQuery(@QueryParam @Default("FFA") Set type) { String enumQueryImplied(String s, @QueryParam ServerType type) { return type.name(); } + + @Get("/mapTest") + String mapTest(Map> strings, @Cookie Map> cookie) { + return strings.toString(); + } } diff --git a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController2.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController2.java index daaf6204e..0de341637 100644 --- a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController2.java +++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController2.java @@ -1,9 +1,9 @@ package org.example.myapp.web.test; +import java.util.List; +import java.util.Map; import java.util.Set; -import org.example.myapp.web.HelloDto; - import io.avaje.http.api.Controller; import io.avaje.http.api.Default; import io.avaje.http.api.Form; @@ -34,12 +34,17 @@ String enumQuery(@QueryParam @Default("FFA") ServerType type) { } @Get("/enumQuery2") - String enumMultiQuery(@QueryParam @Default("FFA") Set type) { + String enumMultiQuery(@QueryParam @Default({"FFA", "PROXY"}) Set type) { return type.toString(); } @Post("/enumQueryImplied") - String enumQueryImplied(HelloDto s, ServerType type) { + String enumQueryImplied(String s, @QueryParam ServerType type) { return type.name(); } + + @Get("/mapTest") + String mapTest(Map> strings) { + return strings.toString(); + } } diff --git a/tests/test-jex/src/main/java/org/example/web/TestController.java b/tests/test-jex/src/main/java/org/example/web/TestController.java index ffc6c28b5..69fe686e7 100644 --- a/tests/test-jex/src/main/java/org/example/web/TestController.java +++ b/tests/test-jex/src/main/java/org/example/web/TestController.java @@ -24,12 +24,13 @@ String enumQuery(@QueryParam @Default("FFA") ServerType type) { } @Get("/enumQuery2") - String enumMultiQuery(@QueryParam @Default("FFA") Set type) { + String enumMultiQuery(@QueryParam @Default({"FFA", "PROXY"}) Set type) { return type.toString(); } @Post("/enumQueryImplied") - String enumQueryImplied(HelloDto s, @QueryParam ServerType type) { + String enumQueryImplied(String s, @QueryParam ServerType type) { return type.name(); } + } diff --git a/tests/test-nima-jsonb/src/main/java/org/example/TestController.java b/tests/test-nima-jsonb/src/main/java/org/example/TestController.java index d9728fc38..1679dad1d 100644 --- a/tests/test-nima-jsonb/src/main/java/org/example/TestController.java +++ b/tests/test-nima-jsonb/src/main/java/org/example/TestController.java @@ -37,12 +37,12 @@ String enumQuery(@QueryParam @Default("FFA") ServerType type) { } @Get("/enumQuery2") - String enumMultiQuery(@QueryParam @Default("FFA") Set type) { + String enumMultiQuery(@QueryParam @Default({"FFA", "PROXY"}) Set type) { return type.toString(); } @Post("/enumQueryImplied") - String enumQueryImplied(Person s, @QueryParam ServerType type) { + String enumQueryImplied(String s, @QueryParam ServerType type) { return type.name(); } } From 8788cf1288096840c877b2f2597baae42dcab46e Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Mon, 27 Feb 2023 11:42:36 -0500 Subject: [PATCH 0636/1323] Update ElementReader.java --- .../main/java/io/avaje/http/generator/core/ElementReader.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java index 143f0878c..f61e2f932 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java @@ -246,7 +246,7 @@ void writeParamName(Append writer) { * Build the OpenAPI documentation for this parameter. */ void buildApiDocumentation(MethodDocBuilder methodDoc) { - if (!isPlatformContext()) { + if (!isPlatformContext() && !isParamMap) { new MethodParamDocBuilder(methodDoc, this).build(); } } From 35ff831cc5b337cbc5eb986235aa2d3d35ba6a3a Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Mon, 27 Feb 2023 23:34:09 -0500 Subject: [PATCH 0637/1323] Update PathTypeConversion.java --- .../src/main/java/io/avaje/http/api/PathTypeConversion.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/http-api/src/main/java/io/avaje/http/api/PathTypeConversion.java b/http-api/src/main/java/io/avaje/http/api/PathTypeConversion.java index 24640a01b..260f4310b 100644 --- a/http-api/src/main/java/io/avaje/http/api/PathTypeConversion.java +++ b/http-api/src/main/java/io/avaje/http/api/PathTypeConversion.java @@ -3,7 +3,6 @@ import java.math.BigDecimal; import java.time.*; import java.util.List; -import java.util.Objects; import java.util.Set; import java.util.UUID; import java.util.function.Function; @@ -53,11 +52,11 @@ private static void checkNull(String value) { } public static List list(Function func, List params) { - return params.stream().filter(Objects::nonNull).map(func).collect(Collectors.toList()); + return params.stream().map(func).collect(Collectors.toList()); } public static Set set(Function func, List params) { - return params.stream().filter(Objects::nonNull).map(func).collect(Collectors.toSet()); + return params.stream().map(func).collect(Collectors.toSet()); } /** Convert to int. */ From 86c6e4426bf20a68e843a28c4085fdb299637b4e Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Tue, 28 Feb 2023 00:11:00 -0500 Subject: [PATCH 0638/1323] forgot that multivalue headers are basically csvs --- .../main/java/io/avaje/http/client/DHttpClientRequest.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/http-client/src/main/java/io/avaje/http/client/DHttpClientRequest.java b/http-client/src/main/java/io/avaje/http/client/DHttpClientRequest.java index a670f5495..301ee2b4a 100644 --- a/http-client/src/main/java/io/avaje/http/client/DHttpClientRequest.java +++ b/http-client/src/main/java/io/avaje/http/client/DHttpClientRequest.java @@ -16,6 +16,7 @@ import java.util.*; import java.util.concurrent.CompletableFuture; import java.util.function.Supplier; +import java.util.stream.Collectors; import java.util.stream.Stream; import static java.net.http.HttpResponse.BodyHandlers.discarding; @@ -124,13 +125,11 @@ public HttpClientRequest header(String name, String value) { } @Override + @SuppressWarnings("unchecked") public HttpClientRequest header(String name, Object value) { if (value instanceof Collection) { - for (final var e : (Collection) value) { - header(name, e); - } - return this; + value = ((Collection) value).stream().map(Object::toString).collect(Collectors.joining(",")); } return value != null ? header(name, value.toString()) : this; From b986771e734eb40faf151f14512f7948ebbbc962 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Tue, 28 Feb 2023 00:52:11 -0500 Subject: [PATCH 0639/1323] actually test client changes --- .../avaje/http/client/DHttpClientRequest.java | 14 +++++++- .../avaje/http/client/HttpClientRequest.java | 10 ++++++ .../http/client/DHttpClientRequestTest.java | 34 +++++++++++++++++-- 3 files changed, 55 insertions(+), 3 deletions(-) diff --git a/http-client/src/main/java/io/avaje/http/client/DHttpClientRequest.java b/http-client/src/main/java/io/avaje/http/client/DHttpClientRequest.java index 301ee2b4a..054ebe00f 100644 --- a/http-client/src/main/java/io/avaje/http/client/DHttpClientRequest.java +++ b/http-client/src/main/java/io/avaje/http/client/DHttpClientRequest.java @@ -124,12 +124,24 @@ public HttpClientRequest header(String name, String value) { return this; } + @Override + public HttpClientRequest header(String name, Collection value) { + if (headers == null) { + headers = new LinkedHashMap<>(); + } + headers.computeIfAbsent(name, s -> new ArrayList<>()).addAll(value); + return this; + } + @Override @SuppressWarnings("unchecked") public HttpClientRequest header(String name, Object value) { if (value instanceof Collection) { - value = ((Collection) value).stream().map(Object::toString).collect(Collectors.joining(",")); + final var headerList = + ((Collection) value).stream().map(Object::toString).collect(Collectors.toList()); + + return header(name, headerList); } return value != null ? header(name, value.toString()) : this; diff --git a/http-client/src/main/java/io/avaje/http/client/HttpClientRequest.java b/http-client/src/main/java/io/avaje/http/client/HttpClientRequest.java index db1f14ff8..55ad84ef2 100644 --- a/http-client/src/main/java/io/avaje/http/client/HttpClientRequest.java +++ b/http-client/src/main/java/io/avaje/http/client/HttpClientRequest.java @@ -5,6 +5,7 @@ import java.net.http.HttpResponse; import java.nio.file.Path; import java.time.Duration; +import java.util.Collection; import java.util.List; import java.util.Map; import java.util.function.Supplier; @@ -126,6 +127,15 @@ public interface HttpClientRequest { */ HttpClientRequest header(Map headers); + /** + * Add the headers to the request via Collection. + * + * @param name The header name + * @param value The header values + * @return The request being built + */ + HttpClientRequest header(String name, Collection value); + /** * Return the header values that have been set for the given header name. * diff --git a/http-client/src/test/java/io/avaje/http/client/DHttpClientRequestTest.java b/http-client/src/test/java/io/avaje/http/client/DHttpClientRequestTest.java index f771785c9..11ea00279 100644 --- a/http-client/src/test/java/io/avaje/http/client/DHttpClientRequestTest.java +++ b/http-client/src/test/java/io/avaje/http/client/DHttpClientRequestTest.java @@ -1,10 +1,11 @@ package io.avaje.http.client; -import org.junit.jupiter.api.Test; +import static org.assertj.core.api.Assertions.assertThat; import java.time.Duration; +import java.util.List; -import static org.assertj.core.api.Assertions.assertThat; +import org.junit.jupiter.api.Test; class DHttpClientRequestTest { @@ -21,6 +22,35 @@ void suppressLogging_listenerEvent_expect_suppressedPayloadContent() { assertThat(event.responseBody()).isEqualTo(""); } + @Test + void assertHeader() { + final var request = new DHttpClientRequest(context, Duration.ZERO); + + final var headers = + request + .header("Accept", (Object) List.of("application/json", "application/json2")) + .header("Accept"); + + assertThat(headers).asList().contains("application/json", "application/json2"); + } + + @Test + void assertQuery() { + final var client = HttpClient.builder().baseUrl("https://ap7i.github.com").build(); + + final var uri = + client + .request() + .queryParam("param", List.of("param1", "param2")) + .HEAD() + .asDiscarding() + .request() + .uri() + .toString(); + + assertThat(uri).isEqualTo("https://ap7i.github.com?param=param1¶m=param2"); + } + @Test void skipAuthToken_listenerEvent_expect_suppressedPayloadContent() { final DHttpClientRequest request = new DHttpClientRequest(context, Duration.ZERO); From 37c086c3d500d1e0cc5a17312f2c074a778b75ec Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Tue, 28 Feb 2023 11:17:57 -0500 Subject: [PATCH 0640/1323] add request Timeout --- .../io/avaje/http/api/RequestTimeout.java | 29 +++++++++++++++++++ http-client/pom.xml | 2 +- .../generator/client/ClientMethodWriter.java | 13 +++++++-- .../generator/client/ClientProcessor.java | 23 ++++----------- .../http/generator/core/MethodReader.java | 12 +++++++- .../http/generator/core/package-info.java | 1 + 6 files changed, 58 insertions(+), 22 deletions(-) create mode 100644 http-api/src/main/java/io/avaje/http/api/RequestTimeout.java diff --git a/http-api/src/main/java/io/avaje/http/api/RequestTimeout.java b/http-api/src/main/java/io/avaje/http/api/RequestTimeout.java new file mode 100644 index 000000000..201b21865 --- /dev/null +++ b/http-api/src/main/java/io/avaje/http/api/RequestTimeout.java @@ -0,0 +1,29 @@ +package io.avaje.http.api; + +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; +import java.time.temporal.ChronoUnit; + +/** + * Overrides global request timeout for this endpoint. + * + *
{@code
+ * @Client
+ * interface CustomerApi {
+ *   @Get("/{id}")
+ *   @RequestTimeout(value = 1, ChronoUnit.SECONDS)
+ *   Customer getById(long id);
+ * }
+ *
+ * }
+ */ +@Target(METHOD) +@Retention(RUNTIME) +public @interface RequestTimeout { + long value(); + + ChronoUnit chronoUnit() default ChronoUnit.MILLIS; +} diff --git a/http-client/pom.xml b/http-client/pom.xml index 8fffadfe2..1eb33af63 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -83,7 +83,7 @@ io.avaje avaje-http-api - 1.20 + ${project.version} test diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java index dc76753d6..21024ffee 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java @@ -3,6 +3,7 @@ import io.avaje.http.generator.core.*; import javax.lang.model.element.TypeElement; +import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; @@ -24,6 +25,7 @@ class ClientMethodWriter { private MethodParam bodyHandlerParam; private String methodGenericParams = ""; private final boolean useJsonb; + private final Optional timeout; ClientMethodWriter(MethodReader method, Append writer, ProcessingContext ctx, boolean useJsonb) { this.method = method; @@ -32,6 +34,7 @@ class ClientMethodWriter { this.ctx = ctx; this.returnType = Util.parseType(method.returnType()); this.useJsonb = useJsonb; + this.timeout = method.timeout(); } void addImportTypes(ControllerReader reader) { @@ -83,6 +86,7 @@ void write() { writeHeaders(); writePaths(segments); + timeout.ifPresent(this::writeTimeout); writeQueryParams(pathSegments); writeBeanParams(pathSegments); writeFormParams(pathSegments); @@ -90,8 +94,13 @@ void write() { writeEnd(); } - private void writeEnd() { - WebMethod webMethod = method.webMethod(); + private void writeTimeout(RequestTimeoutPrism p) { + + writer.append(" .requestTimeout(of(%s, %s))", p.value(), p.chronoUnit()).eol(); + } + +private void writeEnd() { + final var webMethod = method.webMethod(); writer.append(" .%s()", webMethod.name()).eol(); if (returnType == UType.VOID) { writer.append(" .asVoid();").eol(); diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java index bbdd20e7f..c632a8e29 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java @@ -3,7 +3,7 @@ import java.io.IOException; import java.io.Writer; import java.util.LinkedHashSet; -import java.util.List; +import java.util.Objects; import java.util.Set; import javax.annotation.processing.AbstractProcessor; @@ -11,8 +11,6 @@ import javax.annotation.processing.RoundEnvironment; import javax.annotation.processing.SupportedAnnotationTypes; import javax.lang.model.SourceVersion; -import javax.lang.model.element.AnnotationMirror; -import javax.lang.model.element.AnnotationValue; import javax.lang.model.element.Element; import javax.lang.model.element.TypeElement; import javax.tools.FileObject; @@ -84,22 +82,11 @@ private void writeServicesFile() { } private void writeForImported(Element importedElement) { - for (AnnotationMirror annotationMirror : importedElement.getAnnotationMirrors()) { - for (AnnotationValue value : annotationMirror.getElementValues().values()) { - for (Object apiClassDef : (List) value.getValue()) { - writeImported(apiClassDef.toString()); - } - } - } - } - private void writeImported(String fullName) { - // trim .class suffix - String apiClassName = fullName.substring(0, fullName.length() - 6); - TypeElement typeElement = ctx.typeElement(apiClassName); - if (typeElement != null) { - writeClient(typeElement); - } + ImportPrism.getInstanceOn(importedElement).types().stream() + .map(ctx::asElement) + .filter(Objects::nonNull) + .forEach(this::writeClient); } private void writeClient(Element controller) { diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java index 1920a42f2..5a04dc2c1 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java @@ -37,6 +37,7 @@ public class MethodReader { private final PathSegments pathSegments; private final boolean hasValid; private final List superMethods; + private final Optional timeout; private WebMethod webMethod; private String webMethodPath; @@ -59,7 +60,12 @@ public class MethodReader { this.apiResponses = buildApiResponses(); this.javadoc = buildJavadoc(element, ctx); - + this.timeout = RequestTimeoutPrism.getOptionalOn(element); + timeout.ifPresent( + p -> { + bean.addStaticImportType("java.time.temporal.ChronoUnit." + p.chronoUnit()); + bean.addStaticImportType("java.time.Duration.of"); + }); if (isWebMethod()) { this.hasValid = initValid(); this.pathSegments = PathSegments.parse(Util.combinePath(bean.path(), webMethodPath)); @@ -325,4 +331,8 @@ public String bodyName() { } return "body"; } + + public Optional timeout() { + return timeout; + } } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/package-info.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/package-info.java index 9fac10bcd..216bc0bee 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/package-info.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/package-info.java @@ -27,6 +27,7 @@ @GeneratePrism(value = org.jetbrains.annotations.NotNull.class, publicAccess = true) @GeneratePrism(value = io.avaje.http.api.Client.class, publicAccess = true) @GeneratePrism(value = io.avaje.http.api.Client.Import.class, publicAccess = true) +@GeneratePrism(value = io.avaje.http.api.RequestTimeout.class, publicAccess = true) package io.avaje.http.generator.core; import io.avaje.prism.GeneratePrism; From df18f10d3e450a29a03663a57e8419028b9b5de0 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Tue, 28 Feb 2023 11:26:37 -0500 Subject: [PATCH 0641/1323] Update ClientMethodWriter.java --- .../java/io/avaje/http/generator/client/ClientMethodWriter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java index 21024ffee..3c55cf7a3 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java @@ -86,10 +86,10 @@ void write() { writeHeaders(); writePaths(segments); - timeout.ifPresent(this::writeTimeout); writeQueryParams(pathSegments); writeBeanParams(pathSegments); writeFormParams(pathSegments); + timeout.ifPresent(this::writeTimeout); writeBody(); writeEnd(); } From 7061f4ca7fb9d1f3713ce35e46cd270ff0fdea66 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Tue, 28 Feb 2023 14:16:48 -0500 Subject: [PATCH 0642/1323] final thing, query param method --- .../java/io/avaje/http/client/HttpClientRequest.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/http-client/src/main/java/io/avaje/http/client/HttpClientRequest.java b/http-client/src/main/java/io/avaje/http/client/HttpClientRequest.java index 55ad84ef2..0040eb7a4 100644 --- a/http-client/src/main/java/io/avaje/http/client/HttpClientRequest.java +++ b/http-client/src/main/java/io/avaje/http/client/HttpClientRequest.java @@ -237,6 +237,17 @@ public interface HttpClientRequest { */ HttpClientRequest queryParam(String name, Object value); + /** + * Add a collection query parameters associated with a single key + * + * @param name The name of the query parameter + * @param values The values of the query parameter which can be null + * @return The request being built + */ + default HttpClientRequest queryParam(String name, Collection value) { + return queryParam(name, (Object) value); + } + /** * Add a multiple query parameters as name value map. * From 4f0a1474c684f5496fcd3d4999a852297d70c45b Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Tue, 28 Feb 2023 14:23:51 -0500 Subject: [PATCH 0643/1323] test --- .../io/avaje/http/client/HelloControllerTest.java | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/http-client/src/test/java/io/avaje/http/client/HelloControllerTest.java b/http-client/src/test/java/io/avaje/http/client/HelloControllerTest.java index 1bf3bbea2..69d3790e0 100644 --- a/http-client/src/test/java/io/avaje/http/client/HelloControllerTest.java +++ b/http-client/src/test/java/io/avaje/http/client/HelloControllerTest.java @@ -31,6 +31,8 @@ class HelloControllerTest extends BaseWebTest { private static final ObjectMapper objectMapper = new ObjectMapper(); final HttpClientContext clientContext = client(); + + String nullString = null; @Test void newClientTest() { @@ -801,7 +803,7 @@ void async_list_as() throws ExecutionException, InterruptedException { void get_withPathParamAndQueryParam_returningBean() { final HelloDto dto = clientContext.request() - .path("hello/43/2020-03-05").queryParam("otherParam", "other").queryParam("foo", null) + .path("hello/43/2020-03-05").queryParam("otherParam", "other").queryParam("foo", nullString) .GET() .bean(HelloDto.class); @@ -813,7 +815,7 @@ void get_withPathParamAndQueryParam_returningBean() { @Test void callBean() { final HelloDto dto = clientContext.request() - .path("hello/43/2020-03-05").queryParam("otherParam", "other").queryParam("foo", null) + .path("hello/43/2020-03-05").queryParam("otherParam", "other").queryParam("foo", (String) null) .GET() .call().bean(HelloDto.class).execute(); @@ -825,7 +827,7 @@ void callBean() { @Test void callBeanAsync() throws ExecutionException, InterruptedException { final CompletableFuture future = clientContext.request() - .path("hello/43/2020-03-05").queryParam("otherParam", "other").queryParam("foo", null) + .path("hello/43/2020-03-05").queryParam("otherParam", "other").queryParam("foo", (String) null) .GET() .call().bean(HelloDto.class).async(); @@ -842,7 +844,7 @@ void async_whenComplete_returningBean() throws ExecutionException, InterruptedEx final AtomicReference ref = new AtomicReference<>(); final CompletableFuture future = clientContext.request() - .path("hello/43/2020-03-05").queryParam("otherParam", "other").queryParam("foo", null) + .path("hello/43/2020-03-05").queryParam("otherParam", "other").queryParam("foo", nullString) .GET() .async().bean(HelloDto.class); @@ -872,7 +874,7 @@ void async_whenComplete_returningBeanWithHeaders() throws ExecutionException, In final AtomicReference> ref = new AtomicReference<>(); final CompletableFuture> future = clientContext.request() - .path("hello/43/2020-03-05").queryParam("otherParam", "other").queryParam("foo", null) + .path("hello/43/2020-03-05").queryParam("otherParam", "other").queryParam("foo", nullString) .GET() .async().as(HelloDto.class); From a4f04f2316715cdfc1f0e652c33b8bef4b1d5d2e Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Tue, 28 Feb 2023 14:26:39 -0500 Subject: [PATCH 0644/1323] Revert "final thing, query param method" This reverts commit 7061f4ca7fb9d1f3713ce35e46cd270ff0fdea66. --- .../java/io/avaje/http/client/HttpClientRequest.java | 11 ----------- .../io/avaje/http/client/HelloControllerTest.java | 12 +++++------- 2 files changed, 5 insertions(+), 18 deletions(-) diff --git a/http-client/src/main/java/io/avaje/http/client/HttpClientRequest.java b/http-client/src/main/java/io/avaje/http/client/HttpClientRequest.java index 0040eb7a4..55ad84ef2 100644 --- a/http-client/src/main/java/io/avaje/http/client/HttpClientRequest.java +++ b/http-client/src/main/java/io/avaje/http/client/HttpClientRequest.java @@ -237,17 +237,6 @@ public interface HttpClientRequest { */ HttpClientRequest queryParam(String name, Object value); - /** - * Add a collection query parameters associated with a single key - * - * @param name The name of the query parameter - * @param values The values of the query parameter which can be null - * @return The request being built - */ - default HttpClientRequest queryParam(String name, Collection value) { - return queryParam(name, (Object) value); - } - /** * Add a multiple query parameters as name value map. * diff --git a/http-client/src/test/java/io/avaje/http/client/HelloControllerTest.java b/http-client/src/test/java/io/avaje/http/client/HelloControllerTest.java index 69d3790e0..1bf3bbea2 100644 --- a/http-client/src/test/java/io/avaje/http/client/HelloControllerTest.java +++ b/http-client/src/test/java/io/avaje/http/client/HelloControllerTest.java @@ -31,8 +31,6 @@ class HelloControllerTest extends BaseWebTest { private static final ObjectMapper objectMapper = new ObjectMapper(); final HttpClientContext clientContext = client(); - - String nullString = null; @Test void newClientTest() { @@ -803,7 +801,7 @@ void async_list_as() throws ExecutionException, InterruptedException { void get_withPathParamAndQueryParam_returningBean() { final HelloDto dto = clientContext.request() - .path("hello/43/2020-03-05").queryParam("otherParam", "other").queryParam("foo", nullString) + .path("hello/43/2020-03-05").queryParam("otherParam", "other").queryParam("foo", null) .GET() .bean(HelloDto.class); @@ -815,7 +813,7 @@ void get_withPathParamAndQueryParam_returningBean() { @Test void callBean() { final HelloDto dto = clientContext.request() - .path("hello/43/2020-03-05").queryParam("otherParam", "other").queryParam("foo", (String) null) + .path("hello/43/2020-03-05").queryParam("otherParam", "other").queryParam("foo", null) .GET() .call().bean(HelloDto.class).execute(); @@ -827,7 +825,7 @@ void callBean() { @Test void callBeanAsync() throws ExecutionException, InterruptedException { final CompletableFuture future = clientContext.request() - .path("hello/43/2020-03-05").queryParam("otherParam", "other").queryParam("foo", (String) null) + .path("hello/43/2020-03-05").queryParam("otherParam", "other").queryParam("foo", null) .GET() .call().bean(HelloDto.class).async(); @@ -844,7 +842,7 @@ void async_whenComplete_returningBean() throws ExecutionException, InterruptedEx final AtomicReference ref = new AtomicReference<>(); final CompletableFuture future = clientContext.request() - .path("hello/43/2020-03-05").queryParam("otherParam", "other").queryParam("foo", nullString) + .path("hello/43/2020-03-05").queryParam("otherParam", "other").queryParam("foo", null) .GET() .async().bean(HelloDto.class); @@ -874,7 +872,7 @@ void async_whenComplete_returningBeanWithHeaders() throws ExecutionException, In final AtomicReference> ref = new AtomicReference<>(); final CompletableFuture> future = clientContext.request() - .path("hello/43/2020-03-05").queryParam("otherParam", "other").queryParam("foo", nullString) + .path("hello/43/2020-03-05").queryParam("otherParam", "other").queryParam("foo", null) .GET() .async().as(HelloDto.class); From e1c35467f3b56f01bec1e525a92dfbce3c368f0e Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Tue, 28 Feb 2023 22:59:11 -0500 Subject: [PATCH 0645/1323] multival client --- .../avaje/http/client/DHttpClientRequest.java | 19 +++++++++++ .../avaje/http/client/HttpClientRequest.java | 10 ++++++ .../java/io/avaje/http/client/UrlBuilder.java | 9 +++++ .../http/client/DHttpClientRequestTest.java | 34 +++++++++++++++++-- 4 files changed, 70 insertions(+), 2 deletions(-) diff --git a/http-client/src/main/java/io/avaje/http/client/DHttpClientRequest.java b/http-client/src/main/java/io/avaje/http/client/DHttpClientRequest.java index dc468d631..054ebe00f 100644 --- a/http-client/src/main/java/io/avaje/http/client/DHttpClientRequest.java +++ b/http-client/src/main/java/io/avaje/http/client/DHttpClientRequest.java @@ -16,6 +16,7 @@ import java.util.*; import java.util.concurrent.CompletableFuture; import java.util.function.Supplier; +import java.util.stream.Collectors; import java.util.stream.Stream; import static java.net.http.HttpResponse.BodyHandlers.discarding; @@ -124,7 +125,25 @@ public HttpClientRequest header(String name, String value) { } @Override + public HttpClientRequest header(String name, Collection value) { + if (headers == null) { + headers = new LinkedHashMap<>(); + } + headers.computeIfAbsent(name, s -> new ArrayList<>()).addAll(value); + return this; + } + + @Override + @SuppressWarnings("unchecked") public HttpClientRequest header(String name, Object value) { + + if (value instanceof Collection) { + final var headerList = + ((Collection) value).stream().map(Object::toString).collect(Collectors.toList()); + + return header(name, headerList); + } + return value != null ? header(name, value.toString()) : this; } diff --git a/http-client/src/main/java/io/avaje/http/client/HttpClientRequest.java b/http-client/src/main/java/io/avaje/http/client/HttpClientRequest.java index 22cc04417..246a78a9d 100644 --- a/http-client/src/main/java/io/avaje/http/client/HttpClientRequest.java +++ b/http-client/src/main/java/io/avaje/http/client/HttpClientRequest.java @@ -5,6 +5,7 @@ import java.net.http.HttpResponse; import java.nio.file.Path; import java.time.Duration; +import java.util.Collection; import java.util.List; import java.util.Map; import java.util.function.Supplier; @@ -125,6 +126,15 @@ public interface HttpClientRequest { */ HttpClientRequest header(Map headers); + /** + * Add the headers to the request via Collection. + * + * @param name The header name + * @param value The header values + * @return The request being built + */ + HttpClientRequest header(String name, Collection value); + /** * Return the header values that have been set for the given header name. * diff --git a/http-client/src/main/java/io/avaje/http/client/UrlBuilder.java b/http-client/src/main/java/io/avaje/http/client/UrlBuilder.java index 40e82d787..2ed93e78d 100644 --- a/http-client/src/main/java/io/avaje/http/client/UrlBuilder.java +++ b/http-client/src/main/java/io/avaje/http/client/UrlBuilder.java @@ -2,6 +2,7 @@ import java.net.URLEncoder; import java.nio.charset.StandardCharsets; +import java.util.Collection; import java.util.Map; /** @@ -84,6 +85,14 @@ public UrlBuilder queryParam(String name, String value) { * The name and value parameters are url encoded. */ public UrlBuilder queryParam(String name, Object value) { + + if (value instanceof Collection) { + for (var e : (Collection) value) { + queryParam(name, e); + } + return this; + } + if (value != null) { addQueryParam(name, value.toString()); } diff --git a/http-client/src/test/java/io/avaje/http/client/DHttpClientRequestTest.java b/http-client/src/test/java/io/avaje/http/client/DHttpClientRequestTest.java index f771785c9..11ea00279 100644 --- a/http-client/src/test/java/io/avaje/http/client/DHttpClientRequestTest.java +++ b/http-client/src/test/java/io/avaje/http/client/DHttpClientRequestTest.java @@ -1,10 +1,11 @@ package io.avaje.http.client; -import org.junit.jupiter.api.Test; +import static org.assertj.core.api.Assertions.assertThat; import java.time.Duration; +import java.util.List; -import static org.assertj.core.api.Assertions.assertThat; +import org.junit.jupiter.api.Test; class DHttpClientRequestTest { @@ -21,6 +22,35 @@ void suppressLogging_listenerEvent_expect_suppressedPayloadContent() { assertThat(event.responseBody()).isEqualTo(""); } + @Test + void assertHeader() { + final var request = new DHttpClientRequest(context, Duration.ZERO); + + final var headers = + request + .header("Accept", (Object) List.of("application/json", "application/json2")) + .header("Accept"); + + assertThat(headers).asList().contains("application/json", "application/json2"); + } + + @Test + void assertQuery() { + final var client = HttpClient.builder().baseUrl("https://ap7i.github.com").build(); + + final var uri = + client + .request() + .queryParam("param", List.of("param1", "param2")) + .HEAD() + .asDiscarding() + .request() + .uri() + .toString(); + + assertThat(uri).isEqualTo("https://ap7i.github.com?param=param1¶m=param2"); + } + @Test void skipAuthToken_listenerEvent_expect_suppressedPayloadContent() { final DHttpClientRequest request = new DHttpClientRequest(context, Duration.ZERO); From 007dea646385fa4e3f9a9ecbabb054b927bb2960 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Tue, 28 Feb 2023 23:04:55 -0500 Subject: [PATCH 0646/1323] revert client changes --- .../avaje/http/client/DHttpClientRequest.java | 19 ----------- .../avaje/http/client/HttpClientRequest.java | 10 ------ .../java/io/avaje/http/client/UrlBuilder.java | 9 ----- .../http/client/DHttpClientRequestTest.java | 34 ++----------------- 4 files changed, 2 insertions(+), 70 deletions(-) diff --git a/http-client/src/main/java/io/avaje/http/client/DHttpClientRequest.java b/http-client/src/main/java/io/avaje/http/client/DHttpClientRequest.java index 054ebe00f..dc468d631 100644 --- a/http-client/src/main/java/io/avaje/http/client/DHttpClientRequest.java +++ b/http-client/src/main/java/io/avaje/http/client/DHttpClientRequest.java @@ -16,7 +16,6 @@ import java.util.*; import java.util.concurrent.CompletableFuture; import java.util.function.Supplier; -import java.util.stream.Collectors; import java.util.stream.Stream; import static java.net.http.HttpResponse.BodyHandlers.discarding; @@ -125,25 +124,7 @@ public HttpClientRequest header(String name, String value) { } @Override - public HttpClientRequest header(String name, Collection value) { - if (headers == null) { - headers = new LinkedHashMap<>(); - } - headers.computeIfAbsent(name, s -> new ArrayList<>()).addAll(value); - return this; - } - - @Override - @SuppressWarnings("unchecked") public HttpClientRequest header(String name, Object value) { - - if (value instanceof Collection) { - final var headerList = - ((Collection) value).stream().map(Object::toString).collect(Collectors.toList()); - - return header(name, headerList); - } - return value != null ? header(name, value.toString()) : this; } diff --git a/http-client/src/main/java/io/avaje/http/client/HttpClientRequest.java b/http-client/src/main/java/io/avaje/http/client/HttpClientRequest.java index 55ad84ef2..db1f14ff8 100644 --- a/http-client/src/main/java/io/avaje/http/client/HttpClientRequest.java +++ b/http-client/src/main/java/io/avaje/http/client/HttpClientRequest.java @@ -5,7 +5,6 @@ import java.net.http.HttpResponse; import java.nio.file.Path; import java.time.Duration; -import java.util.Collection; import java.util.List; import java.util.Map; import java.util.function.Supplier; @@ -127,15 +126,6 @@ public interface HttpClientRequest { */ HttpClientRequest header(Map headers); - /** - * Add the headers to the request via Collection. - * - * @param name The header name - * @param value The header values - * @return The request being built - */ - HttpClientRequest header(String name, Collection value); - /** * Return the header values that have been set for the given header name. * diff --git a/http-client/src/main/java/io/avaje/http/client/UrlBuilder.java b/http-client/src/main/java/io/avaje/http/client/UrlBuilder.java index 2ed93e78d..40e82d787 100644 --- a/http-client/src/main/java/io/avaje/http/client/UrlBuilder.java +++ b/http-client/src/main/java/io/avaje/http/client/UrlBuilder.java @@ -2,7 +2,6 @@ import java.net.URLEncoder; import java.nio.charset.StandardCharsets; -import java.util.Collection; import java.util.Map; /** @@ -85,14 +84,6 @@ public UrlBuilder queryParam(String name, String value) { * The name and value parameters are url encoded. */ public UrlBuilder queryParam(String name, Object value) { - - if (value instanceof Collection) { - for (var e : (Collection) value) { - queryParam(name, e); - } - return this; - } - if (value != null) { addQueryParam(name, value.toString()); } diff --git a/http-client/src/test/java/io/avaje/http/client/DHttpClientRequestTest.java b/http-client/src/test/java/io/avaje/http/client/DHttpClientRequestTest.java index 11ea00279..f771785c9 100644 --- a/http-client/src/test/java/io/avaje/http/client/DHttpClientRequestTest.java +++ b/http-client/src/test/java/io/avaje/http/client/DHttpClientRequestTest.java @@ -1,11 +1,10 @@ package io.avaje.http.client; -import static org.assertj.core.api.Assertions.assertThat; +import org.junit.jupiter.api.Test; import java.time.Duration; -import java.util.List; -import org.junit.jupiter.api.Test; +import static org.assertj.core.api.Assertions.assertThat; class DHttpClientRequestTest { @@ -22,35 +21,6 @@ void suppressLogging_listenerEvent_expect_suppressedPayloadContent() { assertThat(event.responseBody()).isEqualTo(""); } - @Test - void assertHeader() { - final var request = new DHttpClientRequest(context, Duration.ZERO); - - final var headers = - request - .header("Accept", (Object) List.of("application/json", "application/json2")) - .header("Accept"); - - assertThat(headers).asList().contains("application/json", "application/json2"); - } - - @Test - void assertQuery() { - final var client = HttpClient.builder().baseUrl("https://ap7i.github.com").build(); - - final var uri = - client - .request() - .queryParam("param", List.of("param1", "param2")) - .HEAD() - .asDiscarding() - .request() - .uri() - .toString(); - - assertThat(uri).isEqualTo("https://ap7i.github.com?param=param1¶m=param2"); - } - @Test void skipAuthToken_listenerEvent_expect_suppressedPayloadContent() { final DHttpClientRequest request = new DHttpClientRequest(context, Duration.ZERO); From 6bc58972a565e359409b27ff47a17d2f30710d43 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Tue, 28 Feb 2023 23:11:21 -0500 Subject: [PATCH 0647/1323] Revert "doc" This reverts commit 02b8db40976e7516b32a6e0122ff2a100648ff1e. --- .../main/java/io/avaje/http/client/HttpClientRequest.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/http-client/src/main/java/io/avaje/http/client/HttpClientRequest.java b/http-client/src/main/java/io/avaje/http/client/HttpClientRequest.java index db1f14ff8..22cc04417 100644 --- a/http-client/src/main/java/io/avaje/http/client/HttpClientRequest.java +++ b/http-client/src/main/java/io/avaje/http/client/HttpClientRequest.java @@ -109,10 +109,9 @@ public interface HttpClientRequest { HttpClientRequest header(String name, String value); /** - * Add the header to the request implicitly converting the value to a String. If the value is a - * collection then it's values are appended with the same key + * Add the header to the request implicitly converting the value to a String. * - * @param name The header name + * @param name The header name * @param value The header value * @return The request being built */ @@ -219,7 +218,7 @@ public interface HttpClientRequest { HttpClientRequest queryParam(String name, String value); /** - * Add a query parameter, if value is a collection then it's values are appended with the same key + * Add a query parameter * * @param name The name of the query parameter * @param value The value of the query parameter which can be null From 3ecc1bd40b1b8d513ebf560fa55be88ee7092e18 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Tue, 28 Feb 2023 23:11:55 -0500 Subject: [PATCH 0648/1323] javadoc --- .../main/java/io/avaje/http/client/HttpClientRequest.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/http-client/src/main/java/io/avaje/http/client/HttpClientRequest.java b/http-client/src/main/java/io/avaje/http/client/HttpClientRequest.java index 246a78a9d..55ad84ef2 100644 --- a/http-client/src/main/java/io/avaje/http/client/HttpClientRequest.java +++ b/http-client/src/main/java/io/avaje/http/client/HttpClientRequest.java @@ -110,9 +110,10 @@ public interface HttpClientRequest { HttpClientRequest header(String name, String value); /** - * Add the header to the request implicitly converting the value to a String. + * Add the header to the request implicitly converting the value to a String. If the value is a + * collection then it's values are appended with the same key * - * @param name The header name + * @param name The header name * @param value The header value * @return The request being built */ @@ -228,7 +229,7 @@ public interface HttpClientRequest { HttpClientRequest queryParam(String name, String value); /** - * Add a query parameter + * Add a query parameter, if value is a collection then it's values are appended with the same key * * @param name The name of the query parameter * @param value The value of the query parameter which can be null From aa0a193b5f9a220a9abc59be3777952404a1cffe Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Tue, 28 Feb 2023 23:42:42 -0500 Subject: [PATCH 0649/1323] add collection query param method --- .../java/io/avaje/http/client/HttpClientRequest.java | 11 +++++++++++ .../io/avaje/http/client/HelloControllerTest.java | 10 +++++----- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/http-client/src/main/java/io/avaje/http/client/HttpClientRequest.java b/http-client/src/main/java/io/avaje/http/client/HttpClientRequest.java index 55ad84ef2..3ead37cc8 100644 --- a/http-client/src/main/java/io/avaje/http/client/HttpClientRequest.java +++ b/http-client/src/main/java/io/avaje/http/client/HttpClientRequest.java @@ -245,6 +245,17 @@ public interface HttpClientRequest { */ HttpClientRequest queryParam(Map params); + /** + * Add a query parameter with multiple values + * + * @param name The name of the query parameter + * @param value The values of the query parameter which can be null + * @return The request being built + */ + default HttpClientRequest queryParam(String name, Collection values) { + return queryParam(name, values); + } + /** * Add a form parameter. * diff --git a/http-client/src/test/java/io/avaje/http/client/HelloControllerTest.java b/http-client/src/test/java/io/avaje/http/client/HelloControllerTest.java index 1bf3bbea2..cff0b3018 100644 --- a/http-client/src/test/java/io/avaje/http/client/HelloControllerTest.java +++ b/http-client/src/test/java/io/avaje/http/client/HelloControllerTest.java @@ -801,7 +801,7 @@ void async_list_as() throws ExecutionException, InterruptedException { void get_withPathParamAndQueryParam_returningBean() { final HelloDto dto = clientContext.request() - .path("hello/43/2020-03-05").queryParam("otherParam", "other").queryParam("foo", null) + .path("hello/43/2020-03-05").queryParam("otherParam", "other").queryParam("foo", (Object) null) .GET() .bean(HelloDto.class); @@ -813,7 +813,7 @@ void get_withPathParamAndQueryParam_returningBean() { @Test void callBean() { final HelloDto dto = clientContext.request() - .path("hello/43/2020-03-05").queryParam("otherParam", "other").queryParam("foo", null) + .path("hello/43/2020-03-05").queryParam("otherParam", "other").queryParam("foo", (Object) null) .GET() .call().bean(HelloDto.class).execute(); @@ -825,7 +825,7 @@ void callBean() { @Test void callBeanAsync() throws ExecutionException, InterruptedException { final CompletableFuture future = clientContext.request() - .path("hello/43/2020-03-05").queryParam("otherParam", "other").queryParam("foo", null) + .path("hello/43/2020-03-05").queryParam("otherParam", "other").queryParam("foo", (String) null) .GET() .call().bean(HelloDto.class).async(); @@ -842,7 +842,7 @@ void async_whenComplete_returningBean() throws ExecutionException, InterruptedEx final AtomicReference ref = new AtomicReference<>(); final CompletableFuture future = clientContext.request() - .path("hello/43/2020-03-05").queryParam("otherParam", "other").queryParam("foo", null) + .path("hello/43/2020-03-05").queryParam("otherParam", "other").queryParam("foo", (String) null) .GET() .async().bean(HelloDto.class); @@ -872,7 +872,7 @@ void async_whenComplete_returningBeanWithHeaders() throws ExecutionException, In final AtomicReference> ref = new AtomicReference<>(); final CompletableFuture> future = clientContext.request() - .path("hello/43/2020-03-05").queryParam("otherParam", "other").queryParam("foo", null) + .path("hello/43/2020-03-05").queryParam("otherParam", "other").queryParam("foo", (String) null) .GET() .async().as(HelloDto.class); From fb862fbff980ba8fea5705f31fb188886c44ec9a Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Tue, 28 Feb 2023 23:46:08 -0500 Subject: [PATCH 0650/1323] Update HttpClientRequest.java --- .../src/main/java/io/avaje/http/client/HttpClientRequest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/http-client/src/main/java/io/avaje/http/client/HttpClientRequest.java b/http-client/src/main/java/io/avaje/http/client/HttpClientRequest.java index 3ead37cc8..4831291ec 100644 --- a/http-client/src/main/java/io/avaje/http/client/HttpClientRequest.java +++ b/http-client/src/main/java/io/avaje/http/client/HttpClientRequest.java @@ -253,7 +253,7 @@ public interface HttpClientRequest { * @return The request being built */ default HttpClientRequest queryParam(String name, Collection values) { - return queryParam(name, values); + return queryParam(name, (Object) values); } /** From 0e29dd0636670a6f514136e7004e664511fb4ac2 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Tue, 28 Feb 2023 23:54:06 -0500 Subject: [PATCH 0651/1323] fix tests --- .../src/test/java/org/example/myapp/HelloControllerTest.java | 2 +- .../src/test/java/org/example/myapp/HelloControllerTest.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test-javalin-jsonb/src/test/java/org/example/myapp/HelloControllerTest.java b/tests/test-javalin-jsonb/src/test/java/org/example/myapp/HelloControllerTest.java index e13c77d69..2939847a8 100644 --- a/tests/test-javalin-jsonb/src/test/java/org/example/myapp/HelloControllerTest.java +++ b/tests/test-javalin-jsonb/src/test/java/org/example/myapp/HelloControllerTest.java @@ -96,7 +96,7 @@ void getWithPathParamAndQueryParam() { assertThat(bean.otherParam).isEqualTo("other"); final HelloDto dto = client.request() - .path("hello/43/2020-03-05").queryParam("otherParam", "other").queryParam("foo", null) + .path("hello/43/2020-03-05").queryParam("otherParam", "other").queryParam("foo", (String) null) .GET().bean(HelloDto.class); assertThat(dto.id).isEqualTo(43L); diff --git a/tests/test-javalin/src/test/java/org/example/myapp/HelloControllerTest.java b/tests/test-javalin/src/test/java/org/example/myapp/HelloControllerTest.java index 3672dac56..acc8b7309 100644 --- a/tests/test-javalin/src/test/java/org/example/myapp/HelloControllerTest.java +++ b/tests/test-javalin/src/test/java/org/example/myapp/HelloControllerTest.java @@ -98,7 +98,7 @@ void getWithPathParamAndQueryParam() { assertThat(bean.otherParam).isEqualTo("other"); final HelloDto dto = client.request() - .path("hello/43/2020-03-05").queryParam("otherParam", "other").queryParam("foo", null) + .path("hello/43/2020-03-05").queryParam("otherParam", "other").queryParam("foo", (String) null) .GET().bean(HelloDto.class); assertThat(dto.id).isEqualTo(43L); From e9376f0c993d8fa0e79558317a21bbaf8694bb70 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Wed, 1 Mar 2023 18:51:06 -0500 Subject: [PATCH 0652/1323] static context --- .../generator/client/ClientMethodWriter.java | 13 ++- .../generator/client/ClientProcessor.java | 27 +++--- .../http/generator/client/ClientWriter.java | 6 +- .../generator/core/BaseControllerWriter.java | 11 ++- .../http/generator/core/BaseProcessor.java | 42 ++++----- .../http/generator/core/BeanParamReader.java | 17 ++-- .../http/generator/core/ControllerReader.java | 21 +++-- .../http/generator/core/ElementReader.java | 43 +++++---- .../http/generator/core/MethodParam.java | 4 +- .../http/generator/core/MethodReader.java | 25 +++--- .../generator/core/ProcessingContext.java | 89 ++++++++++--------- .../helidon/ControllerMethodWriter.java | 8 +- .../generator/helidon/ControllerWriter.java | 9 +- .../generator/helidon/HelidonProcessor.java | 7 +- .../javalin/ControllerMethodWriter.java | 8 +- .../generator/javalin/ControllerWriter.java | 12 +-- .../generator/javalin/JavalinProcessor.java | 4 +- .../generator/jex/ControllerMethodWriter.java | 8 +- .../http/generator/jex/ControllerWriter.java | 11 +-- .../http/generator/jex/JexProcessor.java | 5 +- .../helidon/nima/ControllerMethodWriter.java | 8 +- .../helidon/nima/ControllerWriter.java | 9 +- .../generator/helidon/nima/NimaProcessor.java | 4 +- tests/test-nima-jsonb/.factorypath | 18 ++-- 24 files changed, 194 insertions(+), 215 deletions(-) diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java index 3c55cf7a3..dea5b2e46 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java @@ -1,5 +1,6 @@ package io.avaje.http.generator.client; +import static io.avaje.http.generator.core.ProcessingContext.*; import io.avaje.http.generator.core.*; import javax.lang.model.element.TypeElement; @@ -20,18 +21,16 @@ class ClientMethodWriter { private final MethodReader method; private final Append writer; private final WebMethod webMethod; - private final ProcessingContext ctx; private final UType returnType; private MethodParam bodyHandlerParam; private String methodGenericParams = ""; private final boolean useJsonb; private final Optional timeout; - ClientMethodWriter(MethodReader method, Append writer, ProcessingContext ctx, boolean useJsonb) { + ClientMethodWriter(MethodReader method, Append writer, boolean useJsonb) { this.method = method; this.writer = writer; this.webMethod = method.webMethod(); - this.ctx = ctx; this.returnType = Util.parseType(method.returnType()); this.useJsonb = useJsonb; this.timeout = method.timeout(); @@ -215,8 +214,8 @@ private void writeBeanParams(PathSegments segments) { ParamType paramType = param.paramType(); PathSegments.Segment segment = segments.segment(varName); if (segment == null && paramType == ParamType.BEANPARAM) { - TypeElement formBeanType = ctx.typeElement(param.rawType()); - BeanParamReader form = new BeanParamReader(ctx, formBeanType, param.name(), param.shortType(), ParamType.QUERYPARAM); + TypeElement formBeanType = typeElement(param.rawType()); + BeanParamReader form = new BeanParamReader(formBeanType, param.name(), param.shortType(), ParamType.QUERYPARAM); form.writeFormParams(writer); } } @@ -242,8 +241,8 @@ private void writeFormParam(MethodParam param, ParamType paramType) { writer.append(" .formParam(\"%s\", %s)", param.paramName(), param.name()).eol(); } } else if (paramType == ParamType.FORM) { - TypeElement formBeanType = ctx.typeElement(param.rawType()); - BeanParamReader form = new BeanParamReader(ctx, formBeanType, param.name(), param.shortType(), ParamType.FORMPARAM); + TypeElement formBeanType = typeElement(param.rawType()); + BeanParamReader form = new BeanParamReader(formBeanType, param.name(), param.shortType(), ParamType.FORMPARAM); form.writeFormParams(writer); } } diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java index c632a8e29..98c0d9fc2 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java @@ -1,5 +1,6 @@ package io.avaje.http.generator.client; +import static io.avaje.http.generator.core.ProcessingContext.*; import java.io.IOException; import java.io.Writer; import java.util.LinkedHashSet; @@ -28,8 +29,6 @@ public class ClientProcessor extends AbstractProcessor { private final Set generatedClients = new LinkedHashSet<>(); - protected ProcessingContext ctx; - private final boolean useJsonB; public ClientProcessor() { @@ -49,17 +48,17 @@ public SourceVersion getSupportedSourceVersion() { public synchronized void init(ProcessingEnvironment processingEnv) { super.init(processingEnv); this.processingEnv = processingEnv; - this.ctx = new ProcessingContext(processingEnv, new ClientPlatformAdapter()); + ProcessingContext.init(processingEnv, new ClientPlatformAdapter()); } @Override public boolean process(Set annotations, RoundEnvironment round) { for (final Element controller : - round.getElementsAnnotatedWith(ctx.typeElement(ClientPrism.PRISM_TYPE))) { + round.getElementsAnnotatedWith(typeElement(ClientPrism.PRISM_TYPE))) { writeClient(controller); } for (final Element importedElement : - round.getElementsAnnotatedWith(ctx.typeElement(ImportPrism.PRISM_TYPE))) { + round.getElementsAnnotatedWith(typeElement(ImportPrism.PRISM_TYPE))) { writeForImported(importedElement); } if (round.processingOver()) { @@ -70,40 +69,40 @@ public boolean process(Set annotations, RoundEnvironment private void writeServicesFile() { try { - final FileObject metaInfWriter = ctx.createMetaInfWriter(METAINF_SERVICES_PROVIDER); + final FileObject metaInfWriter = createMetaInfWriter(METAINF_SERVICES_PROVIDER); final Writer writer = metaInfWriter.openWriter(); for (String generatedClient : generatedClients) { writer.append(generatedClient).append("$Provider\n"); } writer.close(); } catch (IOException e) { - ctx.logError(null, "Error writing services file " + e, e); + logError(null, "Error writing services file " + e, e); } } private void writeForImported(Element importedElement) { ImportPrism.getInstanceOn(importedElement).types().stream() - .map(ctx::asElement) + .map(ProcessingContext::asElement) .filter(Objects::nonNull) .forEach(this::writeClient); } private void writeClient(Element controller) { if (controller instanceof TypeElement) { - ControllerReader reader = new ControllerReader((TypeElement) controller, ctx); + ControllerReader reader = new ControllerReader((TypeElement) controller); reader.read(false); try { - generatedClients.add(writeClientAdapter(ctx, reader)); + generatedClients.add(writeClientAdapter(reader)); } catch (Throwable e) { e.printStackTrace(); - ctx.logError(reader.beanType(), "Failed to write client class " + e); + logError(reader.beanType(), "Failed to write client class " + e); } - } + } } - protected String writeClientAdapter(ProcessingContext ctx, ControllerReader reader) throws IOException { - return new ClientWriter(reader, ctx, useJsonB).write(); + protected String writeClientAdapter(ControllerReader reader) throws IOException { + return new ClientWriter(reader, useJsonB).write(); } } diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientWriter.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientWriter.java index 967831b0b..d2d313795 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientWriter.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientWriter.java @@ -23,8 +23,8 @@ class ClientWriter extends BaseControllerWriter { private final List methodList = new ArrayList<>(); private final boolean useJsonb; - ClientWriter(ControllerReader reader, ProcessingContext ctx, boolean useJsonB) throws IOException { - super(reader, ctx, SUFFIX); + ClientWriter(ControllerReader reader, boolean useJsonB) throws IOException { + super(reader, SUFFIX); reader.addImportType(HTTP_CLIENT); reader.addImportType(HTTP_API_PROVIDER); this.useJsonb = useJsonB; @@ -41,7 +41,7 @@ protected String initPackageName(String originName) { private void readMethods() { for (MethodReader method : reader.methods()) { if (method.isWebMethod()) { - final var methodWriter = new ClientMethodWriter(method, writer, ctx, useJsonb); + final var methodWriter = new ClientMethodWriter(method, writer, useJsonb); methodWriter.addImportTypes(reader); methodList.add(methodWriter); } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseControllerWriter.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseControllerWriter.java index 28ee7e14c..44ae01495 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseControllerWriter.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseControllerWriter.java @@ -1,5 +1,6 @@ package io.avaje.http.generator.core; +import static io.avaje.http.generator.core.ProcessingContext.*; import javax.lang.model.element.TypeElement; import javax.tools.JavaFileObject; import java.io.IOException; @@ -11,7 +12,6 @@ public abstract class BaseControllerWriter { protected final ControllerReader reader; - protected final ProcessingContext ctx; protected final String originName; protected final String shortName; protected final String fullName; @@ -19,13 +19,12 @@ public abstract class BaseControllerWriter { protected final boolean router; protected Append writer; - protected BaseControllerWriter(ControllerReader reader, ProcessingContext ctx) throws IOException { - this(reader, ctx, "$Route"); + protected BaseControllerWriter(ControllerReader reader) throws IOException { + this(reader, "$Route"); } - protected BaseControllerWriter(ControllerReader reader, ProcessingContext ctx, String suffix) throws IOException { + protected BaseControllerWriter(ControllerReader reader, String suffix) throws IOException { this.reader = reader; - this.ctx = ctx; this.router = "$Route".equals(suffix); TypeElement origin = reader.beanType(); this.originName = origin.getQualifiedName().toString(); @@ -50,7 +49,7 @@ protected void initWriter() throws IOException { } protected Writer createFileWriter() throws IOException { - JavaFileObject jfo = ctx.createWriter(fullName, reader.beanType()); + JavaFileObject jfo = createWriter(fullName, reader.beanType()); return jfo.openWriter(); } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java index 4ed248e5d..9b1acd321 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java @@ -1,5 +1,6 @@ package io.avaje.http.generator.core; +import static io.avaje.http.generator.core.ProcessingContext.*; import java.io.IOException; import java.util.Set; import javax.annotation.processing.AbstractProcessor; @@ -13,7 +14,6 @@ @SupportedOptions({"useJavax", "useSingleton"}) public abstract class BaseProcessor extends AbstractProcessor { - protected ProcessingContext ctx; @Override public SourceVersion getSupportedSourceVersion() { @@ -28,7 +28,7 @@ public Set getSupportedAnnotationTypes() { @Override public synchronized void init(ProcessingEnvironment processingEnv) { super.init(processingEnv); - this.ctx = new ProcessingContext(processingEnv, providePlatformAdapter()); + ProcessingContext.init(processingEnv, providePlatformAdapter()); } /** Provide the platform specific adapter to use for Javalin, Helidon etc. */ @@ -37,16 +37,16 @@ public synchronized void init(ProcessingEnvironment processingEnv) { @Override public boolean process(Set annotations, RoundEnvironment round) { - if (ctx.isOpenApiAvailable()) { + if (isOpenApiAvailable()) { readOpenApiDefinition(round); readTagDefinitions(round); readSecuritySchemes(round); } final Set controllers = - round.getElementsAnnotatedWith(ctx.typeElement(ControllerPrism.PRISM_TYPE)); + round.getElementsAnnotatedWith(typeElement(ControllerPrism.PRISM_TYPE)); for (Element controller : controllers) { - writeControllerAdapter(controller); + writeAdapter(controller); } if (round.processingOver()) { @@ -57,50 +57,50 @@ public boolean process(Set annotations, RoundEnvironment private void readOpenApiDefinition(RoundEnvironment round) { final Set elements = - round.getElementsAnnotatedWith(ctx.typeElement(OpenAPIDefinitionPrism.PRISM_TYPE)); + round.getElementsAnnotatedWith(typeElement(OpenAPIDefinitionPrism.PRISM_TYPE)); for (Element element : elements) { - ctx.doc().readApiDefinition(element); + doc().readApiDefinition(element); } } private void readTagDefinitions(RoundEnvironment round) { Set elements = - round.getElementsAnnotatedWith(ctx.typeElement(TagPrism.PRISM_TYPE)); + round.getElementsAnnotatedWith(typeElement(TagPrism.PRISM_TYPE)); for (Element element : elements) { - ctx.doc().addTagDefinition(element); + doc().addTagDefinition(element); } - elements = round.getElementsAnnotatedWith(ctx.typeElement(TagsPrism.PRISM_TYPE)); + elements = round.getElementsAnnotatedWith(typeElement(TagsPrism.PRISM_TYPE)); for (Element element : elements) { - ctx.doc().addTagsDefinition(element); + doc().addTagsDefinition(element); } } private void readSecuritySchemes(RoundEnvironment round) { - Set elements = round.getElementsAnnotatedWith(ctx.typeElement(SecuritySchemePrism.PRISM_TYPE)); + Set elements = round.getElementsAnnotatedWith(typeElement(SecuritySchemePrism.PRISM_TYPE)); for (Element element : elements) { - ctx.doc().addSecurityScheme(element); + doc().addSecurityScheme(element); } - elements = round.getElementsAnnotatedWith(ctx.typeElement(SecuritySchemesPrism.PRISM_TYPE)); + elements = round.getElementsAnnotatedWith(typeElement(SecuritySchemesPrism.PRISM_TYPE)); for (Element element : elements) { - ctx.doc().addSecuritySchemes(element); + doc().addSecuritySchemes(element); } } private void writeOpenAPI() { - ctx.doc().writeApi(); + doc().writeApi(); } - private void writeControllerAdapter(Element controller) { + private void writeAdapter(Element controller) { if (controller instanceof TypeElement) { - ControllerReader reader = new ControllerReader((TypeElement) controller, ctx); + ControllerReader reader = new ControllerReader((TypeElement) controller); reader.read(true); try { - writeControllerAdapter(ctx, reader); + writeControllerAdapter(reader); } catch (Throwable e) { e.printStackTrace(); - ctx.logError(reader.beanType(), "Failed to write $Route class " + e); + logError(reader.beanType(), "Failed to write $Route class " + e); } } } @@ -108,6 +108,6 @@ private void writeControllerAdapter(Element controller) { /** * Write the adapter code for the given controller. */ - public abstract void writeControllerAdapter(ProcessingContext ctx, ControllerReader reader) throws IOException; + public abstract void writeControllerAdapter(ControllerReader reader) throws IOException; } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/BeanParamReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/BeanParamReader.java index d3350b74c..dfd6b56a9 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/BeanParamReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/BeanParamReader.java @@ -1,11 +1,11 @@ package io.avaje.http.generator.core; +import static io.avaje.http.generator.core.ProcessingContext.*; import javax.lang.model.element.*; import java.util.*; public class BeanParamReader { - private final ProcessingContext ctx; private final String beanVarName; private final String beanShortType; private final TypeElement beanType; @@ -15,8 +15,7 @@ public class BeanParamReader { private final List constructors = new ArrayList<>(); private final Map methodMap = new LinkedHashMap<>(); - public BeanParamReader(ProcessingContext ctx, TypeElement beanType, String beanVarName, String beanShortType, ParamType defaultParamType) { - this.ctx = ctx; + public BeanParamReader(TypeElement beanType, String beanVarName, String beanShortType, ParamType defaultParamType) { this.beanType = beanType; this.beanVarName = beanVarName; this.beanShortType = beanShortType; @@ -41,7 +40,7 @@ private void read() { } private void readField(Element enclosedElement) { - FieldReader field = new FieldReader(ctx, enclosedElement, defaultParamType); + FieldReader field = new FieldReader(enclosedElement, defaultParamType); fieldMap.put(field.varName(), field); } @@ -141,14 +140,12 @@ private ExecutableElement findGetter(String varName) { static class FieldReader { - private final ProcessingContext ctx; private final ElementReader element; private String setterMethod; private boolean constructorParam; - FieldReader(ProcessingContext ctx, Element enclosedElement, ParamType defaultParamType) { - this.ctx = ctx; - this.element = new ElementReader(enclosedElement, ctx, defaultParamType, false); + FieldReader(Element enclosedElement, ParamType defaultParamType) { + this.element = new ElementReader(enclosedElement, defaultParamType, false); } boolean isPublic() { @@ -181,13 +178,13 @@ boolean isConstructorParam() { void writeSet(Append writer, String beanVarName) { if (setterMethod != null) { // populate via setter method - writer.append("%s %s.%s(", ctx.platform().indent(), beanVarName, setterMethod); + writer.append("%s %s.%s(", platform().indent(), beanVarName, setterMethod); element.setValue(writer); writer.append(");").eol(); } else { // populate via field put - writer.append("%s %s.%s = ", ctx.platform().indent(), beanVarName, varName()); + writer.append("%s %s.%s = ", platform().indent(), beanVarName, varName()); element.setValue(writer); writer.append(";").eol(); } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java index 4f3ed84d5..99be109ec 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java @@ -1,5 +1,6 @@ package io.avaje.http.generator.core; +import static io.avaje.http.generator.core.ProcessingContext.*; import static java.util.function.Predicate.not; import java.util.ArrayList; @@ -23,7 +24,6 @@ */ public final class ControllerReader { - private final ProcessingContext ctx; private final TypeElement beanType; private final List interfaces; private final List interfaceMethods; @@ -45,13 +45,12 @@ public final class ControllerReader { private boolean requestScope; private boolean docHidden; - public ControllerReader(TypeElement beanType, ProcessingContext ctx) { + public ControllerReader(TypeElement beanType) { this.beanType = beanType; - this.ctx = ctx; this.interfaces = initInterfaces(); this.interfaceMethods = initInterfaceMethods(); this.roles = buildRoles(); - if (ctx.isOpenApiAvailable()) { + if (isOpenApiAvailable()) { docHidden = initDocHidden(); } this.hasValid = initHasValid(); @@ -93,10 +92,10 @@ void addImports(boolean withSingleton) { importTypes.add(Constants.VALIDATOR); } if (withSingleton) { - if (ctx.useComponent()) { + if (useComponent()) { importTypes.add(Constants.COMPONENT); } else { - importTypes.add(ctx.useJavax() ? Constants.SINGLETON_JAVAX : Constants.SINGLETON_JAKARTA); + importTypes.add(useJavax() ? Constants.SINGLETON_JAVAX : Constants.SINGLETON_JAKARTA); } } } @@ -104,7 +103,7 @@ void addImports(boolean withSingleton) { private List initInterfaces() { List interfaces = new ArrayList<>(); for (TypeMirror anInterface : beanType.getInterfaces()) { - final Element ifaceElement = ctx.asElement(anInterface); + final Element ifaceElement = asElement(anInterface); final var controller = ControllerPrism.getInstanceOn(ifaceElement); if (controller != null && !controller.value().isBlank() || PathPrism.isPresent(ifaceElement)) { @@ -196,7 +195,7 @@ boolean isRequestScoped() { public void read(boolean withSingleton) { if (!roles.isEmpty()) { - ctx.platform().controllerRoles(roles, this); + platform().controllerRoles(roles, this); } for (Element element : beanType.getEnclosedElements()) { if (element.getKind() == ElementKind.METHOD) { @@ -237,7 +236,7 @@ private void readSuper(TypeElement beanType) { TypeMirror superclass = beanType.getSuperclass(); if (superclass.getKind() != TypeKind.NONE) { DeclaredType declaredType = (DeclaredType) superclass; - final Element superElement = ctx.asElement(superclass); + final Element superElement = asElement(superclass); if (!"java.lang.Object".equals(superElement.toString())) { for (Element element : superElement.getEnclosedElements()) { if (element.getKind() == ElementKind.METHOD) { @@ -261,9 +260,9 @@ private void readMethod(ExecutableElement method, DeclaredType declaredType) { ExecutableType actualExecutable = null; if (declaredType != null) { // actual taking into account generics - actualExecutable = (ExecutableType) ctx.asMemberOf(declaredType, method); + actualExecutable = (ExecutableType) asMemberOf(declaredType, method); } - MethodReader methodReader = new MethodReader(this, method, actualExecutable, ctx); + MethodReader methodReader = new MethodReader(this, method, actualExecutable); if (methodReader.isWebMethod()) { methodReader.read(); methods.add(methodReader); diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java index f61e2f932..3da9a4b27 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java @@ -1,5 +1,6 @@ package io.avaje.http.generator.core; +import static io.avaje.http.generator.core.ProcessingContext.*; import static io.avaje.http.generator.core.ParamType.RESPONSE_HANDLER; import java.util.List; @@ -15,7 +16,6 @@ public class ElementReader { - private final ProcessingContext ctx; private final Element element; private final UType type; private final String rawType; @@ -39,17 +39,16 @@ public class ElementReader { private boolean isParamMap; // private boolean notNullJavax; - ElementReader(Element element, ProcessingContext ctx, ParamType defaultType, boolean formMarker) { - this(element, null, Util.typeDef(element.asType()), ctx, defaultType, formMarker); + ElementReader(Element element, ParamType defaultType, boolean formMarker) { + this(element, null, Util.typeDef(element.asType()), defaultType, formMarker); } - ElementReader(Element element, UType type, String rawType, ProcessingContext ctx, ParamType defaultType, boolean formMarker) { - this.ctx = ctx; + ElementReader(Element element, UType type, String rawType, ParamType defaultType, boolean formMarker) { this.element = element; this.type = type; this.rawType = rawType; this.shortType = Util.shortName(rawType); - this.contextType = ctx.platform().isContextType(rawType); + this.contextType = platform().isContextType(rawType); this.specialParam = defaultType == ParamType.FORMPARAM @@ -81,7 +80,7 @@ TypeHandler initTypeHandler() { final var mainTypeEnum = typeOp - .flatMap(t -> Optional.ofNullable(ctx.typeElement(t.mainType()))) + .flatMap(t -> Optional.ofNullable(typeElement(t.mainType()))) .map(TypeElement::getKind) .filter(ElementKind.ENUM::equals) .isPresent(); @@ -100,7 +99,7 @@ TypeHandler initTypeHandler() { this.isParamCollection = true; final var isEnumCollection = typeOp - .flatMap(t -> Optional.ofNullable(ctx.typeElement(t.param0()))) + .flatMap(t -> Optional.ofNullable(typeElement(t.param0()))) .map(TypeElement::getKind) .filter(ElementKind.ENUM::equals) .isPresent(); @@ -120,7 +119,7 @@ private boolean useValidation() { if (typeHandler != null) { return false; } - final var elementType = ctx.typeElement(rawType); + final var elementType = typeElement(rawType); return elementType != null && (ValidPrism.isPresent(elementType) || JavaxValidPrism.isPresent(elementType)); } @@ -214,7 +213,7 @@ private boolean isPlatformContext() { } private String platformVariable() { - return ctx.platform().platformVariable(rawType); + return platform().platformVariable(rawType); } private String handlerShortType() { @@ -264,12 +263,12 @@ void writeValidate(Append writer) { void writeCtxGet(Append writer, PathSegments segments) { if (isPlatformContext() - || (paramType == ParamType.BODY && ctx.platform().isBodyMethodParam())) { + || (paramType == ParamType.BODY && platform().isBodyMethodParam())) { // body passed as method parameter (Helidon) return; } String shortType = handlerShortType(); - writer.append("%s var %s = ", ctx.platform().indent(), varName); + writer.append("%s var %s = ", platform().indent(), varName); if (setValue(writer, segments, shortType)) { writer.append(";").eol(); } @@ -310,7 +309,7 @@ private boolean setValue(Append writer, PathSegments segments, String shortType) if (asMethod != null) { writer.append(asMethod); } - segment.writeGetVal(writer, name, ctx.platform()); + segment.writeGetVal(writer, name, platform()); if (asMethod != null) { writer.append(")"); } @@ -326,26 +325,26 @@ private boolean setValue(Append writer, PathSegments segments, String shortType) if (typeHandler == null) { // this is a body (POST, PATCH) - writer.append(ctx.platform().bodyAsClass(type)); + writer.append(platform().bodyAsClass(type)); } else if (isParamCollection && specialParam) { if (hasParamDefault()) { - ctx.platform().writeReadCollectionParameter(writer, paramType, paramName, paramDefault); + platform().writeReadCollectionParameter(writer, paramType, paramName, paramDefault); } else { - ctx.platform().writeReadCollectionParameter(writer, paramType, paramName); + platform().writeReadCollectionParameter(writer, paramType, paramName); } } else if (isParamMap) { - ctx.platform().writeReadMapParameter(writer, paramType); + platform().writeReadMapParameter(writer, paramType); } else if (hasParamDefault()) { - ctx.platform().writeReadParameter(writer, paramType, paramName, paramDefault.get(0)); + platform().writeReadParameter(writer, paramType, paramName, paramDefault.get(0)); } else { final var checkNull = notNullKotlin || (paramType == ParamType.FORMPARAM && typeHandler.isPrimitive()); if (checkNull) { writer.append("checkNull("); } - ctx.platform().writeReadParameter(writer, paramType, paramName); - // writer.append("ctx.%s(\"%s\")", paramType, paramName); + platform().writeReadParameter(writer, paramType, paramName); + // writer.append("%s(\"%s\")", paramType, paramName); if (checkNull) { writer.append(", \"%s\")", paramName); } @@ -358,8 +357,8 @@ private boolean setValue(Append writer, PathSegments segments, String shortType) } private void writeForm(Append writer, String shortType, String varName, ParamType defaultParamType) { - TypeElement formBeanType = ctx.typeElement(rawType); - BeanParamReader form = new BeanParamReader(ctx, formBeanType, varName, shortType, defaultParamType); + TypeElement formBeanType = typeElement(rawType); + BeanParamReader form = new BeanParamReader(formBeanType, varName, shortType, defaultParamType); form.write(writer); } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodParam.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodParam.java index 3439dec0b..d212027c3 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodParam.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodParam.java @@ -8,8 +8,8 @@ public class MethodParam { private final ElementReader elementParam; - MethodParam(VariableElement param, UType type, String rawType, ProcessingContext ctx, ParamType defaultParamType, boolean formMarker) { - this.elementParam = new ElementReader(param, type, rawType, ctx, defaultParamType, formMarker); + MethodParam(VariableElement param, UType type, String rawType, ParamType defaultParamType, boolean formMarker) { + this.elementParam = new ElementReader(param, type, rawType, defaultParamType, formMarker); } public void writeCtxGet(Append writer, PathSegments segments) { diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java index d8c7edd95..d48feb797 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java @@ -1,5 +1,6 @@ package io.avaje.http.generator.core; +import static io.avaje.http.generator.core.ProcessingContext.*; import io.avaje.http.generator.core.javadoc.Javadoc; import io.avaje.http.generator.core.openapi.MethodDocBuilder; import java.util.ArrayList; @@ -21,7 +22,6 @@ public class MethodReader { - private final ProcessingContext ctx; private final ControllerReader bean; private final ExecutableElement element; private final boolean isVoid; @@ -45,8 +45,7 @@ public class MethodReader { private String webMethodPath; private boolean formMarker; - MethodReader(ControllerReader bean, ExecutableElement element, ExecutableType actualExecutable, ProcessingContext ctx) { - this.ctx = ctx; + MethodReader(ControllerReader bean, ExecutableElement element, ExecutableType actualExecutable) { this.bean = bean; this.element = element; this.actualExecutable = actualExecutable; @@ -57,12 +56,12 @@ public class MethodReader { initWebMethodViaAnnotation(); this.superMethods = - ctx.superMethods(element.getEnclosingElement(), element.getSimpleName().toString()); + superMethods(element.getEnclosingElement(), element.getSimpleName().toString()); superMethods.forEach(m -> methodRoles.addAll(Util.findRoles(m))); this.securityRequirements = readSecurityRequirements(); this.apiResponses = buildApiResponses(); - this.javadoc = buildJavadoc(element, ctx); + this.javadoc = buildJavadoc(element); this.timeout = RequestTimeoutPrism.getOptionalOn(element); timeout.ifPresent( p -> { @@ -78,13 +77,13 @@ public class MethodReader { } } - private Javadoc buildJavadoc(ExecutableElement element, ProcessingContext ctx) { - return Optional.of(Javadoc.parse(ctx.docComment(element))) + private Javadoc buildJavadoc(ExecutableElement element) { + return Optional.of(Javadoc.parse(docComment(element))) .filter(Predicate.not(Javadoc::isEmpty)) .orElseGet( () -> superMethods.stream() - .map(e -> Javadoc.parse(ctx.docComment(e))) + .map(e -> Javadoc.parse(docComment(e))) .filter(Predicate.not(Javadoc::isEmpty)) .findFirst() .orElse(Javadoc.parse(""))); @@ -235,7 +234,7 @@ public List tags() { void read() { if (!methodRoles.isEmpty()) { - ctx.platform().methodRoles(methodRoles, bean); + platform().methodRoles(methodRoles, bean); } // non-path parameters default to form or query parameters based on the // existence of @Form annotation on the method @@ -252,21 +251,21 @@ void read() { } String rawType = Util.typeDef(typeMirror); UType type = Util.parse(typeMirror.toString()); - MethodParam param = new MethodParam(p, type, rawType, ctx, defaultParamType, formMarker); + MethodParam param = new MethodParam(p, type, rawType, defaultParamType, formMarker); params.add(param); param.addImports(bean); } } public void buildApiDoc() { - buildApiDocumentation(ctx); + buildApiDocumentation(); } /** * Build the OpenAPI documentation for the method / operation. */ - public void buildApiDocumentation(ProcessingContext ctx) { - new MethodDocBuilder(this, ctx.doc()).build(); + public void buildApiDocumentation() { + new MethodDocBuilder(this, doc()).build(); } public List roles() { diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java index f26b1e13d..3acc651c8 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java @@ -1,6 +1,9 @@ package io.avaje.http.generator.core; -import io.avaje.http.generator.core.openapi.DocContext; +import java.io.IOException; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; import javax.annotation.processing.Filer; import javax.annotation.processing.Messager; @@ -17,107 +20,105 @@ import javax.tools.FileObject; import javax.tools.JavaFileObject; import javax.tools.StandardLocation; -import java.io.IOException; -import java.util.List; -import java.util.Objects; -import java.util.stream.Collectors; + +import io.avaje.http.generator.core.openapi.DocContext; public class ProcessingContext { - private final PlatformAdapter readAdapter; - private final Messager messager; - private final Filer filer; - private final Elements elements; - private final Types types; - private final boolean openApiAvailable; - private final DocContext docContext; - private final boolean useComponent; - private final boolean useJavax; - private final String diAnnotation; - - public ProcessingContext(ProcessingEnvironment env, PlatformAdapter readAdapter) { - this.readAdapter = readAdapter; - this.messager = env.getMessager(); - this.filer = env.getFiler(); - this.elements = env.getElementUtils(); - this.types = env.getTypeUtils(); - this.openApiAvailable = isTypeAvailable(Constants.OPENAPIDEFINITION); - this.docContext = new DocContext(env, openApiAvailable); + private static PlatformAdapter readAdapter; + private static Messager messager; + private static Filer filer; + private static Elements elements; + private static Types types; + private static boolean openApiAvailable; + private static DocContext docContext; + private static boolean useComponent; + private static boolean useJavax; + private static String diAnnotation; + + public static void init(ProcessingEnvironment env, PlatformAdapter adapter) { + readAdapter = adapter; + messager = env.getMessager(); + filer = env.getFiler(); + elements = env.getElementUtils(); + types = env.getTypeUtils(); + openApiAvailable = isTypeAvailable(Constants.OPENAPIDEFINITION); + docContext = new DocContext(env, openApiAvailable); final var options = env.getOptions(); final var singletonOverride = options.get("useSingleton"); if (singletonOverride != null) { - this.useComponent = !Boolean.parseBoolean(singletonOverride); + useComponent = !Boolean.parseBoolean(singletonOverride); } else { - this.useComponent = isTypeAvailable(Constants.COMPONENT); + useComponent = isTypeAvailable(Constants.COMPONENT); } - this.diAnnotation = useComponent ? "@Component" : "@Singleton"; + diAnnotation = useComponent ? "@Component" : "@Singleton"; final var javax = isTypeAvailable(Constants.SINGLETON_JAVAX); final var jakarta = isTypeAvailable(Constants.SINGLETON_JAKARTA); final var override = env.getOptions().get("useJavax"); if (override != null || (javax && jakarta)) { - this.useJavax = Boolean.parseBoolean(override); + useJavax = Boolean.parseBoolean(override); } else { - this.useJavax = javax; + useJavax = javax; } } - private boolean isTypeAvailable(String canonicalName) { + private static boolean isTypeAvailable(String canonicalName) { return null != typeElement(canonicalName); } - public TypeElement typeElement(String canonicalName) { + public static TypeElement typeElement(String canonicalName) { return elements.getTypeElement(canonicalName); } - public boolean isOpenApiAvailable() { + public static boolean isOpenApiAvailable() { return openApiAvailable; } - public boolean useJavax() { + public static boolean useJavax() { return useJavax; } - public boolean useComponent() { + public static boolean useComponent() { return useComponent; } - public void logError(Element e, String msg, Object... args) { + public static void logError(Element e, String msg, Object... args) { messager.printMessage(Diagnostic.Kind.ERROR, String.format(msg, args), e); } /** * Create a file writer for the given class name. */ - public JavaFileObject createWriter(String cls, Element origin) throws IOException { + public static JavaFileObject createWriter(String cls, Element origin) throws IOException { return filer.createSourceFile(cls, origin); } /** * Create a file writer for the META-INF services file. */ - public FileObject createMetaInfWriter(String target) throws IOException { + public static FileObject createMetaInfWriter(String target) throws IOException { return filer.createResource(StandardLocation.CLASS_OUTPUT, "", target); } - public String docComment(Element param) { + public static String docComment(Element param) { return elements.getDocComment(param); } - public DocContext doc() { + public static DocContext doc() { return docContext; } - public Element asElement(TypeMirror typeMirror) { + public static Element asElement(TypeMirror typeMirror) { return types.asElement(typeMirror); } - public TypeMirror asMemberOf(DeclaredType declaredType, Element element) { + public static TypeMirror asMemberOf(DeclaredType declaredType, Element element) { return types.asMemberOf(declaredType, element); } - public List superMethods(Element element, String methodName) { + public static List superMethods(Element element, String methodName) { return types.directSupertypes(element.asType()).stream() .filter(type -> !type.toString().contains("java.lang.Object")) .map( @@ -134,11 +135,11 @@ public List superMethods(Element element, String methodName) .collect(Collectors.toList()); } - public PlatformAdapter platform() { + public static PlatformAdapter platform() { return readAdapter; } - public String diAnnotation() { + public static String diAnnotation() { return diAnnotation; } } diff --git a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/ControllerMethodWriter.java b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/ControllerMethodWriter.java index 87f62cf48..4d0a75d2f 100644 --- a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/ControllerMethodWriter.java +++ b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/ControllerMethodWriter.java @@ -1,12 +1,12 @@ package io.avaje.http.generator.helidon; +import static io.avaje.http.generator.core.ProcessingContext.platform; import java.util.List; import io.avaje.http.generator.core.Append; import io.avaje.http.generator.core.MethodParam; import io.avaje.http.generator.core.MethodReader; import io.avaje.http.generator.core.PathSegments; -import io.avaje.http.generator.core.ProcessingContext; import io.avaje.http.generator.core.WebMethod; import io.avaje.http.generator.core.openapi.MediaType; @@ -18,13 +18,11 @@ class ControllerMethodWriter { private final MethodReader method; private final Append writer; private final WebMethod webMethod; - private final ProcessingContext ctx; - ControllerMethodWriter(MethodReader method, Append writer, ProcessingContext ctx) { + ControllerMethodWriter(MethodReader method, Append writer) { this.method = method; this.writer = writer; this.webMethod = method.webMethod(); - this.ctx = ctx; } void writeRule() { @@ -55,7 +53,7 @@ void writeHandler(boolean requestScoped) { final PathSegments segments = method.pathSegments(); List matrixSegments = segments.matrixSegments(); for (PathSegments.Segment matrixSegment : matrixSegments) { - matrixSegment.writeCreateSegment(writer, ctx.platform()); + matrixSegment.writeCreateSegment(writer, platform()); } final List params = method.params(); diff --git a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/ControllerWriter.java b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/ControllerWriter.java index 0a19d4847..b052ab278 100644 --- a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/ControllerWriter.java +++ b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/ControllerWriter.java @@ -1,5 +1,6 @@ package io.avaje.http.generator.helidon; +import static io.avaje.http.generator.core.ProcessingContext.diAnnotation; import io.avaje.http.generator.core.*; import java.io.IOException; @@ -13,8 +14,8 @@ class ControllerWriter extends BaseControllerWriter { private static final String AT_GENERATED = "@Generated(\"avaje-helidon-generator\")"; - ControllerWriter(ControllerReader reader, ProcessingContext ctx) throws IOException { - super(reader, ctx); + ControllerWriter(ControllerReader reader) throws IOException { + super(reader); reader.addImportType("io.helidon.common.http.FormParams"); reader.addImportType("io.helidon.webserver.Handler"); reader.addImportType("io.helidon.webserver.Routing"); @@ -34,7 +35,7 @@ void write() { private List getWriterMethods() { return reader.methods().stream() .filter(MethodReader::isWebMethod) - .map(it -> new ControllerMethodWriter(it, writer, ctx)) + .map(it -> new ControllerMethodWriter(it, writer)) .collect(Collectors.toList()); } @@ -60,7 +61,7 @@ private void writeRoutes(List methods) { private void writeClassStart() { writer.append(AT_GENERATED).eol(); - writer.append(ctx.diAnnotation()).eol(); + writer.append(diAnnotation()).eol(); writer.append("public class ").append(shortName).append("$Route implements Service {").eol().eol(); String controllerName = "controller"; diff --git a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/HelidonProcessor.java b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/HelidonProcessor.java index 4f5b49509..9f88d25b6 100644 --- a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/HelidonProcessor.java +++ b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/HelidonProcessor.java @@ -3,9 +3,8 @@ import io.avaje.http.generator.core.BaseProcessor; import io.avaje.http.generator.core.ControllerReader; import io.avaje.http.generator.core.PlatformAdapter; -import io.avaje.http.generator.core.ProcessingContext; -import java.io.IOException; +import java.io.IOException; public class HelidonProcessor extends BaseProcessor { @@ -15,7 +14,7 @@ protected PlatformAdapter providePlatformAdapter() { } @Override - public void writeControllerAdapter(ProcessingContext ctx, ControllerReader reader) throws IOException { - new ControllerWriter(reader, ctx).write(); + public void writeControllerAdapter(ControllerReader reader) throws IOException { + new ControllerWriter(reader).write(); } } diff --git a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java index 46d72b787..1ee63cffa 100644 --- a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java +++ b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java @@ -1,10 +1,10 @@ package io.avaje.http.generator.javalin; +import static io.avaje.http.generator.core.ProcessingContext.platform; import io.avaje.http.generator.core.Append; import io.avaje.http.generator.core.MethodParam; import io.avaje.http.generator.core.MethodReader; import io.avaje.http.generator.core.PathSegments; -import io.avaje.http.generator.core.ProcessingContext; import io.avaje.http.generator.core.UType; import io.avaje.http.generator.core.Util; import io.avaje.http.generator.core.WebMethod; @@ -18,14 +18,12 @@ class ControllerMethodWriter { private final MethodReader method; private final Append writer; private final WebMethod webMethod; - private final ProcessingContext ctx; private final boolean useJsonB; - ControllerMethodWriter(MethodReader method, Append writer, ProcessingContext ctx, boolean useJsonB) { + ControllerMethodWriter(MethodReader method, Append writer, boolean useJsonB) { this.method = method; this.writer = writer; this.webMethod = method.webMethod(); - this.ctx = ctx; this.useJsonB = useJsonB; } @@ -39,7 +37,7 @@ void write(boolean requestScoped) { final var matrixSegments = segments.matrixSegments(); for (final PathSegments.Segment matrixSegment : matrixSegments) { - matrixSegment.writeCreateSegment(writer, ctx.platform()); + matrixSegment.writeCreateSegment(writer, platform()); } final var params = method.params(); diff --git a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java index 6ad12f09a..5325f426c 100644 --- a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java +++ b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java @@ -1,5 +1,6 @@ package io.avaje.http.generator.javalin; +import static io.avaje.http.generator.core.ProcessingContext.diAnnotation; import java.io.IOException; import java.util.Map; @@ -9,7 +10,6 @@ import io.avaje.http.generator.core.JsonBUtil; import io.avaje.http.generator.core.MethodReader; import io.avaje.http.generator.core.PrimitiveUtil; -import io.avaje.http.generator.core.ProcessingContext; import io.avaje.http.generator.core.UType; /** @@ -22,8 +22,8 @@ class ControllerWriter extends BaseControllerWriter { private final boolean useJsonB; private final Map jsonTypes; - ControllerWriter(ControllerReader reader, ProcessingContext ctx, boolean jsonB) throws IOException { - super(reader, ctx); + ControllerWriter(ControllerReader reader, boolean jsonB) throws IOException { + super(reader); this.useJsonB = jsonB; if (useJsonB) { reader.addImportType("io.avaje.jsonb.Jsonb"); @@ -59,15 +59,15 @@ private void writeAddRoutes() { } private void writeForMethod(MethodReader method) { - new ControllerMethodWriter(method, writer, ctx, useJsonB).write(isRequestScoped()); + new ControllerMethodWriter(method, writer, useJsonB).write(isRequestScoped()); if (!reader.isDocHidden()) { - method.buildApiDocumentation(ctx); + method.buildApiDocumentation(); } } private void writeClassStart() { writer.append(AT_GENERATED).eol(); - writer.append(ctx.diAnnotation()).eol(); + writer.append(diAnnotation()).eol(); writer .append("public class ") .append(shortName) diff --git a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinProcessor.java b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinProcessor.java index cbe3c0f27..1e797b958 100644 --- a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinProcessor.java +++ b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinProcessor.java @@ -22,7 +22,7 @@ protected PlatformAdapter providePlatformAdapter() { } @Override - public void writeControllerAdapter(ProcessingContext ctx, ControllerReader reader) throws IOException { - new ControllerWriter(reader, ctx, useJsonB).write(); + public void writeControllerAdapter(ControllerReader reader) throws IOException { + new ControllerWriter(reader, useJsonB).write(); } } diff --git a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java index cf666f927..b5a548300 100644 --- a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java +++ b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java @@ -1,12 +1,12 @@ package io.avaje.http.generator.jex; +import static io.avaje.http.generator.core.ProcessingContext.platform; import java.util.List; import io.avaje.http.generator.core.Append; import io.avaje.http.generator.core.MethodParam; import io.avaje.http.generator.core.MethodReader; import io.avaje.http.generator.core.PathSegments; -import io.avaje.http.generator.core.ProcessingContext; import io.avaje.http.generator.core.Util; import io.avaje.http.generator.core.WebMethod; import io.avaje.http.generator.core.openapi.MediaType; @@ -19,13 +19,11 @@ class ControllerMethodWriter { private final MethodReader method; private final Append writer; private final WebMethod webMethod; - private final ProcessingContext ctx; - ControllerMethodWriter(MethodReader method, Append writer, ProcessingContext ctx) { + ControllerMethodWriter(MethodReader method, Append writer) { this.method = method; this.writer = writer; this.webMethod = method.webMethod(); - this.ctx = ctx; } void write(boolean requestScoped) { @@ -38,7 +36,7 @@ void write(boolean requestScoped) { List matrixSegments = segments.matrixSegments(); for (PathSegments.Segment matrixSegment : matrixSegments) { - matrixSegment.writeCreateSegment(writer, ctx.platform()); + matrixSegment.writeCreateSegment(writer, platform()); } final List params = method.params(); diff --git a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerWriter.java b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerWriter.java index 6ce5dcc91..c3faeb3a0 100644 --- a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerWriter.java +++ b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerWriter.java @@ -1,5 +1,6 @@ package io.avaje.http.generator.jex; +import static io.avaje.http.generator.core.ProcessingContext.diAnnotation; import io.avaje.http.generator.core.*; import java.io.IOException; @@ -13,8 +14,8 @@ class ControllerWriter extends BaseControllerWriter { private static final String API_ROUTING = "io.avaje.jex.Routing"; private static final String API_ROUTING_SERVICE = "io.avaje.jex.Routing.Service"; - ControllerWriter(ControllerReader reader, ProcessingContext ctx) throws IOException { - super(reader, ctx); + ControllerWriter(ControllerReader reader) throws IOException { + super(reader); reader.addImportType(API_ROUTING); reader.addImportType(API_ROUTING_SERVICE); } @@ -39,15 +40,15 @@ private void writeAddRoutes() { } private void writeForMethod(MethodReader method) { - new ControllerMethodWriter(method, writer, ctx).write(isRequestScoped()); + new ControllerMethodWriter(method, writer).write(isRequestScoped()); if (!reader.isDocHidden()) { - method.buildApiDocumentation(ctx); + method.buildApiDocumentation(); } } private void writeClassStart() { writer.append(AT_GENERATED).eol(); - writer.append(ctx.diAnnotation()).eol(); + writer.append(diAnnotation()).eol(); writer.append("public class ").append(shortName).append("$Route implements Routing.Service {").eol().eol(); String controllerName = "controller"; diff --git a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/JexProcessor.java b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/JexProcessor.java index dfcb5b244..922a23565 100644 --- a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/JexProcessor.java +++ b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/JexProcessor.java @@ -3,7 +3,6 @@ import io.avaje.http.generator.core.BaseProcessor; import io.avaje.http.generator.core.ControllerReader; import io.avaje.http.generator.core.PlatformAdapter; -import io.avaje.http.generator.core.ProcessingContext; import java.io.IOException; @@ -15,7 +14,7 @@ protected PlatformAdapter providePlatformAdapter() { } @Override - public void writeControllerAdapter(ProcessingContext ctx, ControllerReader reader) throws IOException { - new ControllerWriter(reader, ctx).write(); + public void writeControllerAdapter(ControllerReader reader) throws IOException { + new ControllerWriter(reader).write(); } } diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java index 1e5371060..11d12d5d8 100644 --- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java +++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java @@ -1,5 +1,6 @@ package io.avaje.http.generator.helidon.nima; +import static io.avaje.http.generator.core.ProcessingContext.platform; import java.util.List; import java.util.Optional; @@ -8,7 +9,6 @@ import io.avaje.http.generator.core.MethodReader; import io.avaje.http.generator.core.ParamType; import io.avaje.http.generator.core.PathSegments; -import io.avaje.http.generator.core.ProcessingContext; import io.avaje.http.generator.core.UType; import io.avaje.http.generator.core.WebMethod; import io.avaje.http.generator.core.openapi.MediaType; @@ -21,14 +21,12 @@ class ControllerMethodWriter { private final MethodReader method; private final Append writer; private final WebMethod webMethod; - private final ProcessingContext ctx; private final boolean useJsonB; - ControllerMethodWriter(MethodReader method, Append writer, ProcessingContext ctx, boolean useJsonB) { + ControllerMethodWriter(MethodReader method, Append writer, boolean useJsonB) { this.method = method; this.writer = writer; this.webMethod = method.webMethod(); - this.ctx = ctx; this.useJsonB = useJsonB; } @@ -78,7 +76,7 @@ void writeHandler(boolean requestScoped) { } final var matrixSegments = segments.matrixSegments(); for (final PathSegments.Segment matrixSegment : matrixSegments) { - matrixSegment.writeCreateSegment(writer, ctx.platform()); + matrixSegment.writeCreateSegment(writer, platform()); } final var params = method.params(); diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java index 754fa5828..ff155735e 100644 --- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java +++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java @@ -1,5 +1,6 @@ package io.avaje.http.generator.helidon.nima; +import static io.avaje.http.generator.core.ProcessingContext.diAnnotation; import io.avaje.http.generator.core.*; import java.io.IOException; @@ -15,8 +16,8 @@ class ControllerWriter extends BaseControllerWriter { private final boolean useJsonB; private final Map jsonTypes; - ControllerWriter(ControllerReader reader, ProcessingContext ctx, boolean jsonB) throws IOException { - super(reader, ctx); + ControllerWriter(ControllerReader reader, boolean jsonB) throws IOException { + super(reader); this.useJsonB = jsonB; if (useJsonB) { reader.addImportType("io.avaje.jsonb.Jsonb"); @@ -49,7 +50,7 @@ void write() { private List writerMethods() { return reader.methods().stream() .filter(MethodReader::isWebMethod) - .map(it -> new ControllerMethodWriter(it, writer, ctx, useJsonB)) + .map(it -> new ControllerMethodWriter(it, writer, useJsonB)) .toList(); } @@ -76,7 +77,7 @@ private void writeRoutes(List methods) { private void writeClassStart() { writer.append(AT_GENERATED).eol(); - writer.append(ctx.diAnnotation()).eol(); + writer.append(diAnnotation()).eol(); writer.append("public class %s$Route implements HttpService {", shortName).eol().eol(); var controllerName = "controller"; diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/NimaProcessor.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/NimaProcessor.java index 67461a37e..cb0311a0b 100644 --- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/NimaProcessor.java +++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/NimaProcessor.java @@ -22,7 +22,7 @@ protected PlatformAdapter providePlatformAdapter() { } @Override - public void writeControllerAdapter(ProcessingContext ctx, ControllerReader reader) throws IOException { - new ControllerWriter(reader, ctx, jsonB).write(); + public void writeControllerAdapter(ControllerReader reader) throws IOException { + new ControllerWriter(reader, jsonB).write(); } } diff --git a/tests/test-nima-jsonb/.factorypath b/tests/test-nima-jsonb/.factorypath index 741f86c2a..8eb4b4952 100644 --- a/tests/test-nima-jsonb/.factorypath +++ b/tests/test-nima-jsonb/.factorypath @@ -1,16 +1,10 @@ - - - - - - - - - - + + + + - - + + From 7bb49827dce88cb0c938d8a2198a340f6e72c5e8 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Wed, 1 Mar 2023 18:57:05 -0500 Subject: [PATCH 0653/1323] Update .factorypath --- tests/test-nima-jsonb/.factorypath | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/tests/test-nima-jsonb/.factorypath b/tests/test-nima-jsonb/.factorypath index 8eb4b4952..741f86c2a 100644 --- a/tests/test-nima-jsonb/.factorypath +++ b/tests/test-nima-jsonb/.factorypath @@ -1,10 +1,16 @@ - - - - + + + + + + + + + + - - + + From 8e80643649ba3dc50155f6dc0b40d4424199201b Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Wed, 1 Mar 2023 19:02:18 -0500 Subject: [PATCH 0654/1323] prism version --- http-generator-core/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 5fe20cb2e..a70846ee2 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -15,7 +15,7 @@ io.avaje avaje-prisms - 1.4 + 1.5 true provided @@ -83,7 +83,7 @@ io.avaje avaje-prisms - 1.4 + 1.5 From 69f0979fc134c7256a80300be4622ca57ea3b3b0 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Wed, 1 Mar 2023 19:43:37 -0500 Subject: [PATCH 0655/1323] catch enum illegal state exception --- .../java/io/avaje/http/api/PathTypeConversion.java | 12 +++++++++++- .../java/io/avaje/http/generator/core/TypeMap.java | 4 ++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/http-api/src/main/java/io/avaje/http/api/PathTypeConversion.java b/http-api/src/main/java/io/avaje/http/api/PathTypeConversion.java index 260f4310b..15680c916 100644 --- a/http-api/src/main/java/io/avaje/http/api/PathTypeConversion.java +++ b/http-api/src/main/java/io/avaje/http/api/PathTypeConversion.java @@ -64,7 +64,17 @@ public static int asInt(String value) { checkNull(value); try { return Integer.parseInt(value); - } catch (NumberFormatException e) { + } catch (final NumberFormatException e) { + throw new InvalidPathArgumentException(e); + } + } + + /** Convert to enum. */ + public static Enum asEnum(Class clazz, String value) { + checkNull(value); + try { + return Enum.valueOf((Class) clazz, value.toUpperCase()); + } catch (final IllegalArgumentException e) { throw new InvalidPathArgumentException(e); } } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/TypeMap.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/TypeMap.java index 1d0a481e3..bed872cd3 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/TypeMap.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/TypeMap.java @@ -310,7 +310,7 @@ static class EnumHandler extends ObjectHandler { @Override public String toMethod() { - return type.shortType() + ".valueOf("; + return "(" + type.shortType() + ") asEnum(" + type.shortType() + ".class,"; } @Override @@ -334,7 +334,7 @@ static class CollectionHandler implements TypeHandler { (set ? "set" : "list") + "(" + (isEnum - ? handler.toMethod().replace(".", "::").replace("(", "") + ? "qp -> " + handler.toMethod() + " qp)" : "PathTypeConversion::" + shortName) + ", "; From 47230f6ff43665e1a062fb6251edb3bbc049760a Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Wed, 1 Mar 2023 23:21:45 -0500 Subject: [PATCH 0656/1323] update validator plugin --- http-hibernate-validator/pom.xml | 2 +- .../io/avaje/http/hibernate/validator/ValidatorProvider.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/http-hibernate-validator/pom.xml b/http-hibernate-validator/pom.xml index 01f63773b..a016b8bc8 100644 --- a/http-hibernate-validator/pom.xml +++ b/http-hibernate-validator/pom.xml @@ -43,7 +43,7 @@ io.avaje avaje-inject - 8.12-RC1 + 8.13 provided diff --git a/http-hibernate-validator/src/main/java/io/avaje/http/hibernate/validator/ValidatorProvider.java b/http-hibernate-validator/src/main/java/io/avaje/http/hibernate/validator/ValidatorProvider.java index 78f7b7bb8..ce2d3356a 100644 --- a/http-hibernate-validator/src/main/java/io/avaje/http/hibernate/validator/ValidatorProvider.java +++ b/http-hibernate-validator/src/main/java/io/avaje/http/hibernate/validator/ValidatorProvider.java @@ -15,6 +15,6 @@ public Class[] provides() { @Override public void apply(BeanScopeBuilder builder) { - builder.provideDefault(Validator.class, BeanValidator::new); + builder.provideDefault(null, Validator.class, BeanValidator::new); } } \ No newline at end of file From 17c87a9f007d44c416d2463bf322cd9a7c00bb36 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Sat, 4 Mar 2023 00:08:10 +1300 Subject: [PATCH 0657/1323] Version 1.28 --- http-api/pom.xml | 2 +- http-client-gson-adapter/pom.xml | 6 +- http-client/pom.xml | 4 +- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 4 +- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-generator-nima/pom.xml | 2 +- pom.xml | 2 +- tests/pom.xml | 2 +- .../src/main/resources/public/openapi.json | 214 +++++++++++++++++- .../src/main/resources/public/openapi.json | 136 +++++++++++ tests/test-nima-jsonb/.factorypath | 2 +- 14 files changed, 363 insertions(+), 19 deletions(-) diff --git a/http-api/pom.xml b/http-api/pom.xml index adfc4ee2d..b7408637e 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.28-SNAPSHOT + 1.28 .. diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index 8efb1705b..a5ebf2654 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,13 +4,13 @@ io.avaje avaje-http-parent - 1.28-SNAPSHOT + 1.28 .. io.avaje avaje-http-client-gson - 1.28-SNAPSHOT + 1.28 @@ -23,7 +23,7 @@ io.avaje avaje-http-client - 1.28-SNAPSHOT + 1.28 provided diff --git a/http-client/pom.xml b/http-client/pom.xml index 1eb33af63..99cad40d5 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,13 +4,13 @@ io.avaje avaje-http-parent - 1.28-SNAPSHOT + 1.28 .. io.avaje avaje-http-client - 1.28-SNAPSHOT + 1.28 scm:git:git@github.com:avaje/avaje-http-client.git diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index d8bfbc625..d2c933e14 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -5,7 +5,7 @@ io.avaje avaje-http-parent - 1.28-SNAPSHOT + 1.28 .. diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index a70846ee2..5acc1f248 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-parent - 1.28-SNAPSHOT + 1.28 .. @@ -23,7 +23,7 @@ io.avaje avaje-http-api - 1.28-SNAPSHOT + 1.28 true provided diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index b77263ce2..bd319967e 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-parent - 1.28-SNAPSHOT + 1.28 .. diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index 071841f35..d15e160cd 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-parent - 1.28-SNAPSHOT + 1.28 .. diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index e27fd40ad..696a459f2 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-parent - 1.28-SNAPSHOT + 1.28 .. diff --git a/http-generator-nima/pom.xml b/http-generator-nima/pom.xml index f0eb2734e..e387eb591 100644 --- a/http-generator-nima/pom.xml +++ b/http-generator-nima/pom.xml @@ -3,7 +3,7 @@ avaje-http-parent io.avaje - 1.28-SNAPSHOT + 1.28 4.0.0 diff --git a/pom.xml b/pom.xml index 8aec62826..ee9c54f5e 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-parent - 1.28-SNAPSHOT + 1.28 pom diff --git a/tests/pom.xml b/tests/pom.xml index 0700bacb5..d5ecff33d 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -20,7 +20,7 @@ 2.14.1 2.5 8.12-RC3 - 1.28-SNAPSHOT + 1.28 diff --git a/tests/test-javalin-jsonb/src/main/resources/public/openapi.json b/tests/test-javalin-jsonb/src/main/resources/public/openapi.json index f56485ba9..02e11d26e 100644 --- a/tests/test-javalin-jsonb/src/main/resources/public/openapi.json +++ b/tests/test-javalin-jsonb/src/main/resources/public/openapi.json @@ -1,18 +1,18 @@ { "openapi" : "3.0.1", "info" : { - "title" : "Example service", + "title" : "Example service showing off the Path extension method of controller", "description" : "Example Javalin controllers with Java and Maven", "version" : "" }, "tags" : [ { "name" : "tag1", - "description" : "it's somethin" + "description" : "this is added to openapi tags" }, { "name" : "tag1", - "description" : "this is added to openapi tags" + "description" : "it's somethin" } ], "paths" : { @@ -1139,6 +1139,184 @@ } } }, + "/test/enumForm" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "requestBody" : { + "content" : { + "application/x-www-form-urlencoded" : { + "schema" : { + "type" : "object", + "properties" : { + "s" : { + "type" : "string" + }, + "type" : { + "$ref" : "#/components/schemas/ServerType" + } + } + } + } + }, + "required" : true + }, + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/test/enumFormParam" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "requestBody" : { + "content" : { + "application/x-www-form-urlencoded" : { + "schema" : { + "type" : "object", + "properties" : { + "s" : { + "type" : "string" + }, + "type" : { + "$ref" : "#/components/schemas/ServerType" + } + } + } + } + }, + "required" : true + }, + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/test/enumQuery" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "parameters" : [ + { + "name" : "type", + "in" : "query", + "schema" : { + "$ref" : "#/components/schemas/ServerType" + } + } + ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/test/enumQuery2" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "parameters" : [ + { + "name" : "type", + "in" : "query", + "schema" : { + "type" : "array", + "items" : { + "$ref" : "#/components/schemas/ServerType" + } + } + } + ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/test/enumQueryImplied" : { + "post" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "parameters" : [ + { + "name" : "s", + "in" : "query", + "schema" : { + "type" : "string" + } + }, + { + "name" : "type", + "in" : "query", + "schema" : { + "$ref" : "#/components/schemas/ServerType" + } + } + ], + "responses" : { + "201" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, "/test/form" : { "post" : { "tags" : [ @@ -1309,6 +1487,27 @@ } } }, + "/test/mapTest" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, "/test/person" : { "post" : { "tags" : [ @@ -1619,6 +1818,12 @@ "maxLength" : 100, "type" : "string", "format" : "email" + }, + "addresses" : { + "type" : "array", + "items" : { + "type" : "string" + } } } }, @@ -1698,6 +1903,9 @@ } } }, + "ServerType" : { + "type" : "object" + }, "byte" : { "type" : "object" } diff --git a/tests/test-jex/src/main/resources/public/openapi.json b/tests/test-jex/src/main/resources/public/openapi.json index fb4378388..8dc579692 100644 --- a/tests/test-jex/src/main/resources/public/openapi.json +++ b/tests/test-jex/src/main/resources/public/openapi.json @@ -178,6 +178,139 @@ } } }, + "/test/enumQuery" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "parameters" : [ + { + "name" : "type", + "in" : "query", + "schema" : { + "$ref" : "#/components/schemas/ServerType" + } + } + ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/test/enumQuery2" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "parameters" : [ + { + "name" : "type", + "in" : "query", + "schema" : { + "type" : "array", + "items" : { + "$ref" : "#/components/schemas/ServerType" + } + } + } + ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/test/enumQueryImplied" : { + "post" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "parameters" : [ + { + "name" : "s", + "in" : "query", + "schema" : { + "type" : "string" + } + }, + { + "name" : "type", + "in" : "query", + "schema" : { + "$ref" : "#/components/schemas/ServerType" + } + } + ], + "responses" : { + "201" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/test/paramMulti" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "parameters" : [ + { + "name" : "strings", + "in" : "query", + "schema" : { + "type" : "array", + "items" : { + "type" : "string" + } + } + } + ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, "/withDefault/{name}" : { "get" : { "tags" : [ @@ -232,6 +365,9 @@ "nullable" : false } } + }, + "ServerType" : { + "type" : "object" } } } diff --git a/tests/test-nima-jsonb/.factorypath b/tests/test-nima-jsonb/.factorypath index 741f86c2a..6729750e9 100644 --- a/tests/test-nima-jsonb/.factorypath +++ b/tests/test-nima-jsonb/.factorypath @@ -1,7 +1,7 @@ - + From cc4e36b06ad79c8730d42796a302ded57c8ef122 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Sat, 4 Mar 2023 00:15:23 +1300 Subject: [PATCH 0658/1323] Bump to 1.29-SNAPSHOT --- http-api/pom.xml | 2 +- http-client-gson-adapter/pom.xml | 6 +++--- http-client/pom.xml | 4 ++-- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 4 ++-- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-generator-nima/pom.xml | 2 +- pom.xml | 2 +- tests/pom.xml | 2 +- tests/test-nima-jsonb/.factorypath | 2 +- 12 files changed, 16 insertions(+), 16 deletions(-) diff --git a/http-api/pom.xml b/http-api/pom.xml index b7408637e..366092c5b 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.28 + 1.29-SNAPSHOT .. diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index a5ebf2654..d12ef3f60 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,13 +4,13 @@ io.avaje avaje-http-parent - 1.28 + 1.29-SNAPSHOT .. io.avaje avaje-http-client-gson - 1.28 + 1.29-SNAPSHOT @@ -23,7 +23,7 @@ io.avaje avaje-http-client - 1.28 + 1.29-SNAPSHOT provided diff --git a/http-client/pom.xml b/http-client/pom.xml index 99cad40d5..afa3d71e0 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,13 +4,13 @@ io.avaje avaje-http-parent - 1.28 + 1.29-SNAPSHOT .. io.avaje avaje-http-client - 1.28 + 1.29-SNAPSHOT scm:git:git@github.com:avaje/avaje-http-client.git diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index d2c933e14..6496f28ff 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -5,7 +5,7 @@ io.avaje avaje-http-parent - 1.28 + 1.29-SNAPSHOT .. diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 5acc1f248..7d762b7bd 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-parent - 1.28 + 1.29-SNAPSHOT .. @@ -23,7 +23,7 @@ io.avaje avaje-http-api - 1.28 + 1.29-SNAPSHOT true provided diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index bd319967e..26fdffde1 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-parent - 1.28 + 1.29-SNAPSHOT .. diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index d15e160cd..f8b87d575 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-parent - 1.28 + 1.29-SNAPSHOT .. diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index 696a459f2..8ce76ea67 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -7,7 +7,7 @@ io.avaje avaje-http-parent - 1.28 + 1.29-SNAPSHOT .. diff --git a/http-generator-nima/pom.xml b/http-generator-nima/pom.xml index e387eb591..9a5751079 100644 --- a/http-generator-nima/pom.xml +++ b/http-generator-nima/pom.xml @@ -3,7 +3,7 @@ avaje-http-parent io.avaje - 1.28 + 1.29-SNAPSHOT 4.0.0 diff --git a/pom.xml b/pom.xml index ee9c54f5e..b0cb17b20 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-parent - 1.28 + 1.29-SNAPSHOT pom diff --git a/tests/pom.xml b/tests/pom.xml index d5ecff33d..bacc91acc 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -20,7 +20,7 @@ 2.14.1 2.5 8.12-RC3 - 1.28 + 1.29-SNAPSHOT diff --git a/tests/test-nima-jsonb/.factorypath b/tests/test-nima-jsonb/.factorypath index 6729750e9..7506fe785 100644 --- a/tests/test-nima-jsonb/.factorypath +++ b/tests/test-nima-jsonb/.factorypath @@ -1,7 +1,7 @@ - + From dcad850c2f8606ec592fc2f61b41e3e1f4001ea4 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Fri, 3 Mar 2023 11:10:28 -0500 Subject: [PATCH 0659/1323] fix client processor overriding OpenAPI --- .../io/avaje/http/generator/client/ClientProcessor.java | 2 +- .../io/avaje/http/generator/core/ProcessingContext.java | 9 ++++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java index 98c0d9fc2..4dc1f5ff2 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java @@ -48,7 +48,7 @@ public SourceVersion getSupportedSourceVersion() { public synchronized void init(ProcessingEnvironment processingEnv) { super.init(processingEnv); this.processingEnv = processingEnv; - ProcessingContext.init(processingEnv, new ClientPlatformAdapter()); + ProcessingContext.init(processingEnv, new ClientPlatformAdapter(), false); } @Override diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java index 3acc651c8..0ee781ff0 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java @@ -37,13 +37,20 @@ public class ProcessingContext { private static String diAnnotation; public static void init(ProcessingEnvironment env, PlatformAdapter adapter) { + init(env, adapter, true); + } + + public static void init(ProcessingEnvironment env, PlatformAdapter adapter, boolean generateOpenAPI) { readAdapter = adapter; messager = env.getMessager(); filer = env.getFiler(); elements = env.getElementUtils(); types = env.getTypeUtils(); openApiAvailable = isTypeAvailable(Constants.OPENAPIDEFINITION); - docContext = new DocContext(env, openApiAvailable); + + if (generateOpenAPI) { + docContext = new DocContext(env, openApiAvailable); + } final var options = env.getOptions(); final var singletonOverride = options.get("useSingleton"); From a8eed7c72a33e9fadd61a1fa120df10719049d05 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Fri, 3 Mar 2023 11:21:07 -0500 Subject: [PATCH 0660/1323] cover our bases against multiple rounds --- .../io/avaje/http/generator/client/ClientProcessor.java | 9 +++++++++ .../io/avaje/http/generator/core/ProcessingContext.java | 4 ++++ 2 files changed, 13 insertions(+) diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java index 4dc1f5ff2..9690576fe 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java @@ -53,6 +53,15 @@ public synchronized void init(ProcessingEnvironment processingEnv) { @Override public boolean process(Set annotations, RoundEnvironment round) { + + final var platform = platform(); + + if (platform instanceof ClientPlatformAdapter) { + + } else { + setPlatform(new ClientPlatformAdapter()); + } + for (final Element controller : round.getElementsAnnotatedWith(typeElement(ClientPrism.PRISM_TYPE))) { writeClient(controller); diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java index 0ee781ff0..016445b02 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java @@ -146,6 +146,10 @@ public static PlatformAdapter platform() { return readAdapter; } + public static void setPlatform(PlatformAdapter platform) { + readAdapter = platform; + } + public static String diAnnotation() { return diAnnotation; } From c95a21ca3f9f9329b48c4a6f026417a7e10acada Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Fri, 3 Mar 2023 11:25:55 -0500 Subject: [PATCH 0661/1323] Update ProcessingContext.java --- .../java/io/avaje/http/generator/core/ProcessingContext.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java index 016445b02..d4ebdb5a7 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java @@ -46,9 +46,9 @@ public static void init(ProcessingEnvironment env, PlatformAdapter adapter, bool filer = env.getFiler(); elements = env.getElementUtils(); types = env.getTypeUtils(); - openApiAvailable = isTypeAvailable(Constants.OPENAPIDEFINITION); if (generateOpenAPI) { + openApiAvailable = isTypeAvailable(Constants.OPENAPIDEFINITION); docContext = new DocContext(env, openApiAvailable); } From ef62e249ede8d24e7b860ea1d0cf89cc78fa0112 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Fri, 3 Mar 2023 11:33:24 -0500 Subject: [PATCH 0662/1323] Update ClientProcessor.java --- .../java/io/avaje/http/generator/client/ClientProcessor.java | 1 + 1 file changed, 1 insertion(+) diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java index 9690576fe..86ae30660 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java @@ -73,6 +73,7 @@ public boolean process(Set annotations, RoundEnvironment if (round.processingOver()) { writeServicesFile(); } + setPlatform(platform); return false; } From c4b611e0afda846d024ea8d8f26af2af4070d8ef Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Wed, 8 Mar 2023 10:08:29 +1300 Subject: [PATCH 0663/1323] #175 - Format code only, no effective change --- .../http/generator/client/ClientProcessor.java | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java index 86ae30660..18ad8bcb2 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java @@ -53,21 +53,15 @@ public synchronized void init(ProcessingEnvironment processingEnv) { @Override public boolean process(Set annotations, RoundEnvironment round) { - final var platform = platform(); - - if (platform instanceof ClientPlatformAdapter) { - - } else { + if (!(platform instanceof ClientPlatformAdapter)) { setPlatform(new ClientPlatformAdapter()); } - for (final Element controller : - round.getElementsAnnotatedWith(typeElement(ClientPrism.PRISM_TYPE))) { + for (final Element controller : round.getElementsAnnotatedWith(typeElement(ClientPrism.PRISM_TYPE))) { writeClient(controller); } - for (final Element importedElement : - round.getElementsAnnotatedWith(typeElement(ImportPrism.PRISM_TYPE))) { + for (final Element importedElement : round.getElementsAnnotatedWith(typeElement(ImportPrism.PRISM_TYPE))) { writeForImported(importedElement); } if (round.processingOver()) { @@ -76,7 +70,7 @@ public boolean process(Set annotations, RoundEnvironment setPlatform(platform); return false; } - + private void writeServicesFile() { try { final FileObject metaInfWriter = createMetaInfWriter(METAINF_SERVICES_PROVIDER); @@ -91,7 +85,6 @@ private void writeServicesFile() { } private void writeForImported(Element importedElement) { - ImportPrism.getInstanceOn(importedElement).types().stream() .map(ProcessingContext::asElement) .filter(Objects::nonNull) @@ -108,7 +101,7 @@ private void writeClient(Element controller) { e.printStackTrace(); logError(reader.beanType(), "Failed to write client class " + e); } - } + } } protected String writeClientAdapter(ControllerReader reader) throws IOException { From 54f3f2534f324d47cde1c88804b54b9b6bda8660 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Wed, 8 Mar 2023 11:00:32 +1300 Subject: [PATCH 0664/1323] Version 1.29 --- http-api/pom.xml | 2 +- http-client-gson-adapter/pom.xml | 7 ++----- http-client/pom.xml | 5 +---- http-generator-client/pom.xml | 4 +--- http-generator-core/pom.xml | 10 ++++------ http-generator-helidon/pom.xml | 8 +++----- http-generator-javalin/pom.xml | 8 +++----- http-generator-jex/pom.xml | 8 +++----- http-generator-nima/pom.xml | 4 ++-- pom.xml | 2 +- tests/pom.xml | 12 ++++-------- tests/test-client-generation/pom.xml | 14 +++++++------- tests/test-client/pom.xml | 13 ++++++------- tests/test-helidon/pom.xml | 12 ++++++------ tests/test-javalin-jsonb/pom.xml | 12 ++++++------ tests/test-javalin/pom.xml | 12 ++++++------ tests/test-jex/pom.xml | 12 ++++++------ tests/test-nima-jsonb/pom.xml | 12 ++++++------ tests/test-nima/pom.xml | 10 +++++----- 19 files changed, 73 insertions(+), 94 deletions(-) diff --git a/http-api/pom.xml b/http-api/pom.xml index 366092c5b..cd4e9ef5b 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.29-SNAPSHOT + 1.29 .. diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index d12ef3f60..d94f54ae7 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,13 +4,10 @@ io.avaje avaje-http-parent - 1.29-SNAPSHOT - .. + 1.29 - io.avaje avaje-http-client-gson - 1.29-SNAPSHOT @@ -23,7 +20,7 @@ io.avaje avaje-http-client - 1.29-SNAPSHOT + 1.29 provided diff --git a/http-client/pom.xml b/http-client/pom.xml index afa3d71e0..400312954 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,13 +4,10 @@ io.avaje avaje-http-parent - 1.29-SNAPSHOT - .. + 1.29 - io.avaje avaje-http-client - 1.29-SNAPSHOT scm:git:git@github.com:avaje/avaje-http-client.git diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index 6496f28ff..bd4ccf873 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -1,12 +1,10 @@ 4.0.0 - io.avaje avaje-http-parent - 1.29-SNAPSHOT - .. + 1.29 avaje-http-client-generator diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 7d762b7bd..e81308559 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -1,16 +1,14 @@ 4.0.0 - - avaje-http-generator-core - io.avaje avaje-http-parent - 1.29-SNAPSHOT - .. + 1.29 + avaje-http-generator-core + io.avaje @@ -23,7 +21,7 @@ io.avaje avaje-http-api - 1.29-SNAPSHOT + 1.29 true provided diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index 26fdffde1..02e787a68 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -1,16 +1,14 @@ 4.0.0 - - avaje-http-helidon-generator - io.avaje avaje-http-parent - 1.29-SNAPSHOT - .. + 1.29 + avaje-http-helidon-generator + diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index f8b87d575..79aa40fe7 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -1,16 +1,14 @@ 4.0.0 - - avaje-http-javalin-generator - io.avaje avaje-http-parent - 1.29-SNAPSHOT - .. + 1.29 + avaje-http-javalin-generator + diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index 8ce76ea67..c06d4b32f 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -1,16 +1,14 @@ 4.0.0 - - avaje-http-jex-generator - io.avaje avaje-http-parent - 1.29-SNAPSHOT - .. + 1.29 + avaje-http-jex-generator + diff --git a/http-generator-nima/pom.xml b/http-generator-nima/pom.xml index 9a5751079..7c8e70ef0 100644 --- a/http-generator-nima/pom.xml +++ b/http-generator-nima/pom.xml @@ -1,11 +1,11 @@ + 4.0.0 avaje-http-parent io.avaje - 1.29-SNAPSHOT + 1.29 - 4.0.0 avaje-http-nima-generator diff --git a/pom.xml b/pom.xml index b0cb17b20..8e53f5ec9 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-parent - 1.29-SNAPSHOT + 1.29 pom diff --git a/tests/pom.xml b/tests/pom.xml index bacc91acc..c46d93608 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -2,15 +2,12 @@ 4.0.0 - java11-oss - org.avaje - 3.9 - + avaje-http-parent + io.avaje + 1.29 - io.avaje.http - tests-reactor - 1 + tests pom @@ -20,7 +17,6 @@ 2.14.1 2.5 8.12-RC3 - 1.29-SNAPSHOT diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index 14e31a579..8d7cffd19 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -2,9 +2,9 @@ 4.0.0 - io.avaje.http - tests-reactor - 1 + io.avaje + tests + 1.29 test-client-generation @@ -24,13 +24,13 @@ io.avaje avaje-http-client - ${avaje-http-version} + ${project.version} io.avaje avaje-http-api - ${avaje-http-version} + ${project.version} @@ -102,12 +102,12 @@ io.avaje avaje-http-client-generator - ${avaje-http-version} + ${project.version} io.avaje avaje-http-jex-generator - ${avaje-http-version} + ${project.version} io.avaje diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index d19e6f84d..de1f35537 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -4,13 +4,12 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - io.avaje.http - tests-reactor - 1 + io.avaje + tests + 1.29 test-client - 1 UTF-8 @@ -21,19 +20,19 @@ io.avaje avaje-http-client - ${avaje-http-version} + ${project.version} io.avaje avaje-http-client-gson - ${avaje-http-version} + ${project.version} io.avaje avaje-http-api - ${avaje-http-version} + ${project.version} diff --git a/tests/test-helidon/pom.xml b/tests/test-helidon/pom.xml index 85632e7a3..7cde5378f 100644 --- a/tests/test-helidon/pom.xml +++ b/tests/test-helidon/pom.xml @@ -2,9 +2,9 @@ 4.0.0 - io.avaje.http - tests-reactor - 1 + io.avaje + tests + 1.29 test-helidon @@ -32,7 +32,7 @@ io.avaje avaje-http-api - ${avaje-http-version} + ${project.version} io.avaje @@ -49,7 +49,7 @@ io.avaje avaje-http-helidon-generator - ${avaje-http-version} + ${project.version} provided @@ -111,7 +111,7 @@ io.avaje avaje-http-client - ${avaje-http-version} + ${project.version} test diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index ce4784588..7434f729e 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -3,9 +3,9 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - io.avaje.http - tests-reactor - 1 + io.avaje + tests + 1.29 test-javalin-jsonb @@ -47,7 +47,7 @@ io.avaje avaje-http-api - ${avaje-http-version} + ${project.version} @@ -74,7 +74,7 @@ io.avaje avaje-http-javalin-generator - ${avaje-http-version} + ${project.version} provided @@ -103,7 +103,7 @@ io.avaje avaje-http-client - ${avaje-http-version} + ${project.version} test diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 4e3c3de35..17c7e7c82 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -2,9 +2,9 @@ 4.0.0 - io.avaje.http - tests-reactor - 1 + io.avaje + tests + 1.29 test-javalin @@ -52,7 +52,7 @@ io.avaje avaje-http-api - ${avaje-http-version} + ${project.version} @@ -79,7 +79,7 @@ io.avaje avaje-http-javalin-generator - ${avaje-http-version} + ${project.version} provided @@ -102,7 +102,7 @@ io.avaje avaje-http-client - ${avaje-http-version} + ${project.version} test diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index ff7bd7c44..1c419743f 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -2,9 +2,9 @@ 4.0.0 - io.avaje.http - tests-reactor - 1 + io.avaje + tests + 1.29 test-jex @@ -51,7 +51,7 @@ io.avaje avaje-http-api - ${avaje-http-version} + ${project.version} @@ -78,7 +78,7 @@ io.avaje avaje-http-jex-generator - ${avaje-http-version} + ${project.version} provided @@ -94,7 +94,7 @@ io.avaje avaje-http-client - ${avaje-http-version} + ${project.version} test diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 8e8944f22..a29f5d1cb 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -2,9 +2,9 @@ 4.0.0 - io.avaje.http - tests-reactor - 1 + io.avaje + tests + 1.29 test-nima-jsonb @@ -26,7 +26,7 @@ io.avaje avaje-http-api - ${avaje-http-version} + ${project.version} io.avaje @@ -46,7 +46,7 @@ io.avaje avaje-http-nima-generator - ${avaje-http-version} + ${project.version} test @@ -79,7 +79,7 @@ io.avaje avaje-http-nima-generator - ${avaje-http-version} + ${project.version} io.avaje diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index 2c7e3c451..6bab770e1 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -4,9 +4,9 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - io.avaje.http - tests-reactor - 1 + io.avaje + tests + 1.29 test-nima @@ -27,7 +27,7 @@ io.avaje avaje-http-api - ${avaje-http-version} + ${project.version} io.helidon.nima.webserver @@ -64,7 +64,7 @@ io.avaje avaje-http-nima-generator - ${avaje-http-version} + ${project.version} io.avaje From df5dc3ffeb376391561f101c125b9f45274a7182 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Wed, 8 Mar 2023 11:10:22 +1300 Subject: [PATCH 0665/1323] Bump to version 1.30-SNAPSHOT --- http-api/pom.xml | 2 +- http-client-gson-adapter/pom.xml | 4 ++-- http-client/pom.xml | 2 +- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 4 ++-- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-generator-nima/pom.xml | 2 +- pom.xml | 2 +- tests/pom.xml | 2 +- tests/test-client-generation/pom.xml | 2 +- tests/test-client/pom.xml | 2 +- tests/test-helidon/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- 19 files changed, 21 insertions(+), 21 deletions(-) diff --git a/http-api/pom.xml b/http-api/pom.xml index cd4e9ef5b..f08f6c4c2 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.29 + 1.30-SNAPSHOT .. diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index d94f54ae7..f116ad3bb 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.29 + 1.30-SNAPSHOT avaje-http-client-gson @@ -20,7 +20,7 @@ io.avaje avaje-http-client - 1.29 + 1.30-SNAPSHOT provided diff --git a/http-client/pom.xml b/http-client/pom.xml index 400312954..755bde76f 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.29 + 1.30-SNAPSHOT avaje-http-client diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index bd4ccf873..a0fdef343 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.29 + 1.30-SNAPSHOT avaje-http-client-generator diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index e81308559..6232a9f8a 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.29 + 1.30-SNAPSHOT avaje-http-generator-core @@ -21,7 +21,7 @@ io.avaje avaje-http-api - 1.29 + 1.30-SNAPSHOT true provided diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index 02e787a68..b2c43cf4d 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.29 + 1.30-SNAPSHOT avaje-http-helidon-generator diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index 79aa40fe7..0214b1218 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.29 + 1.30-SNAPSHOT avaje-http-javalin-generator diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index c06d4b32f..6d3d0c183 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.29 + 1.30-SNAPSHOT avaje-http-jex-generator diff --git a/http-generator-nima/pom.xml b/http-generator-nima/pom.xml index 7c8e70ef0..54903be44 100644 --- a/http-generator-nima/pom.xml +++ b/http-generator-nima/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 1.29 + 1.30-SNAPSHOT avaje-http-nima-generator diff --git a/pom.xml b/pom.xml index 8e53f5ec9..9ab455696 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-parent - 1.29 + 1.30-SNAPSHOT pom diff --git a/tests/pom.xml b/tests/pom.xml index c46d93608..0b1531567 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 1.29 + 1.30-SNAPSHOT tests diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index 8d7cffd19..a5c0e60f5 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.29 + 1.30-SNAPSHOT test-client-generation diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index de1f35537..ccc531a21 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 1.29 + 1.30-SNAPSHOT test-client diff --git a/tests/test-helidon/pom.xml b/tests/test-helidon/pom.xml index 7cde5378f..e9271cfc8 100644 --- a/tests/test-helidon/pom.xml +++ b/tests/test-helidon/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.29 + 1.30-SNAPSHOT test-helidon diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 7434f729e..41d0256e9 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 1.29 + 1.30-SNAPSHOT test-javalin-jsonb diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 17c7e7c82..d67af1e51 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.29 + 1.30-SNAPSHOT test-javalin diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 1c419743f..a0451d012 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.29 + 1.30-SNAPSHOT test-jex diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index a29f5d1cb..1a04480f8 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.29 + 1.30-SNAPSHOT test-nima-jsonb diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index 6bab770e1..c7de99d7d 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 1.29 + 1.30-SNAPSHOT test-nima From 3727b1c6874d4b4e9a9baece938afdac84e3b941 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Wed, 8 Mar 2023 17:22:24 -0500 Subject: [PATCH 0666/1323] support inputstream --- .../java/io/avaje/http/generator/core/JsonBUtil.java | 6 ++++-- .../avaje/http/generator/javalin/JavalinAdapter.java | 12 +++++++++--- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java index 1014e88cc..b3555b23a 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java @@ -33,9 +33,9 @@ public static Map jsonTypes(ControllerReader reader) { methodReader -> { addJsonBodyType(methodReader, addToMap); if (!methodReader.isVoid()) { - UType uType = UType.parse(methodReader.returnType()); + var uType = UType.parse(methodReader.returnType()); - if (uType.mainType().equals("java.util.concurrent.CompletableFuture")) { + if ("java.util.concurrent.CompletableFuture".equals(uType.mainType())) { uType = uType.paramRaw(); } @@ -51,6 +51,8 @@ private static void addJsonBodyType(MethodReader methodReader, Consumer a methodReader.params().stream() .filter(MethodParam::isBody) .map(MethodParam::utype) + .filter(s -> !s.full().startsWith("java.io.InputStream")) + .filter(s -> !s.full().startsWith("byte[]")) .forEach(addToMap); } } diff --git a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinAdapter.java b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinAdapter.java index f7fba9b85..a22914629 100644 --- a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinAdapter.java +++ b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinAdapter.java @@ -31,10 +31,16 @@ public boolean isBodyMethodParam() { @Override public String bodyAsClass(UType type) { - if (useJsonB) { - return type.shortName() + "JsonType.fromJson(ctx.bodyInputStream())"; + if (type.full().startsWith("java.io.InputStream")) { + return "ctx.bodyInputStream()"; + } else if (type.full().startsWith("byte[]")) { + return "ctx.bodyAsBytes()"; + } else { + if (useJsonB) { + return type.shortName() + "JsonType.fromJson(ctx.bodyInputStream())"; + } + return "ctx.bodyAsClass(" + type.mainType() + ".class)"; } - return "ctx.bodyAsClass(" + type.mainType() + ".class)"; } @Override From 8223d8bcedefdf1d826fdf3d99ddce477ed6ed8a Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Wed, 8 Mar 2023 17:31:27 -0500 Subject: [PATCH 0667/1323] Update TestController2.java --- .../java/org/example/myapp/web/test/TestController2.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController2.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController2.java index 0de341637..7ca725fc2 100644 --- a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController2.java +++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController2.java @@ -1,5 +1,6 @@ package org.example.myapp.web.test; +import java.io.InputStream; import java.util.List; import java.util.Map; import java.util.Set; @@ -47,4 +48,9 @@ String enumQueryImplied(String s, @QueryParam ServerType type) { String mapTest(Map> strings) { return strings.toString(); } + + @Get("/inputStream") + String mapTest(InputStream stream) { + return stream.toString(); + } } From 1f023ea43ca8a5f2d4c46006b2dcd8771c48afb8 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Wed, 8 Mar 2023 17:49:27 -0500 Subject: [PATCH 0668/1323] nima --- .../helidon/nima/ControllerMethodWriter.java | 34 ++++++++++++------- .../myapp/web/test/TestController2.java | 7 +++- .../main/java/org/example/TestController.java | 6 ++++ 3 files changed, 33 insertions(+), 14 deletions(-) diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java index 11d12d5d8..819140132 100644 --- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java +++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java @@ -1,6 +1,7 @@ package io.avaje.http.generator.helidon.nima; import static io.avaje.http.generator.core.ProcessingContext.platform; + import java.util.List; import java.util.Optional; @@ -53,18 +54,25 @@ void writeHandler(boolean requestScoped) { } else { // use default helidon content negotiation method.params().stream() - .filter(MethodParam::isBody) - .forEach( - param -> { - final var type = param.utype(); - writer.append(" var %s = req.content().as(", method.bodyName()); - if (type.param0() != null) { - writer.append("new io.helidon.common.GenericType<%s>() {}", type.full()); - } else { - writer.append("%s.class", type.full()); - } - writer.append(");").eol(); - }); + .filter(MethodParam::isBody) + .forEach( + param -> { + final var type = param.utype(); + + writer.append(" var %s = req.content()", method.bodyName()); + + if (type.full().startsWith("java.io.InputStream")) { + writer.append(".inputStream();").eol(); + return; + } + writer.append(".as("); + if (type.param0() != null) { + writer.append("new io.helidon.common.GenericType<%s>() {}", type.full()); + } else { + writer.append("%s.class", type.full()); + } + writer.append(");").eol(); + }); } } else if (usesFormParams()) { writer.append(" var formParams = req.content().as(Parameters.class);").eol(); @@ -111,7 +119,7 @@ void writeHandler(boolean requestScoped) { if (!method.isVoid()) { writeContextReturn(); if (producesJson()) { - final UType uType = UType.parse(method.returnType()); + final var uType = UType.parse(method.returnType()); writer.append(" %sJsonType.toJson(result, res.outputStream());", uType.shortName()).eol(); } else { writer.append(" res.send(result);").eol(); diff --git a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController2.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController2.java index 7ca725fc2..0bad2a07c 100644 --- a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController2.java +++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController2.java @@ -50,7 +50,12 @@ String mapTest(Map> strings) { } @Get("/inputStream") - String mapTest(InputStream stream) { + String stream(InputStream stream) { return stream.toString(); } + + @Get("/byteArray") + String bytes(byte[] array) { + return array.toString(); + } } diff --git a/tests/test-nima-jsonb/src/main/java/org/example/TestController.java b/tests/test-nima-jsonb/src/main/java/org/example/TestController.java index 1679dad1d..3644ba151 100644 --- a/tests/test-nima-jsonb/src/main/java/org/example/TestController.java +++ b/tests/test-nima-jsonb/src/main/java/org/example/TestController.java @@ -1,5 +1,6 @@ package org.example; +import java.io.InputStream; import java.util.Set; import io.avaje.http.api.Controller; @@ -45,4 +46,9 @@ String enumMultiQuery(@QueryParam @Default({"FFA", "PROXY"}) Set typ String enumQueryImplied(String s, @QueryParam ServerType type) { return type.name(); } + + @Get("/inputStream") + String stream(InputStream stream) { + return stream.toString(); + } } From 9ca7dbb6e79a395300dfa6afeaaf86b9efd34d35 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Wed, 8 Mar 2023 18:03:15 -0500 Subject: [PATCH 0669/1323] fix nima --- .../generator/helidon/nima/ControllerMethodWriter.java | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java index 819140132..c9dfb90ad 100644 --- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java +++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java @@ -41,7 +41,10 @@ void writeHandler(boolean requestScoped) { writer.append(" private void _%s(ServerRequest req, ServerResponse res) {", method.simpleName()).eol(); final var bodyType = method.bodyType(); if (bodyType != null) { - if (useJsonB) { + + if (bodyType.equals("InputStream")) { + writer.append(" var %s = req.content().inputStream();", method.bodyName()).eol(); + } else if (useJsonB) { final var fieldName = method.params().stream() .filter(MethodParam::isBody) @@ -60,11 +63,6 @@ void writeHandler(boolean requestScoped) { final var type = param.utype(); writer.append(" var %s = req.content()", method.bodyName()); - - if (type.full().startsWith("java.io.InputStream")) { - writer.append(".inputStream();").eol(); - return; - } writer.append(".as("); if (type.param0() != null) { writer.append("new io.helidon.common.GenericType<%s>() {}", type.full()); From a976ee73d6ee0d91839970e1a82bd54834863794 Mon Sep 17 00:00:00 2001 From: ZY Date: Thu, 9 Mar 2023 10:45:30 +0800 Subject: [PATCH 0670/1323] OpenAPI documents support enumeration types --- .../core/openapi/SchemaDocBuilder.java | 17 +++++++++++++++++ .../src/main/java/org/example/web/HelloDto.java | 1 + 2 files changed, 18 insertions(+) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/SchemaDocBuilder.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/SchemaDocBuilder.java index f7b07e1bd..b1b6cd5eb 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/SchemaDocBuilder.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/SchemaDocBuilder.java @@ -3,6 +3,7 @@ import static io.avaje.http.generator.core.Util.typeDef; import io.avaje.http.generator.core.javadoc.Javadoc; +import io.swagger.v3.oas.models.media.StringSchema; import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -11,6 +12,7 @@ import javax.lang.model.element.AnnotationMirror; import javax.lang.model.element.Element; +import javax.lang.model.element.ElementKind; import javax.lang.model.element.Modifier; import javax.lang.model.element.TypeElement; import javax.lang.model.element.VariableElement; @@ -149,9 +151,24 @@ Schema toSchema(TypeMirror type) { if (types.isAssignable(type, iterableType)) { return buildIterableSchema(type); } + Element e = types.asElement(type); + if (e != null && e.getKind() == ElementKind.ENUM) { + return buildEnumSchema(e); + } return buildObjectSchema(type); } + private Schema buildEnumSchema(Element e) { + var schema = new StringSchema(); + e.getEnclosedElements().stream() + .filter(ec -> ec.getKind().equals(ElementKind.ENUM_CONSTANT)) + .forEach(ec -> schema.addEnumItem(ec.getSimpleName().toString())); + + var doc = Javadoc.parse(elements.getDocComment(e)); + schema.setDescription(doc.getDescription()); + return schema; + } + private Schema buildObjectSchema(TypeMirror type) { String objectSchemaKey = getObjectSchemaName(type); diff --git a/tests/test-jex/src/main/java/org/example/web/HelloDto.java b/tests/test-jex/src/main/java/org/example/web/HelloDto.java index 61eb7651a..884fcdb5a 100644 --- a/tests/test-jex/src/main/java/org/example/web/HelloDto.java +++ b/tests/test-jex/src/main/java/org/example/web/HelloDto.java @@ -8,4 +8,5 @@ public class HelloDto { public int id; @NotNull public String name; + public ServerType serverType; } From 9c0188459a3e3e51f257ce602f63109596243f07 Mon Sep 17 00:00:00 2001 From: ZY Date: Thu, 9 Mar 2023 11:18:20 +0800 Subject: [PATCH 0671/1323] optimize --- .../avaje/http/generator/core/openapi/SchemaDocBuilder.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/SchemaDocBuilder.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/SchemaDocBuilder.java index b1b6cd5eb..ec00d047e 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/SchemaDocBuilder.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/SchemaDocBuilder.java @@ -165,7 +165,10 @@ private Schema buildEnumSchema(Element e) { .forEach(ec -> schema.addEnumItem(ec.getSimpleName().toString())); var doc = Javadoc.parse(elements.getDocComment(e)); - schema.setDescription(doc.getDescription()); + var desc = doc.getDescription(); + if (desc != null && !desc.isEmpty()) { + schema.setDescription(desc); + } return schema; } From 48659024028744d5ef1b6cd1b2b54e1ef62b8b59 Mon Sep 17 00:00:00 2001 From: ZY Date: Thu, 9 Mar 2023 11:27:19 +0800 Subject: [PATCH 0672/1323] OpenAPI documents support enumeration types --- .../core/openapi/OpenAPISerializer.java | 2 +- .../src/main/resources/public/openapi.json | 44 ++++++++++++++----- .../src/main/resources/public/openapi.json | 32 +++++++++++--- 3 files changed, 60 insertions(+), 18 deletions(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/OpenAPISerializer.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/OpenAPISerializer.java index e2f751316..c26961899 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/OpenAPISerializer.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/OpenAPISerializer.java @@ -81,7 +81,7 @@ static String serialize(Object obj) throws IllegalAccessException { sb.append(","); } sb.append("\""); - sb.append(field.getName()); + sb.append(field.getName().replace("_enum", "enum")); sb.append("\" : "); write(sb, value); firstField = false; diff --git a/tests/test-javalin-jsonb/src/main/resources/public/openapi.json b/tests/test-javalin-jsonb/src/main/resources/public/openapi.json index 02e11d26e..fe0c66425 100644 --- a/tests/test-javalin-jsonb/src/main/resources/public/openapi.json +++ b/tests/test-javalin-jsonb/src/main/resources/public/openapi.json @@ -1,18 +1,18 @@ { "openapi" : "3.0.1", "info" : { - "title" : "Example service showing off the Path extension method of controller", + "title" : "Example service", "description" : "Example Javalin controllers with Java and Maven", "version" : "" }, "tags" : [ { "name" : "tag1", - "description" : "this is added to openapi tags" + "description" : "it's somethin" }, { "name" : "tag1", - "description" : "it's somethin" + "description" : "this is added to openapi tags" } ], "paths" : { @@ -1156,7 +1156,12 @@ "type" : "string" }, "type" : { - "$ref" : "#/components/schemas/ServerType" + "type" : "string", + "enum" : [ + "PROXY", + "HIDE_N_SEEK", + "FFA" + ] } } } @@ -1195,7 +1200,12 @@ "type" : "string" }, "type" : { - "$ref" : "#/components/schemas/ServerType" + "type" : "string", + "enum" : [ + "PROXY", + "HIDE_N_SEEK", + "FFA" + ] } } } @@ -1229,7 +1239,12 @@ "name" : "type", "in" : "query", "schema" : { - "$ref" : "#/components/schemas/ServerType" + "type" : "string", + "enum" : [ + "PROXY", + "HIDE_N_SEEK", + "FFA" + ] } } ], @@ -1261,7 +1276,12 @@ "schema" : { "type" : "array", "items" : { - "$ref" : "#/components/schemas/ServerType" + "type" : "string", + "enum" : [ + "PROXY", + "HIDE_N_SEEK", + "FFA" + ] } } } @@ -1299,7 +1319,12 @@ "name" : "type", "in" : "query", "schema" : { - "$ref" : "#/components/schemas/ServerType" + "type" : "string", + "enum" : [ + "PROXY", + "HIDE_N_SEEK", + "FFA" + ] } } ], @@ -1903,9 +1928,6 @@ } } }, - "ServerType" : { - "type" : "object" - }, "byte" : { "type" : "object" } diff --git a/tests/test-jex/src/main/resources/public/openapi.json b/tests/test-jex/src/main/resources/public/openapi.json index 8dc579692..cbf18157e 100644 --- a/tests/test-jex/src/main/resources/public/openapi.json +++ b/tests/test-jex/src/main/resources/public/openapi.json @@ -190,7 +190,12 @@ "name" : "type", "in" : "query", "schema" : { - "$ref" : "#/components/schemas/ServerType" + "type" : "string", + "enum" : [ + "PROXY", + "HIDE_N_SEEK", + "FFA" + ] } } ], @@ -222,7 +227,12 @@ "schema" : { "type" : "array", "items" : { - "$ref" : "#/components/schemas/ServerType" + "type" : "string", + "enum" : [ + "PROXY", + "HIDE_N_SEEK", + "FFA" + ] } } } @@ -260,7 +270,12 @@ "name" : "type", "in" : "query", "schema" : { - "$ref" : "#/components/schemas/ServerType" + "type" : "string", + "enum" : [ + "PROXY", + "HIDE_N_SEEK", + "FFA" + ] } } ], @@ -363,11 +378,16 @@ "name" : { "type" : "string", "nullable" : false + }, + "serverType" : { + "type" : "string", + "enum" : [ + "PROXY", + "HIDE_N_SEEK", + "FFA" + ] } } - }, - "ServerType" : { - "type" : "object" } } } From de550e643548e4995068ce76c46a364876efa0b3 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Wed, 8 Mar 2023 23:25:34 -0500 Subject: [PATCH 0673/1323] beanParam openAPI --- .../http/generator/core/ElementReader.java | 5 ++-- .../http/generator/core/MethodParam.java | 27 ++++++++++++++++--- .../org/example/myapp/web/GetBeanForm.java | 9 +++++++ 3 files changed, 36 insertions(+), 5 deletions(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java index 3da9a4b27..c8973b2e0 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java @@ -1,7 +1,8 @@ package io.avaje.http.generator.core; -import static io.avaje.http.generator.core.ProcessingContext.*; import static io.avaje.http.generator.core.ParamType.RESPONSE_HANDLER; +import static io.avaje.http.generator.core.ProcessingContext.platform; +import static io.avaje.http.generator.core.ProcessingContext.typeElement; import java.util.List; import java.util.Objects; @@ -245,7 +246,7 @@ void writeParamName(Append writer) { * Build the OpenAPI documentation for this parameter. */ void buildApiDocumentation(MethodDocBuilder methodDoc) { - if (!isPlatformContext() && !isParamMap) { + if (!isPlatformContext() && !isParamMap && paramType != ParamType.BEANPARAM) { new MethodParamDocBuilder(methodDoc, this).build(); } } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodParam.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodParam.java index d212027c3..0028e88f8 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodParam.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodParam.java @@ -1,9 +1,12 @@ package io.avaje.http.generator.core; -import io.avaje.http.generator.core.openapi.MethodDocBuilder; +import static io.avaje.http.generator.core.ProcessingContext.asElement; +import javax.lang.model.element.ElementKind; import javax.lang.model.element.VariableElement; +import io.avaje.http.generator.core.openapi.MethodDocBuilder; + public class MethodParam { private final ElementReader elementParam; @@ -29,8 +32,26 @@ public void buildParamName(Append writer) { } public void buildApiDocumentation(MethodDocBuilder methodDoc) { - elementParam.buildApiDocumentation(methodDoc); - } + if (elementParam.paramType() != ParamType.BEANPARAM) + elementParam.buildApiDocumentation(methodDoc); + else { + asElement(elementParam.element().asType()).getEnclosedElements().stream() + .filter(e -> e.getKind() == ElementKind.FIELD) + .map(VariableElement.class::cast) + .forEach( + e -> { + final var typeMirror = e.asType(); + + new ElementReader( + e, + Util.parse(typeMirror.toString()), + Util.typeDef(typeMirror), + ParamType.QUERYPARAM, + false) + .buildApiDocumentation(methodDoc); + }); + } + } public boolean isBody() { return elementParam.paramType() == ParamType.BODY; diff --git a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/GetBeanForm.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/GetBeanForm.java index fe0b552f0..a821a1f66 100644 --- a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/GetBeanForm.java +++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/GetBeanForm.java @@ -7,6 +7,7 @@ import javax.validation.constraints.NotNull; import javax.validation.constraints.Size; +import io.avaje.http.api.Header; import io.avaje.jsonb.Json; @Json @@ -22,6 +23,8 @@ public class GetBeanForm { private String email; private List addresses; + @Header + private String head; public String getName() { return name; @@ -56,4 +59,10 @@ public List getAddresses() { public void setAddresses(List addresses) { this.addresses = addresses; } + +public String getHead() { +return head;} + +public void setHead(String head) { +this.head = head;} } From 747a690a3708949f0c2484fa88ddfaeb37dd4f91 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Wed, 8 Mar 2023 23:28:38 -0500 Subject: [PATCH 0674/1323] format --- .../java/io/avaje/http/generator/core/MethodParam.java | 2 +- .../main/java/org/example/myapp/web/GetBeanForm.java | 10 ++++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodParam.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodParam.java index 0028e88f8..3b5967ae6 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodParam.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodParam.java @@ -51,7 +51,7 @@ public void buildApiDocumentation(MethodDocBuilder methodDoc) { .buildApiDocumentation(methodDoc); }); } - } + } public boolean isBody() { return elementParam.paramType() == ParamType.BODY; diff --git a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/GetBeanForm.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/GetBeanForm.java index a821a1f66..a74b0f3cd 100644 --- a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/GetBeanForm.java +++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/GetBeanForm.java @@ -60,9 +60,11 @@ public void setAddresses(List addresses) { this.addresses = addresses; } -public String getHead() { -return head;} + public String getHead() { + return head; + } -public void setHead(String head) { -this.head = head;} + public void setHead(String head) { + this.head = head; + } } From c2fa6e2b3309e445c54cd26c56d3962e663e2336 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Thu, 9 Mar 2023 00:30:22 -0500 Subject: [PATCH 0675/1323] keep validation stuff --- .../generator/core/openapi/DocContext.java | 10 ++- .../core/openapi/SchemaDocBuilder.java | 11 ++++ .../src/main/resources/public/openapi.json | 65 ++++++++++++------- 3 files changed, 59 insertions(+), 27 deletions(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/DocContext.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/DocContext.java index bb6b8f0d0..a354c0923 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/DocContext.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/DocContext.java @@ -22,6 +22,7 @@ import io.avaje.http.generator.core.SecuritySchemesPrism; import io.avaje.http.generator.core.TagPrism; import io.avaje.http.generator.core.TagsPrism; +import io.avaje.http.generator.core.Util; import io.swagger.v3.oas.models.Components; import io.swagger.v3.oas.models.OpenAPI; import io.swagger.v3.oas.models.Operation; @@ -77,12 +78,17 @@ private OpenAPI initOpenAPI() { } Schema toSchema(String rawType, Element element) { - TypeElement typeElement = elements.getTypeElement(rawType); + final var typeElement = elements.getTypeElement(rawType); + final var varElement = + elements.getTypeElement(Util.trimAnnotations(element.asType().toString())); + if (typeElement == null) { // primitive types etc return schemaBuilder.toSchema(element.asType()); + } else if (varElement != null) { + return schemaBuilder.toSchema(element); } else { - return schemaBuilder.toSchema(typeElement.asType()); + return schemaBuilder.toSchema(typeElement); } } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/SchemaDocBuilder.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/SchemaDocBuilder.java index f7b07e1bd..e9c851d0b 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/SchemaDocBuilder.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/SchemaDocBuilder.java @@ -132,6 +132,17 @@ private static TypeMirror typeArgument(TypeMirror type) { return typeArguments.get(0); } + Schema toSchema(Element element) { + var schema = toSchema(element.asType()); + + setLengthMinMax(element, schema); + setFormatFromValidation(element, schema); + if (isNotNullable(element)) { + schema.setNullable(Boolean.FALSE); + } + return schema; + } + Schema toSchema(TypeMirror type) { if (types.isAssignable(type, completableFutureType)) { type = typeArgument(type); diff --git a/tests/test-javalin-jsonb/src/main/resources/public/openapi.json b/tests/test-javalin-jsonb/src/main/resources/public/openapi.json index 02e11d26e..d05568105 100644 --- a/tests/test-javalin-jsonb/src/main/resources/public/openapi.json +++ b/tests/test-javalin-jsonb/src/main/resources/public/openapi.json @@ -692,10 +692,39 @@ "description" : "", "parameters" : [ { - "name" : "bean", - "in" : "bean", + "name" : "name", + "in" : "query", "schema" : { - "$ref" : "#/components/schemas/GetBeanForm" + "maxLength" : 150, + "minLength" : 2, + "type" : "string", + "nullable" : false + } + }, + { + "name" : "email", + "in" : "query", + "schema" : { + "maxLength" : 100, + "type" : "string", + "format" : "email" + } + }, + { + "name" : "addresses", + "in" : "query", + "schema" : { + "type" : "array", + "items" : { + "type" : "string" + } + } + }, + { + "name" : "head", + "in" : "header", + "schema" : { + "type" : "string" } } ], @@ -1440,6 +1469,11 @@ } } } + }, + } + } + } + } }, "/test/int" : { "put" : { @@ -1805,28 +1839,6 @@ } } }, - "GetBeanForm" : { - "type" : "object", - "properties" : { - "name" : { - "maxLength" : 150, - "minLength" : 2, - "type" : "string", - "nullable" : false - }, - "email" : { - "maxLength" : 100, - "type" : "string", - "format" : "email" - }, - "addresses" : { - "type" : "array", - "items" : { - "type" : "string" - } - } - } - }, "HelloDto" : { "type" : "object", "properties" : { @@ -1876,6 +1888,9 @@ } } }, + "InputStream" : { + "type" : "object" + }, "MyForm" : { "type" : "object", "properties" : { From bb234b47fee577efefb5fbca3c7a89637ab9384b Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Thu, 9 Mar 2023 00:32:32 -0500 Subject: [PATCH 0676/1323] Update openapi.json --- .../src/main/resources/public/openapi.json | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/tests/test-javalin-jsonb/src/main/resources/public/openapi.json b/tests/test-javalin-jsonb/src/main/resources/public/openapi.json index d05568105..4639b1a89 100644 --- a/tests/test-javalin-jsonb/src/main/resources/public/openapi.json +++ b/tests/test-javalin-jsonb/src/main/resources/public/openapi.json @@ -1154,6 +1154,40 @@ } } }, + "/test/byteArray" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "type" : "array", + "items" : { + "$ref" : "#/components/schemas/byte" + } + } + } + }, + "required" : true + }, + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, "/test/ctx" : { "get" : { "tags" : [ @@ -1470,6 +1504,32 @@ } } }, + "/test/inputStream" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/InputStream" + } + } + }, + "required" : true + }, + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "string" + } + } } } } From fa4c432ba9fa1c6b8947d8ea243209506031d531 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Fri, 10 Mar 2023 14:23:41 +1300 Subject: [PATCH 0677/1323] Bump github actions to v3 --- .github/workflows/build.yml | 6 +++--- .github/workflows/jdk-ea.yml | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index de6874a55..031109b75 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -14,14 +14,14 @@ jobs: os: [ubuntu-latest] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Set up Java - uses: actions/setup-java@v2 + uses: actions/setup-java@v3 with: java-version: ${{ matrix.java_version }} distribution: "zulu" - name: Maven cache - uses: actions/cache@v2 + uses: actions/cache@v3 env: cache-name: maven-cache with: diff --git a/.github/workflows/jdk-ea.yml b/.github/workflows/jdk-ea.yml index d93f51958..71a9bdf27 100644 --- a/.github/workflows/jdk-ea.yml +++ b/.github/workflows/jdk-ea.yml @@ -20,14 +20,14 @@ jobs: os: [ubuntu-latest] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Set up Java uses: oracle-actions/setup-java@v1 with: website: jdk.java.net release: ${{ matrix.java_version }} - name: Maven cache - uses: actions/cache@v2 + uses: actions/cache@v3 env: cache-name: maven-cache with: From a5a5165051f7d4276bab48993eb02d651603323e Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Fri, 10 Mar 2023 15:13:28 +1300 Subject: [PATCH 0678/1323] #179 Tidy up and format for BeanParam OpenAPI --- .../http/generator/core/MethodParam.java | 23 +++++-------- .../generator/core/openapi/DocContext.java | 4 +-- .../core/openapi/SchemaDocBuilder.java | 3 +- .../src/main/resources/public/openapi.json | 6 ++-- .../src/main/resources/public/openapi.json | 34 ++++++++----------- 5 files changed, 29 insertions(+), 41 deletions(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodParam.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodParam.java index 3b5967ae6..c348c045f 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodParam.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodParam.java @@ -32,27 +32,22 @@ public void buildParamName(Append writer) { } public void buildApiDocumentation(MethodDocBuilder methodDoc) { - if (elementParam.paramType() != ParamType.BEANPARAM) + if (elementParam.paramType() != ParamType.BEANPARAM) { elementParam.buildApiDocumentation(methodDoc); - else { + } else { asElement(elementParam.element().asType()).getEnclosedElements().stream() .filter(e -> e.getKind() == ElementKind.FIELD) .map(VariableElement.class::cast) - .forEach( - e -> { - final var typeMirror = e.asType(); - - new ElementReader( - e, - Util.parse(typeMirror.toString()), - Util.typeDef(typeMirror), - ParamType.QUERYPARAM, - false) - .buildApiDocumentation(methodDoc); - }); + .forEach(e -> buildDoc(methodDoc, e)); } } + private static void buildDoc(MethodDocBuilder methodDoc, VariableElement e) { + final var typeMirror = e.asType(); + new ElementReader(e, Util.parse(typeMirror.toString()), Util.typeDef(typeMirror), ParamType.QUERYPARAM, false) + .buildApiDocumentation(methodDoc); + } + public boolean isBody() { return elementParam.paramType() == ParamType.BODY; } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/DocContext.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/DocContext.java index a354c0923..8be2fee4a 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/DocContext.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/DocContext.java @@ -79,9 +79,7 @@ private OpenAPI initOpenAPI() { Schema toSchema(String rawType, Element element) { final var typeElement = elements.getTypeElement(rawType); - final var varElement = - elements.getTypeElement(Util.trimAnnotations(element.asType().toString())); - + final var varElement = elements.getTypeElement(Util.trimAnnotations(element.asType().toString())); if (typeElement == null) { // primitive types etc return schemaBuilder.toSchema(element.asType()); diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/SchemaDocBuilder.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/SchemaDocBuilder.java index 9aeddce76..d5e2a5134 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/SchemaDocBuilder.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/SchemaDocBuilder.java @@ -135,8 +135,7 @@ private static TypeMirror typeArgument(TypeMirror type) { } Schema toSchema(Element element) { - var schema = toSchema(element.asType()); - + final var schema = toSchema(element.asType()); setLengthMinMax(element, schema); setFormatFromValidation(element, schema); if (isNotNullable(element)) { diff --git a/tests/test-javalin-jsonb/src/main/resources/public/openapi.json b/tests/test-javalin-jsonb/src/main/resources/public/openapi.json index 814b5a024..29be3beca 100644 --- a/tests/test-javalin-jsonb/src/main/resources/public/openapi.json +++ b/tests/test-javalin-jsonb/src/main/resources/public/openapi.json @@ -1,18 +1,18 @@ { "openapi" : "3.0.1", "info" : { - "title" : "Example service", + "title" : "Example service showing off the Path extension method of controller", "description" : "Example Javalin controllers with Java and Maven", "version" : "" }, "tags" : [ { "name" : "tag1", - "description" : "it's somethin" + "description" : "this is added to openapi tags" }, { "name" : "tag1", - "description" : "this is added to openapi tags" + "description" : "it's somethin" } ], "paths" : { diff --git a/tests/test-javalin/src/main/resources/public/openapi.json b/tests/test-javalin/src/main/resources/public/openapi.json index d158f7e76..5b8ec8241 100644 --- a/tests/test-javalin/src/main/resources/public/openapi.json +++ b/tests/test-javalin/src/main/resources/public/openapi.json @@ -682,10 +682,22 @@ "description" : "", "parameters" : [ { - "name" : "bean", - "in" : "bean", + "name" : "name", + "in" : "query", "schema" : { - "$ref" : "#/components/schemas/GetBeanForm" + "maxLength" : 150, + "minLength" : 2, + "type" : "string", + "nullable" : false + } + }, + { + "name" : "email", + "in" : "query", + "schema" : { + "maxLength" : 100, + "type" : "string", + "format" : "email" } } ], @@ -835,22 +847,6 @@ } } }, - "GetBeanForm" : { - "type" : "object", - "properties" : { - "name" : { - "maxLength" : 150, - "minLength" : 2, - "type" : "string", - "nullable" : false - }, - "email" : { - "maxLength" : 100, - "type" : "string", - "format" : "email" - } - } - }, "HelloDto" : { "type" : "object", "properties" : { From a0881be0eca4dc54fa2f627d2be6c8bdd9aa15cd Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Fri, 10 Mar 2023 22:12:36 +1300 Subject: [PATCH 0679/1323] Version 1.30 --- http-api/pom.xml | 2 +- http-client-gson-adapter/pom.xml | 4 ++-- http-client/pom.xml | 2 +- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 4 ++-- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-generator-nima/pom.xml | 2 +- pom.xml | 2 +- tests/pom.xml | 2 +- tests/test-client-generation/pom.xml | 2 +- tests/test-client/pom.xml | 2 +- tests/test-helidon/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- 19 files changed, 21 insertions(+), 21 deletions(-) diff --git a/http-api/pom.xml b/http-api/pom.xml index f08f6c4c2..ad5147ecc 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.30-SNAPSHOT + 1.30 .. diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index f116ad3bb..30e360cea 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.30-SNAPSHOT + 1.30 avaje-http-client-gson @@ -20,7 +20,7 @@ io.avaje avaje-http-client - 1.30-SNAPSHOT + 1.30 provided diff --git a/http-client/pom.xml b/http-client/pom.xml index 755bde76f..b191a4973 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.30-SNAPSHOT + 1.30 avaje-http-client diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index a0fdef343..63beb62ca 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.30-SNAPSHOT + 1.30 avaje-http-client-generator diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 6232a9f8a..70a0e20e3 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.30-SNAPSHOT + 1.30 avaje-http-generator-core @@ -21,7 +21,7 @@ io.avaje avaje-http-api - 1.30-SNAPSHOT + 1.30 true provided diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index b2c43cf4d..b85127dd3 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.30-SNAPSHOT + 1.30 avaje-http-helidon-generator diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index 0214b1218..7281f298d 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.30-SNAPSHOT + 1.30 avaje-http-javalin-generator diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index 6d3d0c183..890ad1de4 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.30-SNAPSHOT + 1.30 avaje-http-jex-generator diff --git a/http-generator-nima/pom.xml b/http-generator-nima/pom.xml index 54903be44..dc145d3d2 100644 --- a/http-generator-nima/pom.xml +++ b/http-generator-nima/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 1.30-SNAPSHOT + 1.30 avaje-http-nima-generator diff --git a/pom.xml b/pom.xml index 9ab455696..a688e4478 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-parent - 1.30-SNAPSHOT + 1.30 pom diff --git a/tests/pom.xml b/tests/pom.xml index 0b1531567..d0eb6ae77 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 1.30-SNAPSHOT + 1.30 tests diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index a5c0e60f5..518dd1702 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.30-SNAPSHOT + 1.30 test-client-generation diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index ccc531a21..0874ebb9a 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 1.30-SNAPSHOT + 1.30 test-client diff --git a/tests/test-helidon/pom.xml b/tests/test-helidon/pom.xml index e9271cfc8..7cc1123dd 100644 --- a/tests/test-helidon/pom.xml +++ b/tests/test-helidon/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.30-SNAPSHOT + 1.30 test-helidon diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 41d0256e9..fae67f94c 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 1.30-SNAPSHOT + 1.30 test-javalin-jsonb diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index d67af1e51..09ac7b73d 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.30-SNAPSHOT + 1.30 test-javalin diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index a0451d012..3984087e0 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.30-SNAPSHOT + 1.30 test-jex diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 1a04480f8..94990c7a2 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.30-SNAPSHOT + 1.30 test-nima-jsonb diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index c7de99d7d..2dfd9f498 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 1.30-SNAPSHOT + 1.30 test-nima From 94c52afe5e7ccf4472349cccb2486d8b3c10037d Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Fri, 10 Mar 2023 22:18:15 +1300 Subject: [PATCH 0680/1323] Bump to 1.31-SNAPSHOT --- http-api/pom.xml | 2 +- http-client-gson-adapter/pom.xml | 4 ++-- http-client/pom.xml | 2 +- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 4 ++-- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-generator-nima/pom.xml | 2 +- pom.xml | 2 +- tests/pom.xml | 2 +- tests/test-client-generation/pom.xml | 2 +- tests/test-client/pom.xml | 2 +- tests/test-helidon/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- 19 files changed, 21 insertions(+), 21 deletions(-) diff --git a/http-api/pom.xml b/http-api/pom.xml index ad5147ecc..041f74ff9 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.30 + 1.31-SNAPSHOT .. diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index 30e360cea..25c466d2c 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.30 + 1.31-SNAPSHOT avaje-http-client-gson @@ -20,7 +20,7 @@ io.avaje avaje-http-client - 1.30 + 1.31-SNAPSHOT provided diff --git a/http-client/pom.xml b/http-client/pom.xml index b191a4973..8269bb5bb 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.30 + 1.31-SNAPSHOT avaje-http-client diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index 63beb62ca..11d4133f1 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.30 + 1.31-SNAPSHOT avaje-http-client-generator diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 70a0e20e3..f1b941a74 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.30 + 1.31-SNAPSHOT avaje-http-generator-core @@ -21,7 +21,7 @@ io.avaje avaje-http-api - 1.30 + 1.31-SNAPSHOT true provided diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index b85127dd3..4713365f5 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.30 + 1.31-SNAPSHOT avaje-http-helidon-generator diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index 7281f298d..518e9465e 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.30 + 1.31-SNAPSHOT avaje-http-javalin-generator diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index 890ad1de4..80c6fae4f 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.30 + 1.31-SNAPSHOT avaje-http-jex-generator diff --git a/http-generator-nima/pom.xml b/http-generator-nima/pom.xml index dc145d3d2..0c3b0a25f 100644 --- a/http-generator-nima/pom.xml +++ b/http-generator-nima/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 1.30 + 1.31-SNAPSHOT avaje-http-nima-generator diff --git a/pom.xml b/pom.xml index a688e4478..656dee555 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-parent - 1.30 + 1.31-SNAPSHOT pom diff --git a/tests/pom.xml b/tests/pom.xml index d0eb6ae77..710c05382 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 1.30 + 1.31-SNAPSHOT tests diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index 518dd1702..4dc456ff1 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.30 + 1.31-SNAPSHOT test-client-generation diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index 0874ebb9a..35bd8df4e 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 1.30 + 1.31-SNAPSHOT test-client diff --git a/tests/test-helidon/pom.xml b/tests/test-helidon/pom.xml index 7cc1123dd..d6256a981 100644 --- a/tests/test-helidon/pom.xml +++ b/tests/test-helidon/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.30 + 1.31-SNAPSHOT test-helidon diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index fae67f94c..97b0cbbcc 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 1.30 + 1.31-SNAPSHOT test-javalin-jsonb diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 09ac7b73d..f3ea5587e 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.30 + 1.31-SNAPSHOT test-javalin diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 3984087e0..a64547c46 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.30 + 1.31-SNAPSHOT test-jex diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 94990c7a2..8f457d6e2 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.30 + 1.31-SNAPSHOT test-nima-jsonb diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index 2dfd9f498..906f9cf50 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 1.30 + 1.31-SNAPSHOT test-nima From fd4d04e4830fe6b1bf5e37ad1f5f26a3ffd7f67c Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sun, 12 Mar 2023 17:51:13 -0400 Subject: [PATCH 0681/1323] support subtypes --- http-client/pom.xml | 6 +++--- .../avaje/http/client/DHttpClientContext.java | 4 ++-- .../avaje/http/client/DHttpClientRequest.java | 19 +++++++++++++++---- .../avaje/http/client/HttpClientRequest.java | 11 +++++++++++ .../generator/client/ClientMethodWriter.java | 2 +- http-generator-core/pom.xml | 4 ++-- 6 files changed, 34 insertions(+), 12 deletions(-) diff --git a/http-client/pom.xml b/http-client/pom.xml index 8269bb5bb..4562741e8 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -29,21 +29,21 @@ com.fasterxml.jackson.core jackson-databind - 2.14.1 + 2.14.2 true io.avaje avaje-jsonb - 1.1 + 1.3 true io.avaje avaje-inject - 8.12-RC1 + 8.13 true diff --git a/http-client/src/main/java/io/avaje/http/client/DHttpClientContext.java b/http-client/src/main/java/io/avaje/http/client/DHttpClientContext.java index 786602b0f..81f28287d 100644 --- a/http-client/src/main/java/io/avaje/http/client/DHttpClientContext.java +++ b/http-client/src/main/java/io/avaje/http/client/DHttpClientContext.java @@ -265,8 +265,8 @@ CompletableFuture> sendAsync(HttpRequest.Builder requestBuil return httpClient.sendAsync(requestBuilder.build(), bodyHandler); } - BodyContent write(T bean, String contentType) { - return bodyAdapter.beanWriter(bean.getClass()).write(bean, contentType); + BodyContent write(T bean, Class type, String contentType) { + return bodyAdapter.beanWriter(type).write(bean, contentType); } BodyReader beanReader(Class type) { diff --git a/http-client/src/main/java/io/avaje/http/client/DHttpClientRequest.java b/http-client/src/main/java/io/avaje/http/client/DHttpClientRequest.java index 054ebe00f..5c12444f5 100644 --- a/http-client/src/main/java/io/avaje/http/client/DHttpClientRequest.java +++ b/http-client/src/main/java/io/avaje/http/client/DHttpClientRequest.java @@ -265,15 +265,26 @@ public HttpClientRequest body(BodyContent bodyContent) { return this; } + @Override + public HttpClientRequest body(Object bean) { + return body(bean, bean.getClass(), null); + } + @Override public HttpClientRequest body(Object bean, String contentType) { - encodedRequestBody = context.write(bean, contentType); - return this; + + return body(bean, bean.getClass(), contentType); } @Override - public HttpClientRequest body(Object bean) { - return body(bean, null); + public HttpClientRequest body(Object bean, Class type) { + return body(bean, type, null); + } + + @Override + public HttpClientRequest body(Object bean, Class type, String contentType) { + encodedRequestBody = context.write(bean, type, contentType); + return this; } @Override diff --git a/http-client/src/main/java/io/avaje/http/client/HttpClientRequest.java b/http-client/src/main/java/io/avaje/http/client/HttpClientRequest.java index 4831291ec..6f4e4b65d 100644 --- a/http-client/src/main/java/io/avaje/http/client/HttpClientRequest.java +++ b/http-client/src/main/java/io/avaje/http/client/HttpClientRequest.java @@ -298,6 +298,17 @@ default HttpClientRequest queryParam(String name, Collection values) { */ HttpClientRequest body(Object bean); + /** + * Set the body as a bean with the given content type using a BodyWriter. + * Used for JsonbAdapter + */ + HttpClientRequest body(Object bean, Class type); + + /** + * Set the body as a bean with the given content type using a BodyWriter. + */ + HttpClientRequest body(Object bean, Class type, String contentType); + /** * Set the body content as a string. * diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java index dea5b2e46..201c15a54 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java @@ -251,7 +251,7 @@ private void writeBody() { for (MethodParam param : method.params()) { ParamType paramType = param.paramType(); if (paramType == ParamType.BODY) { - writer.append(" .body(%s)", param.name()).eol(); + writer.append(" .body(%s, %s.class)", param.name(), param.utype().shortType()).eol(); } } } diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index f1b941a74..88cead6b3 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -13,7 +13,7 @@ io.avaje avaje-prisms - 1.5 + 1.6 true provided @@ -81,7 +81,7 @@ io.avaje avaje-prisms - 1.5 + 1.6 From d0e16c535886d2dc2603a81a5b29c2a5b054026a Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Mon, 13 Mar 2023 11:38:22 +1300 Subject: [PATCH 0682/1323] Improve Javadoc only --- .../java/io/avaje/http/client/DHttpApi.java | 8 ++-- .../avaje/http/client/HttpAsyncResponse.java | 22 ++++----- .../avaje/http/client/HttpCallResponse.java | 8 ++-- .../avaje/http/client/HttpClientRequest.java | 45 +++++++++++++------ .../avaje/http/client/HttpClientResponse.java | 2 +- .../io/avaje/http/client/HttpException.java | 4 +- .../avaje/http/client/JacksonBodyAdapter.java | 2 +- .../avaje/http/client/JsonbBodyAdapter.java | 2 +- .../io/avaje/http/client/package-info.java | 4 +- 9 files changed, 57 insertions(+), 40 deletions(-) diff --git a/http-client/src/main/java/io/avaje/http/client/DHttpApi.java b/http-client/src/main/java/io/avaje/http/client/DHttpApi.java index 10ef79676..74c72f2e1 100644 --- a/http-client/src/main/java/io/avaje/http/client/DHttpApi.java +++ b/http-client/src/main/java/io/avaje/http/client/DHttpApi.java @@ -41,19 +41,19 @@ private HttpApiProvider lookup(Class type) { } @SuppressWarnings("unchecked") - T provideFor(Class type, HttpClient clientContext) { + T provideFor(Class type, HttpClient httpClient) { final HttpApiProvider apiProvider = lookup(type); if (apiProvider == null) { throw new IllegalArgumentException("No registered HttpApiProvider for type: " + type); } - return apiProvider.provide(clientContext); + return apiProvider.provide(httpClient); } /** * Return the client implementation via service loading. */ - static T provide(Class type, HttpClient clientContext) { - return INSTANCE.provideFor(type, clientContext); + static T provide(Class type, HttpClient httpClient) { + return INSTANCE.provideFor(type, httpClient); } /** diff --git a/http-client/src/main/java/io/avaje/http/client/HttpAsyncResponse.java b/http-client/src/main/java/io/avaje/http/client/HttpAsyncResponse.java index 8626b4270..a7ec8e3db 100644 --- a/http-client/src/main/java/io/avaje/http/client/HttpAsyncResponse.java +++ b/http-client/src/main/java/io/avaje/http/client/HttpAsyncResponse.java @@ -20,7 +20,7 @@ *

Example using .join() for testing purposes

*
{@code
  *
- *    clientContext.request()
+ *    client.request()
  *       ...
  *       .POST().async()
  *       .bean(HelloDto.class)
@@ -38,7 +38,7 @@
  * In this example POST async that will return a bean converted from json response.
  * 
{@code
  *
- *    clientContext.request()
+ *    client.request()
  *       ...
  *       .POST().async()
  *       .bean(HelloDto.class)
@@ -80,7 +80,7 @@ public interface HttpAsyncResponse {
    *
    * 
{@code
    *
-   *   clientContext.request()
+   *   client.request()
    *       .path("hello/world")
    *       .GET()
    *       .async().asVoid()
@@ -115,7 +115,7 @@ public interface HttpAsyncResponse {
    *
    * 
{@code
    *
-   *   clientContext.request()
+   *   client.request()
    *       .path("hello/world")
    *       .GET()
    *       .async().asDiscarding()
@@ -140,7 +140,7 @@ public interface HttpAsyncResponse {
    *
    * 
{@code
    *
-   *   clientContext.request()
+   *   client.request()
    *       .path("hello/world")
    *       .GET()
    *       .async().asString()
@@ -191,7 +191,7 @@ public interface HttpAsyncResponse {
    * 

*
{@code
    *
-   *    CompletableFuture> future = clientContext.request()
+   *    CompletableFuture> future = client.request()
    *       .path("hello/lineStream")
    *       .GET().async()
    *       .handler(HttpResponse.BodyHandlers.fromLineSubscriber(new Flow.Subscriber<>() {
@@ -240,7 +240,7 @@ default  CompletableFuture> withHandler(HttpResponse.BodyHand
    *
    * 
{@code
    *
-   *    clientContext.request()
+   *    client.request()
    *       ...
    *       .POST().async()
    *       .as(HelloDto.class)
@@ -280,7 +280,7 @@ default  CompletableFuture> withHandler(HttpResponse.BodyHand
    *
    * 
{@code
    *
-   *    clientContext.request()
+   *    client.request()
    *       ...
    *       .POST().async()
    *       .bean(HelloDto.class)
@@ -314,7 +314,7 @@ default  CompletableFuture> withHandler(HttpResponse.BodyHand
    *
    * 
{@code
    *
-   *    clientContext.request()
+   *    client.request()
    *       ...
    *       .POST().async()
    *       .asList(HelloDto.class)
@@ -356,7 +356,7 @@ default  CompletableFuture> withHandler(HttpResponse.BodyHand
    *
    * 
{@code
    *
-   *    clientContext.request()
+   *    client.request()
    *       ...
    *       .GET().async()
    *       .list(HelloDto.class)
@@ -387,7 +387,7 @@ default  CompletableFuture> withHandler(HttpResponse.BodyHand
    *
    * 
{@code
    *
-   *    clientContext.request()
+   *    client.request()
    *       ...
    *       .POST().async()
    *       .asStream(HelloDto.class)
diff --git a/http-client/src/main/java/io/avaje/http/client/HttpCallResponse.java b/http-client/src/main/java/io/avaje/http/client/HttpCallResponse.java
index e7bf1126d..9001106b9 100644
--- a/http-client/src/main/java/io/avaje/http/client/HttpCallResponse.java
+++ b/http-client/src/main/java/io/avaje/http/client/HttpCallResponse.java
@@ -32,7 +32,7 @@ public interface HttpCallResponse {
    * 
{@code
    *
    *   HttpCall> call =
-   *     clientContext.request()
+   *     client.request()
    *       .path("hello/world")
    *       .GET()
    *       .call().asVoid();
@@ -54,7 +54,7 @@ public interface HttpCallResponse {
    * 
{@code
    *
    *   HttpCall> call =
-   *     clientContext.request()
+   *     client.request()
    *       .path("hello/world")
    *       .GET()
    *       .call().asDiscarding();
@@ -71,7 +71,7 @@ public interface HttpCallResponse {
    * 
{@code
    *
    *   HttpCall> call =
-   *     clientContext.request()
+   *     client.request()
    *       .path("hello/world")
    *       .GET()
    *       .call().asString();
@@ -107,7 +107,7 @@ public interface HttpCallResponse {
    * Call using any given {@code HttpResponse.BodyHandler}.
    * 
{@code
    *
-   *    HttpCall call = clientContext.request()
+   *    HttpCall call = client.request()
    *       .path("hello/lineStream")
    *       .GET()
    *       .call().handler(HttpResponse.BodyHandler ...);
diff --git a/http-client/src/main/java/io/avaje/http/client/HttpClientRequest.java b/http-client/src/main/java/io/avaje/http/client/HttpClientRequest.java
index 6f4e4b65d..8362f9045 100644
--- a/http-client/src/main/java/io/avaje/http/client/HttpClientRequest.java
+++ b/http-client/src/main/java/io/avaje/http/client/HttpClientRequest.java
@@ -19,14 +19,14 @@
  *
  * 
{@code
  *
- *  HelloDto dto = clientContext.request()
+ *  HelloDto dto = client.request()
  *       .path("hello").queryParam("name", "Rob").queryParam("say", "Whats up")
  *       .GET()
  *       .bean(HelloDto.class);
  *
  * }
* - * @see HttpClientContext + * @see HttpClient */ public interface HttpClientRequest { @@ -113,7 +113,7 @@ public interface HttpClientRequest { * Add the header to the request implicitly converting the value to a String. If the value is a * collection then it's values are appended with the same key * - * @param name The header name + * @param name The header name * @param value The header value * @return The request being built */ @@ -130,7 +130,7 @@ public interface HttpClientRequest { /** * Add the headers to the request via Collection. * - * @param name The header name + * @param name The header name * @param value The header values * @return The request being built */ @@ -155,7 +155,7 @@ public interface HttpClientRequest { * Set the URL to use replacing the base URL. *
{code
    *
-   *  HttpResponse res = clientContext.request()
+   *  HttpResponse res = client.request()
    *       .url("http://127.0.0.1:8889")
    *       .path("hello")
    *       .GET()
@@ -165,7 +165,7 @@ public interface HttpClientRequest {
    *
    * @param url The url effectively replacing the base url.
    * @return The request being built
-   * @see HttpClientContext.Builder#baseUrl(String)
+   * @see HttpClient.Builder#baseUrl(String)
    */
   HttpClientRequest url(String url);
 
@@ -248,8 +248,8 @@ public interface HttpClientRequest {
   /**
    * Add a query parameter with multiple values
    *
-   * @param name The name of the query parameter
-   * @param value The values of the query parameter which can be null
+   * @param name   The name of the query parameter
+   * @param values The values of the query parameter which can be null
    * @return The request being built
    */
   default HttpClientRequest queryParam(String name, Collection values) {
@@ -293,24 +293,41 @@ default HttpClientRequest queryParam(String name, Collection values) {
   HttpClientRequest body(Object bean, String contentType);
 
   /**
-   * Set the body as a bean using the default content type. The default
-   * content type will often be application/json; charset=utf8.
+   * Set the body as a bean using the default content type.
+   * 

+ * The default content type will often be {@code application/json; charset=utf8}. */ HttpClientRequest body(Object bean); /** - * Set the body as a bean with the given content type using a BodyWriter. - * Used for JsonbAdapter + * Set the body as a bean additionally specifying the type that will be + * used to serialise the content (e.g. JsonbAdapter). + *

+ * Specifying the type allows the bean instance to be a type that extends + * a type that is known to JsonbAdapter / the body content adapter used. + * + * @param bean The body content as an instance + * @param type The type used by the body content adapter to write the body content + * @return The request being built */ HttpClientRequest body(Object bean, Class type); /** - * Set the body as a bean with the given content type using a BodyWriter. + * Set the body as a bean with the given content type and additionally specifying + * the type that will be used to serialise the content (e.g. JsonbAdapter). + *

+ * Specifying the type allows the bean instance to be a type that extends + * a type that is known to JsonbAdapter / the body content adapter used. + * + * @param bean The body content as an instance + * @param type The type used by the body content adapter to write the body content + * @param contentType The content type of the body + * @return The request being built */ HttpClientRequest body(Object bean, Class type, String contentType); /** - * Set the body content as a string. + * Set the body content as a string using the default content type. * * @param body The body content * @return The request being built diff --git a/http-client/src/main/java/io/avaje/http/client/HttpClientResponse.java b/http-client/src/main/java/io/avaje/http/client/HttpClientResponse.java index 6d066c2b9..4695213f8 100644 --- a/http-client/src/main/java/io/avaje/http/client/HttpClientResponse.java +++ b/http-client/src/main/java/io/avaje/http/client/HttpClientResponse.java @@ -21,7 +21,7 @@ public interface HttpClientResponse { * In this example POST async that will return a bean converted from json response. *

{@code
    *
-   *    clientContext.request()
+   *    client.request()
    *       ...
    *       .POST().async()
    *       .bean(HelloDto.class)
diff --git a/http-client/src/main/java/io/avaje/http/client/HttpException.java b/http-client/src/main/java/io/avaje/http/client/HttpException.java
index 0c8302017..f97049fb2 100644
--- a/http-client/src/main/java/io/avaje/http/client/HttpException.java
+++ b/http-client/src/main/java/io/avaje/http/client/HttpException.java
@@ -13,7 +13,7 @@
  * 
{@code
  *
  *   try {
- *       clientContext.request()
+ *       client.request()
  *         .path("hello/saveForm")
  *         .formParam("email", "user@foo.com")
  *         .formParam("url", "notAValidUrl")
@@ -115,7 +115,7 @@ public String bodyAsString() {
     return new String(body.content(), StandardCharsets.UTF_8);
   }
 
-  /** 
+  /**
    * Return the response body content as raw bytes, or else null if body content doesn't exist.
    */
   public byte[] bodyAsBytes() {
diff --git a/http-client/src/main/java/io/avaje/http/client/JacksonBodyAdapter.java b/http-client/src/main/java/io/avaje/http/client/JacksonBodyAdapter.java
index 5aeacf684..30fe0fce4 100644
--- a/http-client/src/main/java/io/avaje/http/client/JacksonBodyAdapter.java
+++ b/http-client/src/main/java/io/avaje/http/client/JacksonBodyAdapter.java
@@ -15,7 +15,7 @@
  *
  * 
{@code
  *
- *   HttpClientContext.builder()
+ *   HttpClient.builder()
  *       .baseUrl(baseUrl)
  *       .bodyAdapter(new JacksonBodyAdapter())
  *       .build();
diff --git a/http-client/src/main/java/io/avaje/http/client/JsonbBodyAdapter.java b/http-client/src/main/java/io/avaje/http/client/JsonbBodyAdapter.java
index 68f1286d9..f09dd3d39 100644
--- a/http-client/src/main/java/io/avaje/http/client/JsonbBodyAdapter.java
+++ b/http-client/src/main/java/io/avaje/http/client/JsonbBodyAdapter.java
@@ -13,7 +13,7 @@
  *
  * 
{@code
  *
- *   HttpClientContext.builder()
+ *   HttpClient.builder()
  *       .baseUrl(baseUrl)
  *       .bodyAdapter(new JsonbBodyAdapter())
  *       .build();
diff --git a/http-client/src/main/java/io/avaje/http/client/package-info.java b/http-client/src/main/java/io/avaje/http/client/package-info.java
index 979003e2d..d0afcb7ea 100644
--- a/http-client/src/main/java/io/avaje/http/client/package-info.java
+++ b/http-client/src/main/java/io/avaje/http/client/package-info.java
@@ -6,12 +6,12 @@
  *
  * 
{@code
  *
- *   HttpClientContext ctx = HttpClientContext.builder()
+ *   HttpClient client = HttpClient.builder()
  *       .baseUrl("http://localhost:8080")
  *       .bodyAdapter(new JacksonBodyAdapter())
  *       .build();
  *
- *  HelloDto dto = ctx.request()
+ *  HelloDto dto = client.request()
  *       .path("hello")
  *       .queryParam("say", "Whats up")
  *       .GET()

From 2661f791233031d574f8979ce08a5cd97fef486b Mon Sep 17 00:00:00 2001
From: Josiah Noel <32279667+SentryMan@users.noreply.github.com>
Date: Sun, 12 Mar 2023 21:17:57 -0400
Subject: [PATCH 0683/1323] support generic body type

---
 .../java/io/avaje/http/client/BodyAdapter.java     | 10 ++++++++++
 .../io/avaje/http/client/DHttpClientContext.java   |  4 ++++
 .../io/avaje/http/client/DHttpClientRequest.java   |  6 ++++++
 .../io/avaje/http/client/HttpClientRequest.java    | 14 ++++++++++++++
 .../io/avaje/http/client/JsonbBodyAdapter.java     |  6 ++++++
 .../http/generator/client/ClientMethodWriter.java  |  3 ++-
 6 files changed, 42 insertions(+), 1 deletion(-)

diff --git a/http-client/src/main/java/io/avaje/http/client/BodyAdapter.java b/http-client/src/main/java/io/avaje/http/client/BodyAdapter.java
index 5d3fa2d5b..31e4efba1 100644
--- a/http-client/src/main/java/io/avaje/http/client/BodyAdapter.java
+++ b/http-client/src/main/java/io/avaje/http/client/BodyAdapter.java
@@ -17,6 +17,16 @@ public interface BodyAdapter {
    */
    BodyWriter beanWriter(Class type);
 
+  /**
+   * Return a BodyWriter to write beans of this type as request content.
+   *
+   * @param type The type of the bean this writer is for
+   */
+  default  BodyWriter beanWriter(ParameterizedType type) {
+
+    throw new UnsupportedOperationException("Parameterized types not supported for this adapter");
+  }
+
   /**
    * Return a BodyReader to read response content and convert to a bean.
    *
diff --git a/http-client/src/main/java/io/avaje/http/client/DHttpClientContext.java b/http-client/src/main/java/io/avaje/http/client/DHttpClientContext.java
index 81f28287d..598110f18 100644
--- a/http-client/src/main/java/io/avaje/http/client/DHttpClientContext.java
+++ b/http-client/src/main/java/io/avaje/http/client/DHttpClientContext.java
@@ -269,6 +269,10 @@  BodyContent write(T bean, Class type, String contentType) {
     return bodyAdapter.beanWriter(type).write(bean, contentType);
   }
 
+   BodyContent write(T bean, ParameterizedType type, String contentType) {
+    return bodyAdapter.beanWriter(type).write(bean, contentType);
+  }
+
    BodyReader beanReader(Class type) {
     return bodyAdapter.beanReader(type);
   }
diff --git a/http-client/src/main/java/io/avaje/http/client/DHttpClientRequest.java b/http-client/src/main/java/io/avaje/http/client/DHttpClientRequest.java
index 5c12444f5..9728fa585 100644
--- a/http-client/src/main/java/io/avaje/http/client/DHttpClientRequest.java
+++ b/http-client/src/main/java/io/avaje/http/client/DHttpClientRequest.java
@@ -281,6 +281,12 @@ public HttpClientRequest body(Object bean, Class type) {
     return body(bean, type, null);
   }
 
+  @Override
+  public HttpClientRequest body(Object bean, ParameterizedType type) {
+    encodedRequestBody = context.write(bean, type, null);
+    return this;
+  }
+
   @Override
   public HttpClientRequest body(Object bean, Class type, String contentType) {
     encodedRequestBody = context.write(bean, type, contentType);
diff --git a/http-client/src/main/java/io/avaje/http/client/HttpClientRequest.java b/http-client/src/main/java/io/avaje/http/client/HttpClientRequest.java
index 8362f9045..c2e846905 100644
--- a/http-client/src/main/java/io/avaje/http/client/HttpClientRequest.java
+++ b/http-client/src/main/java/io/avaje/http/client/HttpClientRequest.java
@@ -1,6 +1,7 @@
 package io.avaje.http.client;
 
 import java.io.InputStream;
+import java.lang.reflect.ParameterizedType;
 import java.net.http.HttpRequest;
 import java.net.http.HttpResponse;
 import java.nio.file.Path;
@@ -312,6 +313,19 @@ default HttpClientRequest queryParam(String name, Collection values) {
    */
   HttpClientRequest body(Object bean, Class type);
 
+  /**
+   * Set the body as a bean additionally specifying the type that will be
+   * used to serialise the content (e.g. JsonbAdapter).
+   * 

+ * Specifying the type allows the bean instance to be a type that extends + * a type that is known to JsonbAdapter / the body content adapter used. + * + * @param bean The body content as an instance + * @param type The parameterized type used by the body content adapter to write the body content + * @return The request being built + */ + HttpClientRequest body(Object bean, ParameterizedType type); + /** * Set the body as a bean with the given content type and additionally specifying * the type that will be used to serialise the content (e.g. JsonbAdapter). diff --git a/http-client/src/main/java/io/avaje/http/client/JsonbBodyAdapter.java b/http-client/src/main/java/io/avaje/http/client/JsonbBodyAdapter.java index f09dd3d39..95b7b94bf 100644 --- a/http-client/src/main/java/io/avaje/http/client/JsonbBodyAdapter.java +++ b/http-client/src/main/java/io/avaje/http/client/JsonbBodyAdapter.java @@ -47,6 +47,12 @@ public BodyWriter beanWriter(Class cls) { return (BodyWriter) beanWriterCache.computeIfAbsent(cls, aClass -> new JWriter<>(jsonb.type(cls))); } + @SuppressWarnings("unchecked") + @Override + public BodyWriter beanWriter(ParameterizedType type) { + return (BodyWriter) beanWriterCache.computeIfAbsent(type, aClass -> new JWriter<>(jsonb.type(type))); + } + @SuppressWarnings("unchecked") @Override public BodyReader beanReader(Class cls) { diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java index 201c15a54..52ea78aeb 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java @@ -251,7 +251,8 @@ private void writeBody() { for (MethodParam param : method.params()) { ParamType paramType = param.paramType(); if (paramType == ParamType.BODY) { - writer.append(" .body(%s, %s.class)", param.name(), param.utype().shortType()).eol(); + writer.append(" .body(%s, ", param.name()); + writeGeneric(param.utype()); } } } From 67eb2a1b81be99f4a7ea70de2554c01850691424 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sun, 12 Mar 2023 21:43:43 -0400 Subject: [PATCH 0684/1323] Update ClientMethodWriter.java --- .../io/avaje/http/generator/client/ClientMethodWriter.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java index 52ea78aeb..37f914b45 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java @@ -141,6 +141,7 @@ private void writeResponse(UType type) { if (isList(mainType)) { writer.append(".list("); writeGeneric(param1); + writer.append(");").eol(); } else if (isStream(mainType)) { writer.append(".stream("); writeGeneric(param1); @@ -177,7 +178,6 @@ void writeGeneric(UType type) { } else { writer.append("%s.class", Util.shortName(type.mainType())); } - writer.append(");").eol(); } private void writeQueryParams(PathSegments pathSegments) { @@ -253,6 +253,7 @@ private void writeBody() { if (paramType == ParamType.BODY) { writer.append(" .body(%s, ", param.name()); writeGeneric(param.utype()); + writer.append(")").eol(); } } } From 2f5cf18e94b671b96f3c494f307a7c732850237f Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sun, 12 Mar 2023 21:54:06 -0400 Subject: [PATCH 0685/1323] fix --- .../generator/client/ClientMethodWriter.java | 48 +++++++++---------- .../myapp/web/{test => }/ServerType.java | 2 +- 2 files changed, 25 insertions(+), 25 deletions(-) rename tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/{test => }/ServerType.java (61%) diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java index 37f914b45..475efd08d 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java @@ -107,14 +107,12 @@ private void writeEnd() { String known = KNOWN_RESPONSE.get(returnType.full()); if (known != null) { writer.append(" %s", known).eol(); + } else if (COMPLETABLE_FUTURE.equals(returnType.mainType())) { + writeAsyncResponse(); + } else if (HTTP_CALL.equals(returnType.mainType())) { + writeCallResponse(); } else { - if (COMPLETABLE_FUTURE.equals(returnType.mainType())) { - writeAsyncResponse(); - } else if (HTTP_CALL.equals(returnType.mainType())) { - writeCallResponse(); - } else { - writeSyncResponse(); - } + writeSyncResponse(); } } writer.append(" }").eol().eol(); @@ -145,24 +143,28 @@ private void writeResponse(UType type) { } else if (isStream(mainType)) { writer.append(".stream("); writeGeneric(param1); + writer.append(");").eol(); } else if (isHttpResponse(mainType)) { if (bodyHandlerParam == null) { - UType paramType = type.paramRaw(); - if (paramType.mainType().equals("java.util.List")) { + final UType paramType = type.paramRaw(); + if ("java.util.List".equals(paramType.mainType())) { writer.append(".asList("); writeGeneric(paramType.paramRaw()); - } else if (paramType.mainType().equals("java.util.stream.Stream")) { + } else if ("java.util.stream.Stream".equals(paramType.mainType())) { writer.append(".asStream("); writeGeneric(paramType.paramRaw()); } else { writer.append(".as("); writeGeneric(paramType); } + writer.append(");").eol(); } else { - writer.append(".handler(%s);", bodyHandlerParam.name()).eol(); } + writer.append(".handler(%s);", bodyHandlerParam.name()).eol(); + } } else { writer.append(".bean("); writeGeneric(type); + writer.append(");").eol(); } } @@ -181,15 +183,13 @@ void writeGeneric(UType type) { } private void writeQueryParams(PathSegments pathSegments) { - for (MethodParam param : method.params()) { - ParamType paramType = param.paramType(); - if (paramType == ParamType.QUERYPARAM) { - if (pathSegments.segment(param.paramName()) == null) { - if (isMap(param)) { - writer.append(" .queryParam(%s)", param.name()).eol(); - } else { - writer.append(" .queryParam(\"%s\", %s)", param.paramName(), param.name()).eol(); - } + for (final MethodParam param : method.params()) { + final ParamType paramType = param.paramType(); + if (paramType == ParamType.QUERYPARAM && pathSegments.segment(param.paramName()) == null) { + if (isMap(param)) { + writer.append(" .queryParam(%s)", param.name()).eol(); + } else { + writer.append(" .queryParam(\"%s\", %s)", param.paramName(), param.name()).eol(); } } } @@ -280,19 +280,19 @@ private boolean isMap(MethodParam param) { } private boolean isMap(String type0) { - return type0.equals("java.util.Map"); + return "java.util.Map".equals(type0); } private boolean isList(String type0) { - return type0.equals("java.util.List"); + return "java.util.List".equals(type0); } private boolean isStream(String type0) { - return type0.equals("java.util.stream.Stream"); + return "java.util.stream.Stream".equals(type0); } private boolean isHttpResponse(String type0) { - return type0.equals("java.net.http.HttpResponse"); + return "java.net.http.HttpResponse".equals(type0); } } diff --git a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/ServerType.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/ServerType.java similarity index 61% rename from tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/ServerType.java rename to tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/ServerType.java index f77febe75..244f00545 100644 --- a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/ServerType.java +++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/ServerType.java @@ -1,4 +1,4 @@ -package org.example.myapp.web.test; +package org.example.myapp.web; public enum ServerType { PROXY, From f430e73c41a35201dc8982788ca2cab3c21bf0c2 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sun, 12 Mar 2023 21:57:21 -0400 Subject: [PATCH 0686/1323] Update TestController2.java --- .../main/java/org/example/myapp/web/test/TestController2.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController2.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController2.java index 0bad2a07c..2bb9b5305 100644 --- a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController2.java +++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController2.java @@ -5,6 +5,8 @@ import java.util.Map; import java.util.Set; +import org.example.myapp.web.ServerType; + import io.avaje.http.api.Controller; import io.avaje.http.api.Default; import io.avaje.http.api.Form; From 6e0db661772ef2d89030b513b45f01548004cc72 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Mon, 13 Mar 2023 00:09:36 -0400 Subject: [PATCH 0687/1323] ThreadLocal Context (#183) * ThreadLocal * Update pom.xml * Update ProcessingContext.java * Update ProcessingContext.java --- http-generator-core/pom.xml | 9 +- .../generator/core/ProcessingContext.java | 111 +++++++++--------- 2 files changed, 61 insertions(+), 59 deletions(-) diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 88cead6b3..0f18a4a1b 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -9,11 +9,14 @@ avaje-http-generator-core + + 1.6 + io.avaje avaje-prisms - 1.6 + ${avaje.prisms.version} true provided @@ -21,7 +24,7 @@ io.avaje avaje-http-api - 1.31-SNAPSHOT + ${project.version} true provided @@ -81,7 +84,7 @@ io.avaje avaje-prisms - 1.6 + ${avaje.prisms.version} diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java index d4ebdb5a7..e2bcef993 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java @@ -25,49 +25,50 @@ public class ProcessingContext { - private static PlatformAdapter readAdapter; - private static Messager messager; - private static Filer filer; - private static Elements elements; - private static Types types; - private static boolean openApiAvailable; - private static DocContext docContext; - private static boolean useComponent; - private static boolean useJavax; - private static String diAnnotation; + private static ThreadLocal READ_ADAPTER = new ThreadLocal<>(); + private static ThreadLocal MESSAGER = new ThreadLocal<>(); + private static ThreadLocal FILER = new ThreadLocal<>(); + private static ThreadLocal ELEMENTS = new ThreadLocal<>(); + private static ThreadLocal TYPES = new ThreadLocal<>(); + private static ThreadLocal OPENAPI_AVAILABLE = ThreadLocal.withInitial(() -> false); + private static ThreadLocal DOC_CONTEXT = new ThreadLocal<>(); + private static ThreadLocal USE_COMPONENT = ThreadLocal.withInitial(() -> false); + private static ThreadLocal USE_JAVAX = ThreadLocal.withInitial(() -> false); + private static ThreadLocal DI_ANNOTATION = new ThreadLocal<>(); public static void init(ProcessingEnvironment env, PlatformAdapter adapter) { init(env, adapter, true); } - public static void init(ProcessingEnvironment env, PlatformAdapter adapter, boolean generateOpenAPI) { - readAdapter = adapter; - messager = env.getMessager(); - filer = env.getFiler(); - elements = env.getElementUtils(); - types = env.getTypeUtils(); + public static void init( + ProcessingEnvironment env, PlatformAdapter adapter, boolean generateOpenAPI) { + READ_ADAPTER.set(adapter); + MESSAGER.set(env.getMessager()); + FILER.set(env.getFiler()); + ELEMENTS.set(env.getElementUtils()); + TYPES.set(env.getTypeUtils()); if (generateOpenAPI) { - openApiAvailable = isTypeAvailable(Constants.OPENAPIDEFINITION); - docContext = new DocContext(env, openApiAvailable); + OPENAPI_AVAILABLE.set(isTypeAvailable(Constants.OPENAPIDEFINITION)); + DOC_CONTEXT.set(new DocContext(env, OPENAPI_AVAILABLE.get())); } final var options = env.getOptions(); final var singletonOverride = options.get("useSingleton"); if (singletonOverride != null) { - useComponent = !Boolean.parseBoolean(singletonOverride); + USE_COMPONENT.set(!Boolean.parseBoolean(singletonOverride)); } else { - useComponent = isTypeAvailable(Constants.COMPONENT); + USE_COMPONENT.set(isTypeAvailable(Constants.COMPONENT)); } - diAnnotation = useComponent ? "@Component" : "@Singleton"; + DI_ANNOTATION.set(USE_COMPONENT.get() ? "@Component" : "@Singleton"); final var javax = isTypeAvailable(Constants.SINGLETON_JAVAX); final var jakarta = isTypeAvailable(Constants.SINGLETON_JAKARTA); final var override = env.getOptions().get("useJavax"); if (override != null || (javax && jakarta)) { - useJavax = Boolean.parseBoolean(override); + USE_JAVAX.set(Boolean.parseBoolean(override)); } else { - useJavax = javax; + USE_JAVAX.set(javax); } } @@ -76,81 +77,79 @@ private static boolean isTypeAvailable(String canonicalName) { } public static TypeElement typeElement(String canonicalName) { - return elements.getTypeElement(canonicalName); + return ELEMENTS.get().getTypeElement(canonicalName); } public static boolean isOpenApiAvailable() { - return openApiAvailable; + return OPENAPI_AVAILABLE.get(); } public static boolean useJavax() { - return useJavax; + return USE_JAVAX.get(); } public static boolean useComponent() { - return useComponent; + return USE_COMPONENT.get(); } public static void logError(Element e, String msg, Object... args) { - messager.printMessage(Diagnostic.Kind.ERROR, String.format(msg, args), e); + MESSAGER.get().printMessage(Diagnostic.Kind.ERROR, String.format(msg, args), e); } - /** - * Create a file writer for the given class name. - */ + /** Create a file writer for the given class name. */ public static JavaFileObject createWriter(String cls, Element origin) throws IOException { - return filer.createSourceFile(cls, origin); + return FILER.get().createSourceFile(cls, origin); } - /** - * Create a file writer for the META-INF services file. - */ + /** Create a file writer for the META-INF services file. */ public static FileObject createMetaInfWriter(String target) throws IOException { - return filer.createResource(StandardLocation.CLASS_OUTPUT, "", target); + return FILER.get().createResource(StandardLocation.CLASS_OUTPUT, "", target); } public static String docComment(Element param) { - return elements.getDocComment(param); + return ELEMENTS.get().getDocComment(param); } public static DocContext doc() { - return docContext; + return DOC_CONTEXT.get(); } public static Element asElement(TypeMirror typeMirror) { - return types.asElement(typeMirror); + return TYPES.get().asElement(typeMirror); } public static TypeMirror asMemberOf(DeclaredType declaredType, Element element) { - return types.asMemberOf(declaredType, element); + return TYPES.get().asMemberOf(declaredType, element); } public static List superMethods(Element element, String methodName) { + final Types types = TYPES.get(); return types.directSupertypes(element.asType()).stream() - .filter(type -> !type.toString().contains("java.lang.Object")) - .map( - superType -> { - final var superClass = (TypeElement) types.asElement(superType); - for (final ExecutableElement method : ElementFilter.methodsIn(elements.getAllMembers(superClass))) { - if (method.getSimpleName().contentEquals(methodName)) { - return method; - } - } - return null; - }) - .filter(Objects::nonNull) - .collect(Collectors.toList()); + .filter(type -> !type.toString().contains("java.lang.Object")) + .map( + superType -> { + final var superClass = (TypeElement) types.asElement(superType); + for (final ExecutableElement method : + ElementFilter.methodsIn(ELEMENTS.get().getAllMembers(superClass))) { + if (method.getSimpleName().contentEquals(methodName)) { + return method; + } + } + return null; + }) + .filter(Objects::nonNull) + .collect(Collectors.toList()); } public static PlatformAdapter platform() { - return readAdapter; + return READ_ADAPTER.get(); } public static void setPlatform(PlatformAdapter platform) { - readAdapter = platform; + READ_ADAPTER.set(platform); } public static String diAnnotation() { - return diAnnotation; + return DI_ANNOTATION.get(); } } From 3cd5626483022b9d263ff2c49ff874d31f0b301d Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Mon, 13 Mar 2023 17:14:27 +1300 Subject: [PATCH 0688/1323] Format code and final fields for ProcessingContext --- .../generator/core/ProcessingContext.java | 59 ++++++++++--------- 1 file changed, 31 insertions(+), 28 deletions(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java index e2bcef993..c41d9d072 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java @@ -25,23 +25,22 @@ public class ProcessingContext { - private static ThreadLocal READ_ADAPTER = new ThreadLocal<>(); - private static ThreadLocal MESSAGER = new ThreadLocal<>(); - private static ThreadLocal FILER = new ThreadLocal<>(); - private static ThreadLocal ELEMENTS = new ThreadLocal<>(); - private static ThreadLocal TYPES = new ThreadLocal<>(); - private static ThreadLocal OPENAPI_AVAILABLE = ThreadLocal.withInitial(() -> false); - private static ThreadLocal DOC_CONTEXT = new ThreadLocal<>(); - private static ThreadLocal USE_COMPONENT = ThreadLocal.withInitial(() -> false); - private static ThreadLocal USE_JAVAX = ThreadLocal.withInitial(() -> false); - private static ThreadLocal DI_ANNOTATION = new ThreadLocal<>(); + private static final ThreadLocal READ_ADAPTER = new ThreadLocal<>(); + private static final ThreadLocal MESSAGER = new ThreadLocal<>(); + private static final ThreadLocal FILER = new ThreadLocal<>(); + private static final ThreadLocal ELEMENTS = new ThreadLocal<>(); + private static final ThreadLocal TYPES = new ThreadLocal<>(); + private static final ThreadLocal OPENAPI_AVAILABLE = ThreadLocal.withInitial(() -> false); + private static final ThreadLocal DOC_CONTEXT = new ThreadLocal<>(); + private static final ThreadLocal USE_COMPONENT = ThreadLocal.withInitial(() -> false); + private static final ThreadLocal USE_JAVAX = ThreadLocal.withInitial(() -> false); + private static final ThreadLocal DI_ANNOTATION = new ThreadLocal<>(); public static void init(ProcessingEnvironment env, PlatformAdapter adapter) { init(env, adapter, true); } - public static void init( - ProcessingEnvironment env, PlatformAdapter adapter, boolean generateOpenAPI) { + public static void init(ProcessingEnvironment env, PlatformAdapter adapter, boolean generateOpenAPI) { READ_ADAPTER.set(adapter); MESSAGER.set(env.getMessager()); FILER.set(env.getFiler()); @@ -96,12 +95,16 @@ public static void logError(Element e, String msg, Object... args) { MESSAGER.get().printMessage(Diagnostic.Kind.ERROR, String.format(msg, args), e); } - /** Create a file writer for the given class name. */ + /** + * Create a file writer for the given class name. + */ public static JavaFileObject createWriter(String cls, Element origin) throws IOException { return FILER.get().createSourceFile(cls, origin); } - /** Create a file writer for the META-INF services file. */ + /** + * Create a file writer for the META-INF services file. + */ public static FileObject createMetaInfWriter(String target) throws IOException { return FILER.get().createResource(StandardLocation.CLASS_OUTPUT, "", target); } @@ -125,20 +128,20 @@ public static TypeMirror asMemberOf(DeclaredType declaredType, Element element) public static List superMethods(Element element, String methodName) { final Types types = TYPES.get(); return types.directSupertypes(element.asType()).stream() - .filter(type -> !type.toString().contains("java.lang.Object")) - .map( - superType -> { - final var superClass = (TypeElement) types.asElement(superType); - for (final ExecutableElement method : - ElementFilter.methodsIn(ELEMENTS.get().getAllMembers(superClass))) { - if (method.getSimpleName().contentEquals(methodName)) { - return method; - } - } - return null; - }) - .filter(Objects::nonNull) - .collect(Collectors.toList()); + .filter(type -> !type.toString().contains("java.lang.Object")) + .map( + superType -> { + final var superClass = (TypeElement) types.asElement(superType); + for (final ExecutableElement method : + ElementFilter.methodsIn(ELEMENTS.get().getAllMembers(superClass))) { + if (method.getSimpleName().contentEquals(methodName)) { + return method; + } + } + return null; + }) + .filter(Objects::nonNull) + .collect(Collectors.toList()); } public static PlatformAdapter platform() { From 9928cb60c00b3e69b50c00acf26353bf2b933b46 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Mon, 13 Mar 2023 17:34:29 +1300 Subject: [PATCH 0689/1323] Version 1.31-RC2 --- http-api/pom.xml | 2 +- http-client-gson-adapter/pom.xml | 4 ++-- http-client/pom.xml | 2 +- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 2 +- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-generator-nima/pom.xml | 2 +- pom.xml | 2 +- tests/pom.xml | 2 +- tests/test-client-generation/pom.xml | 2 +- tests/test-client/pom.xml | 2 +- tests/test-helidon/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- 19 files changed, 20 insertions(+), 20 deletions(-) diff --git a/http-api/pom.xml b/http-api/pom.xml index 041f74ff9..374fa3f4a 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.31-SNAPSHOT + 1.31-RC2 .. diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index 25c466d2c..771eda31d 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.31-SNAPSHOT + 1.31-RC2 avaje-http-client-gson @@ -20,7 +20,7 @@ io.avaje avaje-http-client - 1.31-SNAPSHOT + 1.31-RC2 provided diff --git a/http-client/pom.xml b/http-client/pom.xml index 4562741e8..7602497d4 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.31-SNAPSHOT + 1.31-RC2 avaje-http-client diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index 11d4133f1..e96b8b1b0 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.31-SNAPSHOT + 1.31-RC2 avaje-http-client-generator diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 0f18a4a1b..dbef29599 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.31-SNAPSHOT + 1.31-RC2 avaje-http-generator-core diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index 4713365f5..c0bea7a35 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.31-SNAPSHOT + 1.31-RC2 avaje-http-helidon-generator diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index 518e9465e..37a0103b8 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.31-SNAPSHOT + 1.31-RC2 avaje-http-javalin-generator diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index 80c6fae4f..09c1f4ac5 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.31-SNAPSHOT + 1.31-RC2 avaje-http-jex-generator diff --git a/http-generator-nima/pom.xml b/http-generator-nima/pom.xml index 0c3b0a25f..72c542d9b 100644 --- a/http-generator-nima/pom.xml +++ b/http-generator-nima/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 1.31-SNAPSHOT + 1.31-RC2 avaje-http-nima-generator diff --git a/pom.xml b/pom.xml index 656dee555..597449dbc 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-parent - 1.31-SNAPSHOT + 1.31-RC2 pom diff --git a/tests/pom.xml b/tests/pom.xml index 710c05382..33700d33e 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 1.31-SNAPSHOT + 1.31-RC2 tests diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index 4dc456ff1..4f9cf3dbb 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.31-SNAPSHOT + 1.31-RC2 test-client-generation diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index 35bd8df4e..da7e7959a 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 1.31-SNAPSHOT + 1.31-RC2 test-client diff --git a/tests/test-helidon/pom.xml b/tests/test-helidon/pom.xml index d6256a981..eb318f43e 100644 --- a/tests/test-helidon/pom.xml +++ b/tests/test-helidon/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.31-SNAPSHOT + 1.31-RC2 test-helidon diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 97b0cbbcc..69458a119 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 1.31-SNAPSHOT + 1.31-RC2 test-javalin-jsonb diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index f3ea5587e..0664c43cc 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.31-SNAPSHOT + 1.31-RC2 test-javalin diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index a64547c46..cebcc4cd2 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.31-SNAPSHOT + 1.31-RC2 test-jex diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 8f457d6e2..b6767094e 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.31-SNAPSHOT + 1.31-RC2 test-nima-jsonb diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index 906f9cf50..d3ae581ea 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 1.31-SNAPSHOT + 1.31-RC2 test-nima From 4dac27d484ce26f1101b95d8016e4609ab94c975 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Tue, 14 Mar 2023 17:34:23 -0400 Subject: [PATCH 0690/1323] Fix collection query mapping (#184) * ThreadLocal * Update pom.xml * Update ProcessingContext.java * Update ProcessingContext.java * fix collection query mapping --- .../src/main/java/io/avaje/http/generator/core/TypeMap.java | 4 ++-- http-hibernate-validator/pom.xml | 4 ++-- .../src/main/java/org/example/TestController.java | 6 ++++++ 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/TypeMap.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/TypeMap.java index bed872cd3..632e9ece8 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/TypeMap.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/TypeMap.java @@ -335,10 +335,10 @@ static class CollectionHandler implements TypeHandler { + "(" + (isEnum ? "qp -> " + handler.toMethod() + " qp)" - : "PathTypeConversion::" + shortName) + : "PathTypeConversion::as" + shortName) + ", "; - this.toMethod = toMethod.replace("PathTypeConversion::String", "Object::toString"); + this.toMethod = toMethod.replace("PathTypeConversion::asString", "Object::toString"); } @Override diff --git a/http-hibernate-validator/pom.xml b/http-hibernate-validator/pom.xml index a016b8bc8..8a6d7e38d 100644 --- a/http-hibernate-validator/pom.xml +++ b/http-hibernate-validator/pom.xml @@ -36,14 +36,14 @@ io.avaje avaje-http-api - 1.22 + 1.30 provided io.avaje avaje-inject - 8.13 + 9.0-RC2 provided diff --git a/tests/test-nima-jsonb/src/main/java/org/example/TestController.java b/tests/test-nima-jsonb/src/main/java/org/example/TestController.java index 3644ba151..03a7ea2ab 100644 --- a/tests/test-nima-jsonb/src/main/java/org/example/TestController.java +++ b/tests/test-nima-jsonb/src/main/java/org/example/TestController.java @@ -1,6 +1,7 @@ package org.example; import java.io.InputStream; +import java.util.List; import java.util.Set; import io.avaje.http.api.Controller; @@ -21,6 +22,11 @@ String paramMulti(Set strings) { return strings.toString(); } + @Get("/BoxCollection") + String boxed(@QueryParam List l) { + return l.toString(); + } + @Form @Get("/enumForm") String enumForm(String s, ServerType type) { From be6e978e58456f8fe46162e5d11d93472cad82fe Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Wed, 15 Mar 2023 10:41:32 +1300 Subject: [PATCH 0691/1323] Version 1.31-RC3 --- http-api/pom.xml | 2 +- http-client-gson-adapter/pom.xml | 4 ++-- http-client/pom.xml | 2 +- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 2 +- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-generator-nima/pom.xml | 2 +- pom.xml | 2 +- tests/pom.xml | 2 +- tests/test-client-generation/pom.xml | 2 +- tests/test-client/pom.xml | 2 +- tests/test-helidon/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- 19 files changed, 20 insertions(+), 20 deletions(-) diff --git a/http-api/pom.xml b/http-api/pom.xml index 374fa3f4a..130b06af2 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.31-RC2 + 1.31-RC3 .. diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index 771eda31d..4cedfbe2b 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.31-RC2 + 1.31-RC3 avaje-http-client-gson @@ -20,7 +20,7 @@ io.avaje avaje-http-client - 1.31-RC2 + 1.31-RC3 provided diff --git a/http-client/pom.xml b/http-client/pom.xml index 7602497d4..25260a56e 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.31-RC2 + 1.31-RC3 avaje-http-client diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index e96b8b1b0..88afbbb8f 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.31-RC2 + 1.31-RC3 avaje-http-client-generator diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index dbef29599..907350651 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.31-RC2 + 1.31-RC3 avaje-http-generator-core diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index c0bea7a35..25750a08e 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.31-RC2 + 1.31-RC3 avaje-http-helidon-generator diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index 37a0103b8..155e287a1 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.31-RC2 + 1.31-RC3 avaje-http-javalin-generator diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index 09c1f4ac5..4dc67bc12 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.31-RC2 + 1.31-RC3 avaje-http-jex-generator diff --git a/http-generator-nima/pom.xml b/http-generator-nima/pom.xml index 72c542d9b..a19e0ccb7 100644 --- a/http-generator-nima/pom.xml +++ b/http-generator-nima/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 1.31-RC2 + 1.31-RC3 avaje-http-nima-generator diff --git a/pom.xml b/pom.xml index 597449dbc..23c8a7d77 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-parent - 1.31-RC2 + 1.31-RC3 pom diff --git a/tests/pom.xml b/tests/pom.xml index 33700d33e..5c1fe5668 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 1.31-RC2 + 1.31-RC3 tests diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index 4f9cf3dbb..b17af72d5 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.31-RC2 + 1.31-RC3 test-client-generation diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index da7e7959a..208a73217 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 1.31-RC2 + 1.31-RC3 test-client diff --git a/tests/test-helidon/pom.xml b/tests/test-helidon/pom.xml index eb318f43e..2f628f779 100644 --- a/tests/test-helidon/pom.xml +++ b/tests/test-helidon/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.31-RC2 + 1.31-RC3 test-helidon diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 69458a119..35ce49bc9 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 1.31-RC2 + 1.31-RC3 test-javalin-jsonb diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 0664c43cc..721b947b7 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.31-RC2 + 1.31-RC3 test-javalin diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index cebcc4cd2..bdfcbe7e6 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.31-RC2 + 1.31-RC3 test-jex diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index b6767094e..33f80fbc9 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.31-RC2 + 1.31-RC3 test-nima-jsonb diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index d3ae581ea..cad698a79 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 1.31-RC2 + 1.31-RC3 test-nima From 6aaa5960b55de3db038c948286da4b6dfa7d6142 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Wed, 15 Mar 2023 20:29:18 -0400 Subject: [PATCH 0692/1323] Single ThreadLocal Context (#185) * Single ThreadLocal * there we go * should work now --- .../generator/core/ProcessingContext.java | 163 ++++++++++-------- 1 file changed, 88 insertions(+), 75 deletions(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java index c41d9d072..6de499f23 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java @@ -25,50 +25,67 @@ public class ProcessingContext { - private static final ThreadLocal READ_ADAPTER = new ThreadLocal<>(); - private static final ThreadLocal MESSAGER = new ThreadLocal<>(); - private static final ThreadLocal FILER = new ThreadLocal<>(); - private static final ThreadLocal ELEMENTS = new ThreadLocal<>(); - private static final ThreadLocal TYPES = new ThreadLocal<>(); - private static final ThreadLocal OPENAPI_AVAILABLE = ThreadLocal.withInitial(() -> false); - private static final ThreadLocal DOC_CONTEXT = new ThreadLocal<>(); - private static final ThreadLocal USE_COMPONENT = ThreadLocal.withInitial(() -> false); - private static final ThreadLocal USE_JAVAX = ThreadLocal.withInitial(() -> false); - private static final ThreadLocal DI_ANNOTATION = new ThreadLocal<>(); - - public static void init(ProcessingEnvironment env, PlatformAdapter adapter) { - init(env, adapter, true); + private static final ThreadLocal CTX = new ThreadLocal<>(); + + private ProcessingContext() {} + + static final class Ctx { + private PlatformAdapter readAdapter; + private final Messager messager; + private final Filer filer; + private final Elements elementUtils; + private final Types typeUtils; + private boolean openApiAvailable; + private DocContext docContext; + private final boolean useComponent; + private final boolean useJavax; + private final String diAnnotation; + + public Ctx(ProcessingEnvironment env, PlatformAdapter adapter, boolean generateOpenAPI) { + readAdapter = adapter; + messager = env.getMessager(); + filer = env.getFiler(); + elementUtils = env.getElementUtils(); + typeUtils = env.getTypeUtils(); + + if (generateOpenAPI) { + openApiAvailable = elementUtils.getTypeElement(Constants.OPENAPIDEFINITION) != null; + docContext = new DocContext(env, openApiAvailable); + } + + final var options = env.getOptions(); + final var singletonOverride = options.get("useSingleton"); + if (singletonOverride != null) { + useComponent = (!Boolean.parseBoolean(singletonOverride)); + } else { + useComponent = elementUtils.getTypeElement(Constants.COMPONENT) != null; + } + diAnnotation = (useComponent ? "@Component" : "@Singleton"); + + final var javax = elementUtils.getTypeElement(Constants.SINGLETON_JAVAX) != null; + final var jakarta = elementUtils.getTypeElement(Constants.SINGLETON_JAKARTA) != null; + final var override = env.getOptions().get("useJavax"); + if (override != null || (javax && jakarta)) { + useJavax = Boolean.parseBoolean(override); + } else { + useJavax = (javax); + } + } } - public static void init(ProcessingEnvironment env, PlatformAdapter adapter, boolean generateOpenAPI) { - READ_ADAPTER.set(adapter); - MESSAGER.set(env.getMessager()); - FILER.set(env.getFiler()); - ELEMENTS.set(env.getElementUtils()); - TYPES.set(env.getTypeUtils()); + public static void init( + ProcessingEnvironment env, PlatformAdapter adapter, boolean generateOpenAPI) { + final var oldCtx = CTX.get(); + final var newCTX = new Ctx(env, adapter, generateOpenAPI); - if (generateOpenAPI) { - OPENAPI_AVAILABLE.set(isTypeAvailable(Constants.OPENAPIDEFINITION)); - DOC_CONTEXT.set(new DocContext(env, OPENAPI_AVAILABLE.get())); + if (oldCtx != null && newCTX.docContext == null) { + newCTX.docContext = oldCtx.docContext; } + CTX.set(newCTX); + } - final var options = env.getOptions(); - final var singletonOverride = options.get("useSingleton"); - if (singletonOverride != null) { - USE_COMPONENT.set(!Boolean.parseBoolean(singletonOverride)); - } else { - USE_COMPONENT.set(isTypeAvailable(Constants.COMPONENT)); - } - DI_ANNOTATION.set(USE_COMPONENT.get() ? "@Component" : "@Singleton"); - - final var javax = isTypeAvailable(Constants.SINGLETON_JAVAX); - final var jakarta = isTypeAvailable(Constants.SINGLETON_JAKARTA); - final var override = env.getOptions().get("useJavax"); - if (override != null || (javax && jakarta)) { - USE_JAVAX.set(Boolean.parseBoolean(override)); - } else { - USE_JAVAX.set(javax); - } + public static void init(ProcessingEnvironment env, PlatformAdapter adapter) { + init(env, adapter, true); } private static boolean isTypeAvailable(String canonicalName) { @@ -76,83 +93,79 @@ private static boolean isTypeAvailable(String canonicalName) { } public static TypeElement typeElement(String canonicalName) { - return ELEMENTS.get().getTypeElement(canonicalName); + return CTX.get().elementUtils.getTypeElement(canonicalName); } public static boolean isOpenApiAvailable() { - return OPENAPI_AVAILABLE.get(); + return CTX.get().openApiAvailable; } public static boolean useJavax() { - return USE_JAVAX.get(); + return CTX.get().useJavax; } public static boolean useComponent() { - return USE_COMPONENT.get(); + return CTX.get().useComponent; } public static void logError(Element e, String msg, Object... args) { - MESSAGER.get().printMessage(Diagnostic.Kind.ERROR, String.format(msg, args), e); + CTX.get().messager.printMessage(Diagnostic.Kind.ERROR, String.format(msg, args), e); } - /** - * Create a file writer for the given class name. - */ + /** Create a file writer for the given class name. */ public static JavaFileObject createWriter(String cls, Element origin) throws IOException { - return FILER.get().createSourceFile(cls, origin); + return CTX.get().filer.createSourceFile(cls, origin); } - /** - * Create a file writer for the META-INF services file. - */ + /** Create a file writer for the META-INF services file. */ public static FileObject createMetaInfWriter(String target) throws IOException { - return FILER.get().createResource(StandardLocation.CLASS_OUTPUT, "", target); + return CTX.get().filer.createResource(StandardLocation.CLASS_OUTPUT, "", target); } public static String docComment(Element param) { - return ELEMENTS.get().getDocComment(param); + return CTX.get().elementUtils.getDocComment(param); } public static DocContext doc() { - return DOC_CONTEXT.get(); + return CTX.get().docContext; } - public static Element asElement(TypeMirror typeMirror) { - return TYPES.get().asElement(typeMirror); + public static TypeElement asElement(TypeMirror typeMirror) { + return (TypeElement) CTX.get().typeUtils.asElement(typeMirror); } public static TypeMirror asMemberOf(DeclaredType declaredType, Element element) { - return TYPES.get().asMemberOf(declaredType, element); + return CTX.get().typeUtils.asMemberOf(declaredType, element); } public static List superMethods(Element element, String methodName) { - final Types types = TYPES.get(); + final Types types = CTX.get().typeUtils; return types.directSupertypes(element.asType()).stream() - .filter(type -> !type.toString().contains("java.lang.Object")) - .map( - superType -> { - final var superClass = (TypeElement) types.asElement(superType); - for (final ExecutableElement method : - ElementFilter.methodsIn(ELEMENTS.get().getAllMembers(superClass))) { - if (method.getSimpleName().contentEquals(methodName)) { - return method; - } - } - return null; - }) - .filter(Objects::nonNull) - .collect(Collectors.toList()); + .filter(type -> !type.toString().contains("java.lang.Object")) + .map( + superType -> { + final var superClass = (TypeElement) types.asElement(superType); + for (final ExecutableElement method : + ElementFilter.methodsIn(CTX.get().elementUtils.getAllMembers(superClass))) { + if (method.getSimpleName().contentEquals(methodName)) { + return method; + } + } + return null; + }) + .filter(Objects::nonNull) + .collect(Collectors.toList()); } public static PlatformAdapter platform() { - return READ_ADAPTER.get(); + return CTX.get().readAdapter; } public static void setPlatform(PlatformAdapter platform) { - READ_ADAPTER.set(platform); + CTX.get().readAdapter = (platform); } public static String diAnnotation() { - return DI_ANNOTATION.get(); + return CTX.get().diAnnotation; } } From cd97fd2d41d7ed43bab1e21f35464cdc833de75f Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Thu, 16 Mar 2023 13:34:01 +1300 Subject: [PATCH 0693/1323] Explicitly make ProcessingContext.Ctx private --- .../generator/core/ProcessingContext.java | 36 ++++++++----------- 1 file changed, 15 insertions(+), 21 deletions(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java index 6de499f23..46b22802a 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java @@ -29,7 +29,7 @@ public class ProcessingContext { private ProcessingContext() {} - static final class Ctx { + private static final class Ctx { private PlatformAdapter readAdapter; private final Messager messager; private final Filer filer; @@ -41,7 +41,7 @@ static final class Ctx { private final boolean useJavax; private final String diAnnotation; - public Ctx(ProcessingEnvironment env, PlatformAdapter adapter, boolean generateOpenAPI) { + Ctx(ProcessingEnvironment env, PlatformAdapter adapter, boolean generateOpenAPI) { readAdapter = adapter; messager = env.getMessager(); filer = env.getFiler(); @@ -56,7 +56,7 @@ public Ctx(ProcessingEnvironment env, PlatformAdapter adapter, boolean generateO final var options = env.getOptions(); final var singletonOverride = options.get("useSingleton"); if (singletonOverride != null) { - useComponent = (!Boolean.parseBoolean(singletonOverride)); + useComponent = !Boolean.parseBoolean(singletonOverride); } else { useComponent = elementUtils.getTypeElement(Constants.COMPONENT) != null; } @@ -73,11 +73,9 @@ public Ctx(ProcessingEnvironment env, PlatformAdapter adapter, boolean generateO } } - public static void init( - ProcessingEnvironment env, PlatformAdapter adapter, boolean generateOpenAPI) { + public static void init(ProcessingEnvironment env, PlatformAdapter adapter, boolean generateOpenAPI) { final var oldCtx = CTX.get(); final var newCTX = new Ctx(env, adapter, generateOpenAPI); - if (oldCtx != null && newCTX.docContext == null) { newCTX.docContext = oldCtx.docContext; } @@ -141,20 +139,16 @@ public static TypeMirror asMemberOf(DeclaredType declaredType, Element element) public static List superMethods(Element element, String methodName) { final Types types = CTX.get().typeUtils; return types.directSupertypes(element.asType()).stream() - .filter(type -> !type.toString().contains("java.lang.Object")) - .map( - superType -> { - final var superClass = (TypeElement) types.asElement(superType); - for (final ExecutableElement method : - ElementFilter.methodsIn(CTX.get().elementUtils.getAllMembers(superClass))) { - if (method.getSimpleName().contentEquals(methodName)) { - return method; - } - } - return null; - }) - .filter(Objects::nonNull) - .collect(Collectors.toList()); + .filter(type -> !type.toString().contains("java.lang.Object")) + .map(superType -> { + final var superClass = (TypeElement) types.asElement(superType); + for (final ExecutableElement method : ElementFilter.methodsIn(CTX.get().elementUtils.getAllMembers(superClass))) { + if (method.getSimpleName().contentEquals(methodName)) { + return method; + } + } + return null; + }).filter(Objects::nonNull).collect(Collectors.toList()); } public static PlatformAdapter platform() { @@ -162,7 +156,7 @@ public static PlatformAdapter platform() { } public static void setPlatform(PlatformAdapter platform) { - CTX.get().readAdapter = (platform); + CTX.get().readAdapter = platform; } public static String diAnnotation() { From b4102980b1e94b916aaf0ff60c924b5c3623909c Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Fri, 17 Mar 2023 17:02:58 -0400 Subject: [PATCH 0694/1323] Fix Query Param Collection Imports (#186) * fix collection imports * move multi test * Update pom.xml --- http-generator-core/pom.xml | 2 +- .../avaje/http/generator/core/ElementReader.java | 15 +++++++++------ .../example/myapp/web/test/TestController.java | 8 ++++++++ .../example/myapp/web/test/TestController2.java | 6 ------ 4 files changed, 18 insertions(+), 13 deletions(-) diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 907350651..6bf3d3d4f 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -10,7 +10,7 @@ avaje-http-generator-core - 1.6 + 1.8 diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java index c8973b2e0..d9971aed9 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java @@ -4,9 +4,10 @@ import static io.avaje.http.generator.core.ProcessingContext.platform; import static io.avaje.http.generator.core.ProcessingContext.typeElement; +import java.util.HashSet; import java.util.List; -import java.util.Objects; import java.util.Optional; +import java.util.Set; import javax.lang.model.element.Element; import javax.lang.model.element.ElementKind; @@ -38,6 +39,7 @@ public class ElementReader { private boolean notNullKotlin; private boolean isParamCollection; private boolean isParamMap; + private final Set imports = new HashSet<>(); // private boolean notNullJavax; ElementReader(Element element, ParamType defaultType, boolean formMarker) { @@ -59,6 +61,11 @@ public class ElementReader { typeHandler = initTypeHandler(); + this.imports.add(rawType); + if (typeHandler != null) { + this.imports.addAll(typeHandler.importTypes()); + } + this.formMarker = formMarker; this.varName = element.getSimpleName().toString(); this.snakeName = Util.snakeCase(varName); @@ -226,12 +233,8 @@ private String handlerShortType() { } void addImports(ControllerReader bean) { - if (typeHandler != null) { - typeHandler.importTypes().stream().filter(Objects::nonNull).forEach(bean::addImportType); - } else { - bean.addImportType(rawType); - } + bean.addImportTypes(imports); } void writeParamName(Append writer) { diff --git a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController.java index 704e4c504..7d48772cc 100644 --- a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController.java +++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController.java @@ -8,8 +8,10 @@ import org.example.myapp.web.AppRoles; import org.example.myapp.web.HelloDto; import org.example.myapp.web.Roles; +import org.example.myapp.web.ServerType; import io.avaje.http.api.Controller; +import io.avaje.http.api.Default; import io.avaje.http.api.Form; import io.avaje.http.api.Get; import io.avaje.http.api.Header; @@ -19,6 +21,7 @@ import io.avaje.http.api.Post; import io.avaje.http.api.Produces; import io.avaje.http.api.Put; +import io.avaje.http.api.QueryParam; import io.javalin.http.Context; @Path("test/") @@ -129,4 +132,9 @@ void neo( CompletableFuture getAllAsync() { return CompletableFuture.supplyAsync(() -> new HelloDto(12, "Jim", "asd")); } + + @Get("/enumQuery2") + String enumMultiQuery(@QueryParam @Default({"FFA", "PROXY"}) Set type) { + return type.toString(); + } } diff --git a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController2.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController2.java index 2bb9b5305..33aa67993 100644 --- a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController2.java +++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController2.java @@ -3,7 +3,6 @@ import java.io.InputStream; import java.util.List; import java.util.Map; -import java.util.Set; import org.example.myapp.web.ServerType; @@ -36,11 +35,6 @@ String enumQuery(@QueryParam @Default("FFA") ServerType type) { return type.name(); } - @Get("/enumQuery2") - String enumMultiQuery(@QueryParam @Default({"FFA", "PROXY"}) Set type) { - return type.toString(); - } - @Post("/enumQueryImplied") String enumQueryImplied(String s, @QueryParam ServerType type) { return type.name(); From a8a2ad7530e752e50510b1c1b4eaef5ff244ad91 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Sat, 18 Mar 2023 10:12:24 +1300 Subject: [PATCH 0695/1323] Version 1.32 --- http-api/pom.xml | 2 +- http-client-gson-adapter/pom.xml | 4 ++-- http-client/pom.xml | 2 +- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 2 +- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-generator-nima/pom.xml | 2 +- pom.xml | 2 +- tests/pom.xml | 2 +- tests/test-client-generation/pom.xml | 2 +- tests/test-client/pom.xml | 2 +- tests/test-helidon/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- 19 files changed, 20 insertions(+), 20 deletions(-) diff --git a/http-api/pom.xml b/http-api/pom.xml index 130b06af2..ff10a1de3 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.31-RC3 + 1.32 .. diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index 4cedfbe2b..4e33aefd7 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.31-RC3 + 1.32 avaje-http-client-gson @@ -20,7 +20,7 @@ io.avaje avaje-http-client - 1.31-RC3 + 1.32 provided diff --git a/http-client/pom.xml b/http-client/pom.xml index 25260a56e..11561d857 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.31-RC3 + 1.32 avaje-http-client diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index 88afbbb8f..20bfa22ab 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.31-RC3 + 1.32 avaje-http-client-generator diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 6bf3d3d4f..42d5b1791 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.31-RC3 + 1.32 avaje-http-generator-core diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index 25750a08e..ec372c628 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.31-RC3 + 1.32 avaje-http-helidon-generator diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index 155e287a1..049e8c338 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.31-RC3 + 1.32 avaje-http-javalin-generator diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index 4dc67bc12..2874998cd 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.31-RC3 + 1.32 avaje-http-jex-generator diff --git a/http-generator-nima/pom.xml b/http-generator-nima/pom.xml index a19e0ccb7..e4158ecb8 100644 --- a/http-generator-nima/pom.xml +++ b/http-generator-nima/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 1.31-RC3 + 1.32 avaje-http-nima-generator diff --git a/pom.xml b/pom.xml index 23c8a7d77..a36d36ee3 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-parent - 1.31-RC3 + 1.32 pom diff --git a/tests/pom.xml b/tests/pom.xml index 5c1fe5668..ad404773d 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 1.31-RC3 + 1.32 tests diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index b17af72d5..18c65a2f7 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.31-RC3 + 1.32 test-client-generation diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index 208a73217..d9e83c38a 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 1.31-RC3 + 1.32 test-client diff --git a/tests/test-helidon/pom.xml b/tests/test-helidon/pom.xml index 2f628f779..560f60923 100644 --- a/tests/test-helidon/pom.xml +++ b/tests/test-helidon/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.31-RC3 + 1.32 test-helidon diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 35ce49bc9..e41a204dd 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 1.31-RC3 + 1.32 test-javalin-jsonb diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 721b947b7..60eb61a3e 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.31-RC3 + 1.32 test-javalin diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index bdfcbe7e6..7acfa7d12 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.31-RC3 + 1.32 test-jex diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 33f80fbc9..d8cf9251f 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.31-RC3 + 1.32 test-nima-jsonb diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index cad698a79..748da0da2 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 1.31-RC3 + 1.32 test-nima From 040f3194db12a4eacede300f451682449ceeb42c Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sun, 19 Mar 2023 17:11:26 -0400 Subject: [PATCH 0696/1323] Fix Bean Param Enum Imports (#187) * fix collection imports * move multi test * Update pom.xml * fix bean param enum import * Update HelloControllerTest.java * Update GetBeanForm.java * Update pom.xml --- http-client/pom.xml | 31 +------------------ .../http/generator/core/ElementReader.java | 2 +- .../org/example/myapp/web/GetBeanForm.java | 16 ++++++++-- .../example/myapp/HelloControllerTest.java | 2 ++ 4 files changed, 18 insertions(+), 33 deletions(-) diff --git a/http-client/pom.xml b/http-client/pom.xml index 11561d857..2274d1766 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -43,19 +43,12 @@ io.avaje avaje-inject - 8.13 + 9.0-RC3 true - - - - - - - io.avaje avaje-applog-slf4j @@ -97,15 +90,6 @@ 1.1 test - - - - - - - - - @@ -134,19 +118,6 @@ maven-surefire-plugin 3.0.0-M6 - - - - - - - - - - - - - diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java index d9971aed9..a4f1d9329 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java @@ -102,7 +102,7 @@ TypeHandler initTypeHandler() { !isCollection && typeOp.filter(t -> t.mainType().startsWith("java.util.Map")).isPresent(); if (mainTypeEnum) { - return TypeMap.enumParamHandler(type); + return TypeMap.enumParamHandler(typeOp.orElseThrow()); } else if (isCollection) { this.isParamCollection = true; final var isEnumCollection = diff --git a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/GetBeanForm.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/GetBeanForm.java index a74b0f3cd..573048b2a 100644 --- a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/GetBeanForm.java +++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/GetBeanForm.java @@ -1,6 +1,7 @@ package org.example.myapp.web; import java.util.List; +import java.util.Set; import javax.validation.Valid; import javax.validation.constraints.Email; @@ -8,6 +9,7 @@ import javax.validation.constraints.Size; import io.avaje.http.api.Header; +import io.avaje.http.api.QueryParam; import io.avaje.jsonb.Json; @Json @@ -23,8 +25,10 @@ public class GetBeanForm { private String email; private List addresses; - @Header - private String head; + + @Header private String head; + + @QueryParam private Set type; public String getName() { return name; @@ -67,4 +71,12 @@ public String getHead() { public void setHead(String head) { this.head = head; } + + public Set getType() { + return type; + } + + public void setType(Set type) { + this.type = type; + } } diff --git a/tests/test-javalin-jsonb/src/test/java/org/example/myapp/HelloControllerTest.java b/tests/test-javalin-jsonb/src/test/java/org/example/myapp/HelloControllerTest.java index 2939847a8..e0eabef84 100644 --- a/tests/test-javalin-jsonb/src/test/java/org/example/myapp/HelloControllerTest.java +++ b/tests/test-javalin-jsonb/src/test/java/org/example/myapp/HelloControllerTest.java @@ -241,6 +241,7 @@ void get_validate_bean_expect422() { final HttpResponse hres = client.request() .path("hello/withValidBean") .queryParam("email", "user@foo.com") + .queryParam("type", "PROXY") .GET() .asString(); @@ -253,6 +254,7 @@ void get_validate_bean_expect200() { .path("hello/withValidBean") .queryParam("name", "hello") .queryParam("email", "user@foo.com") + .queryParam("type", "PROXY") .GET() .asString(); From 11fafa5d6a107d5a6564aebd10df163d1f3b6958 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Mon, 20 Mar 2023 10:19:11 +1300 Subject: [PATCH 0697/1323] Change HttpClient tests to use jakarta.validation (from javax) --- http-client/pom.xml | 10 ++-------- .../org/example/webserver/HelloController.java | 3 +-- .../java/org/example/webserver/HelloForm.java | 10 +++++----- .../src/main/resources/public/openapi.json | 15 +++++++++++++++ 4 files changed, 23 insertions(+), 15 deletions(-) diff --git a/http-client/pom.xml b/http-client/pom.xml index 2274d1766..b73133458 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -80,7 +80,7 @@ io.avaje avaje-http-hibernate-validator - 2.8 + 3.2 test @@ -106,7 +106,7 @@ io.avaje avaje-inject-generator - 8.10 + 9.0-RC3 @@ -114,12 +114,6 @@ - - - maven-surefire-plugin - 3.0.0-M6 - - diff --git a/http-client/src/test/java/org/example/webserver/HelloController.java b/http-client/src/test/java/org/example/webserver/HelloController.java index 63256abb6..f72598ae2 100644 --- a/http-client/src/test/java/org/example/webserver/HelloController.java +++ b/http-client/src/test/java/org/example/webserver/HelloController.java @@ -3,9 +3,8 @@ import io.avaje.http.api.*; import io.javalin.http.Context; -import javax.validation.Valid; +import jakarta.validation.Valid; import java.time.LocalDate; -import java.time.ZoneId; import java.util.ArrayList; import java.util.Base64; import java.util.List; diff --git a/http-client/src/test/java/org/example/webserver/HelloForm.java b/http-client/src/test/java/org/example/webserver/HelloForm.java index fdf1a34cf..3b37ea403 100644 --- a/http-client/src/test/java/org/example/webserver/HelloForm.java +++ b/http-client/src/test/java/org/example/webserver/HelloForm.java @@ -4,11 +4,11 @@ import org.hibernate.validator.constraints.URL; -import javax.validation.Valid; -import javax.validation.constraints.Email; -import javax.validation.constraints.Future; -import javax.validation.constraints.NotNull; -import javax.validation.constraints.Size; +import jakarta.validation.Valid; +import jakarta.validation.constraints.Email; +import jakarta.validation.constraints.Future; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; import java.time.LocalDate; @Valid diff --git a/tests/test-javalin-jsonb/src/main/resources/public/openapi.json b/tests/test-javalin-jsonb/src/main/resources/public/openapi.json index 29be3beca..3eee94924 100644 --- a/tests/test-javalin-jsonb/src/main/resources/public/openapi.json +++ b/tests/test-javalin-jsonb/src/main/resources/public/openapi.json @@ -726,6 +726,21 @@ "schema" : { "type" : "string" } + }, + { + "name" : "type", + "in" : "query", + "schema" : { + "type" : "array", + "items" : { + "type" : "string", + "enum" : [ + "PROXY", + "HIDE_N_SEEK", + "FFA" + ] + } + } } ], "responses" : { From 3f65ee76b1def61247d670f285157f02b437c9ba Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Mon, 20 Mar 2023 10:42:53 +1300 Subject: [PATCH 0698/1323] Version 1.33 --- http-api/pom.xml | 2 +- http-client-gson-adapter/pom.xml | 4 ++-- http-client/pom.xml | 2 +- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 2 +- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-generator-nima/pom.xml | 2 +- pom.xml | 2 +- tests/pom.xml | 2 +- tests/test-client-generation/pom.xml | 2 +- tests/test-client/pom.xml | 2 +- tests/test-helidon/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- 19 files changed, 20 insertions(+), 20 deletions(-) diff --git a/http-api/pom.xml b/http-api/pom.xml index ff10a1de3..f575fad73 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.32 + 1.33 .. diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index 4e33aefd7..3baa9ea3a 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.32 + 1.33 avaje-http-client-gson @@ -20,7 +20,7 @@ io.avaje avaje-http-client - 1.32 + 1.33 provided diff --git a/http-client/pom.xml b/http-client/pom.xml index b73133458..8003298ee 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.32 + 1.33 avaje-http-client diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index 20bfa22ab..9f104275b 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.32 + 1.33 avaje-http-client-generator diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 42d5b1791..2b37dff38 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.32 + 1.33 avaje-http-generator-core diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index ec372c628..f3d321d89 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.32 + 1.33 avaje-http-helidon-generator diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index 049e8c338..1abd17480 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.32 + 1.33 avaje-http-javalin-generator diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index 2874998cd..fc08869ab 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.32 + 1.33 avaje-http-jex-generator diff --git a/http-generator-nima/pom.xml b/http-generator-nima/pom.xml index e4158ecb8..e4626ea34 100644 --- a/http-generator-nima/pom.xml +++ b/http-generator-nima/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 1.32 + 1.33 avaje-http-nima-generator diff --git a/pom.xml b/pom.xml index a36d36ee3..88e781a94 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-parent - 1.32 + 1.33 pom diff --git a/tests/pom.xml b/tests/pom.xml index ad404773d..46599df56 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 1.32 + 1.33 tests diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index 18c65a2f7..9de6311f5 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.32 + 1.33 test-client-generation diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index d9e83c38a..9e1b899d1 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 1.32 + 1.33 test-client diff --git a/tests/test-helidon/pom.xml b/tests/test-helidon/pom.xml index 560f60923..0c4a7d779 100644 --- a/tests/test-helidon/pom.xml +++ b/tests/test-helidon/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.32 + 1.33 test-helidon diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index e41a204dd..22d9b70cd 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 1.32 + 1.33 test-javalin-jsonb diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 60eb61a3e..984f36fb0 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.32 + 1.33 test-javalin diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 7acfa7d12..be7a378ac 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.32 + 1.33 test-jex diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index d8cf9251f..bd274cf08 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.32 + 1.33 test-nima-jsonb diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index 748da0da2..2c44e43f9 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 1.32 + 1.33 test-nima From 24bf0b22cb972af588a7ca367a0b82e65024c2ce Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Mon, 20 Mar 2023 10:43:37 +1300 Subject: [PATCH 0699/1323] Bump to next snapshot version --- http-api/pom.xml | 2 +- http-client-gson-adapter/pom.xml | 4 ++-- http-client/pom.xml | 2 +- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 2 +- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-generator-nima/pom.xml | 2 +- pom.xml | 2 +- tests/pom.xml | 2 +- tests/test-client-generation/pom.xml | 2 +- tests/test-client/pom.xml | 2 +- tests/test-helidon/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- 19 files changed, 20 insertions(+), 20 deletions(-) diff --git a/http-api/pom.xml b/http-api/pom.xml index f575fad73..0e2681e4a 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.33 + 1.34-SNAPSHOT .. diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index 3baa9ea3a..e912a7fcc 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.33 + 1.34-SNAPSHOT avaje-http-client-gson @@ -20,7 +20,7 @@ io.avaje avaje-http-client - 1.33 + 1.34-SNAPSHOT provided diff --git a/http-client/pom.xml b/http-client/pom.xml index 8003298ee..f9feef7f1 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.33 + 1.34-SNAPSHOT avaje-http-client diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index 9f104275b..2461f4305 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.33 + 1.34-SNAPSHOT avaje-http-client-generator diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 2b37dff38..16caf9525 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.33 + 1.34-SNAPSHOT avaje-http-generator-core diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index f3d321d89..01d761f73 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.33 + 1.34-SNAPSHOT avaje-http-helidon-generator diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index 1abd17480..1074dffd3 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.33 + 1.34-SNAPSHOT avaje-http-javalin-generator diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index fc08869ab..8df466233 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.33 + 1.34-SNAPSHOT avaje-http-jex-generator diff --git a/http-generator-nima/pom.xml b/http-generator-nima/pom.xml index e4626ea34..b5cffb06f 100644 --- a/http-generator-nima/pom.xml +++ b/http-generator-nima/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 1.33 + 1.34-SNAPSHOT avaje-http-nima-generator diff --git a/pom.xml b/pom.xml index 88e781a94..1c63078e7 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-parent - 1.33 + 1.34-SNAPSHOT pom diff --git a/tests/pom.xml b/tests/pom.xml index 46599df56..8a3613371 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 1.33 + 1.34-SNAPSHOT tests diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index 9de6311f5..c77217273 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.33 + 1.34-SNAPSHOT test-client-generation diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index 9e1b899d1..def011002 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 1.33 + 1.34-SNAPSHOT test-client diff --git a/tests/test-helidon/pom.xml b/tests/test-helidon/pom.xml index 0c4a7d779..f84780481 100644 --- a/tests/test-helidon/pom.xml +++ b/tests/test-helidon/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.33 + 1.34-SNAPSHOT test-helidon diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 22d9b70cd..63ac10fb4 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 1.33 + 1.34-SNAPSHOT test-javalin-jsonb diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 984f36fb0..f3b3bfccb 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.33 + 1.34-SNAPSHOT test-javalin diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index be7a378ac..fd3f01ece 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.33 + 1.34-SNAPSHOT test-jex diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index bd274cf08..beca4f1ed 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.33 + 1.34-SNAPSHOT test-nima-jsonb diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index 2c44e43f9..567107371 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 1.33 + 1.34-SNAPSHOT test-nima From e43a596d5bf4fb7c3dde44d024f3e958d21efcd4 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Mon, 20 Mar 2023 15:51:45 +1300 Subject: [PATCH 0700/1323] Fix #188 - IllegalAccessError io.avaje.http.generator.core.openapi.KnownTypes ... does not read module java.sql (#190) --- http-generator-client/src/main/java/module-info.java | 1 + http-generator-helidon/src/main/java/module-info.java | 1 + http-generator-javalin/src/main/java/module-info.java | 1 + http-generator-jex/src/main/java/module-info.java | 1 + http-generator-nima/src/main/java/module-info.java | 1 + 5 files changed, 5 insertions(+) diff --git a/http-generator-client/src/main/java/module-info.java b/http-generator-client/src/main/java/module-info.java index 9779dd07e..09c6b3e21 100644 --- a/http-generator-client/src/main/java/module-info.java +++ b/http-generator-client/src/main/java/module-info.java @@ -3,6 +3,7 @@ provides javax.annotation.processing.Processor with io.avaje.http.generator.client.ClientProcessor; requires java.compiler; + requires java.sql; // SHADED: All content after this line will be removed at package time requires transitive io.avaje.http.generator.core; diff --git a/http-generator-helidon/src/main/java/module-info.java b/http-generator-helidon/src/main/java/module-info.java index 4b99fdca1..17e9fec1f 100644 --- a/http-generator-helidon/src/main/java/module-info.java +++ b/http-generator-helidon/src/main/java/module-info.java @@ -3,6 +3,7 @@ provides javax.annotation.processing.Processor with io.avaje.http.generator.helidon.HelidonProcessor; requires java.compiler; + requires java.sql; // SHADED: All content after this line will be removed at package time requires transitive io.avaje.http.generator.core; diff --git a/http-generator-javalin/src/main/java/module-info.java b/http-generator-javalin/src/main/java/module-info.java index 8394c4933..9d5f69e8c 100644 --- a/http-generator-javalin/src/main/java/module-info.java +++ b/http-generator-javalin/src/main/java/module-info.java @@ -3,6 +3,7 @@ provides javax.annotation.processing.Processor with io.avaje.http.generator.javalin.JavalinProcessor; requires java.compiler; + requires java.sql; // SHADED: All content after this line will be removed at package time requires transitive io.avaje.http.generator.core; diff --git a/http-generator-jex/src/main/java/module-info.java b/http-generator-jex/src/main/java/module-info.java index 56d367564..c87618944 100644 --- a/http-generator-jex/src/main/java/module-info.java +++ b/http-generator-jex/src/main/java/module-info.java @@ -3,6 +3,7 @@ provides javax.annotation.processing.Processor with io.avaje.http.generator.jex.JexProcessor; requires java.compiler; + requires java.sql; // SHADED: All content after this line will be removed at package time requires transitive io.avaje.http.generator.core; diff --git a/http-generator-nima/src/main/java/module-info.java b/http-generator-nima/src/main/java/module-info.java index a17a78106..166a3303a 100644 --- a/http-generator-nima/src/main/java/module-info.java +++ b/http-generator-nima/src/main/java/module-info.java @@ -3,6 +3,7 @@ provides javax.annotation.processing.Processor with io.avaje.http.generator.helidon.nima.NimaProcessor; requires java.compiler; + requires java.sql; // SHADED: All content after this line will be removed at package time requires transitive io.avaje.http.generator.core; From 83dd9adfbb823fb7c12dd5437c5ac8f1e46371ca Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Mon, 20 Mar 2023 23:45:26 -0400 Subject: [PATCH 0701/1323] Nima JsonB Stream (#191) * nima stream * Revert "nima stream" This reverts commit d3f8b08b5bd5c090bb1b92ffcec06971a9cd3906. * use the new jsonb json output --- .../helidon/nima/ControllerMethodWriter.java | 4 ++-- .../generator/helidon/nima/ControllerWriter.java | 1 + tests/test-nima-jsonb/pom.xml | 14 ++------------ 3 files changed, 5 insertions(+), 14 deletions(-) diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java index c9dfb90ad..8d80988d0 100644 --- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java +++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java @@ -42,7 +42,7 @@ void writeHandler(boolean requestScoped) { final var bodyType = method.bodyType(); if (bodyType != null) { - if (bodyType.equals("InputStream")) { + if ("InputStream".equals(bodyType)) { writer.append(" var %s = req.content().inputStream();", method.bodyName()).eol(); } else if (useJsonB) { final var fieldName = @@ -118,7 +118,7 @@ void writeHandler(boolean requestScoped) { writeContextReturn(); if (producesJson()) { final var uType = UType.parse(method.returnType()); - writer.append(" %sJsonType.toJson(result, res.outputStream());", uType.shortName()).eol(); + writer.append(" %sJsonType.toJson(result, JsonOutput.of(res));", uType.shortName()).eol(); } else { writer.append(" res.send(result);").eol(); } diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java index ff155735e..38f811ff0 100644 --- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java +++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java @@ -23,6 +23,7 @@ class ControllerWriter extends BaseControllerWriter { reader.addImportType("io.avaje.jsonb.Jsonb"); reader.addImportType("io.avaje.jsonb.JsonType"); reader.addImportType("io.avaje.jsonb.Types"); + reader.addImportType("io.avaje.jsonb.stream.JsonOutput"); this.jsonTypes = JsonBUtil.jsonTypes(reader); jsonTypes.values().stream() .map(UType::importTypes) diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index beca4f1ed..34b100aec 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -36,12 +36,12 @@ io.helidon.nima.webserver helidon-nima-webserver - 4.0.0-ALPHA4 + 4.0.0-ALPHA5 io.helidon.nima.http.media helidon-nima-http-media-jsonb - 4.0.0-ALPHA4 + 4.0.0-ALPHA5 io.avaje @@ -49,16 +49,6 @@ ${project.version} test - - - - - - - - - - io.avaje junit From 3ef93c373eaae802cd570f75f09e862e93c82b46 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 21 Mar 2023 16:56:04 +1300 Subject: [PATCH 0702/1323] Bump Nima test to use jsonb 1.4-RC7 with JsonOutput support --- tests/test-nima-jsonb/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 34b100aec..b478d5ab3 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -31,7 +31,7 @@ io.avaje avaje-jsonb - 1.1 + 1.4-RC7 io.helidon.nima.webserver @@ -79,7 +79,7 @@ io.avaje avaje-jsonb-generator - 1.1 + 1.4-RC7 From 10c8fa1f751866b698724d350dcf9e44b87c4b29 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 21 Mar 2023 17:02:04 +1300 Subject: [PATCH 0703/1323] Version 1.34-RC1 --- http-api/pom.xml | 2 +- http-client-gson-adapter/pom.xml | 4 ++-- http-client/pom.xml | 2 +- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 2 +- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-generator-nima/pom.xml | 2 +- pom.xml | 2 +- tests/pom.xml | 2 +- tests/test-client-generation/pom.xml | 2 +- tests/test-client/pom.xml | 2 +- tests/test-helidon/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- 19 files changed, 20 insertions(+), 20 deletions(-) diff --git a/http-api/pom.xml b/http-api/pom.xml index 0e2681e4a..6217b9af8 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.34-SNAPSHOT + 1.34-RC1 .. diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index e912a7fcc..bf8cc13cd 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.34-SNAPSHOT + 1.34-RC1 avaje-http-client-gson @@ -20,7 +20,7 @@ io.avaje avaje-http-client - 1.34-SNAPSHOT + 1.34-RC1 provided diff --git a/http-client/pom.xml b/http-client/pom.xml index f9feef7f1..df2c72ecc 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.34-SNAPSHOT + 1.34-RC1 avaje-http-client diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index 2461f4305..94709aa03 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.34-SNAPSHOT + 1.34-RC1 avaje-http-client-generator diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 16caf9525..5bb54bb3c 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.34-SNAPSHOT + 1.34-RC1 avaje-http-generator-core diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index 01d761f73..1e6af82b1 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.34-SNAPSHOT + 1.34-RC1 avaje-http-helidon-generator diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index 1074dffd3..0b9cd4e2d 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.34-SNAPSHOT + 1.34-RC1 avaje-http-javalin-generator diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index 8df466233..b38ba3400 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.34-SNAPSHOT + 1.34-RC1 avaje-http-jex-generator diff --git a/http-generator-nima/pom.xml b/http-generator-nima/pom.xml index b5cffb06f..dcaf2cfde 100644 --- a/http-generator-nima/pom.xml +++ b/http-generator-nima/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 1.34-SNAPSHOT + 1.34-RC1 avaje-http-nima-generator diff --git a/pom.xml b/pom.xml index 1c63078e7..0ead8f45c 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-parent - 1.34-SNAPSHOT + 1.34-RC1 pom diff --git a/tests/pom.xml b/tests/pom.xml index 8a3613371..4102e705b 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 1.34-SNAPSHOT + 1.34-RC1 tests diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index c77217273..883c25fe8 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.34-SNAPSHOT + 1.34-RC1 test-client-generation diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index def011002..402fe45d2 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 1.34-SNAPSHOT + 1.34-RC1 test-client diff --git a/tests/test-helidon/pom.xml b/tests/test-helidon/pom.xml index f84780481..4e77b2e57 100644 --- a/tests/test-helidon/pom.xml +++ b/tests/test-helidon/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.34-SNAPSHOT + 1.34-RC1 test-helidon diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 63ac10fb4..aa81e43d9 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 1.34-SNAPSHOT + 1.34-RC1 test-javalin-jsonb diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index f3b3bfccb..d296e7d88 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.34-SNAPSHOT + 1.34-RC1 test-javalin diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index fd3f01ece..77ec604e3 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.34-SNAPSHOT + 1.34-RC1 test-jex diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index b478d5ab3..24a525fed 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.34-SNAPSHOT + 1.34-RC1 test-nima-jsonb diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index 567107371..f5745fae7 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 1.34-SNAPSHOT + 1.34-RC1 test-nima From ad30a41983022e0d811d1acf9f4ea3dd395970cc Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Tue, 21 Mar 2023 00:13:29 -0400 Subject: [PATCH 0704/1323] remove compiler plugin from quick start --- README.md | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/README.md b/README.md index 7c2e188ba..d859b557f 100644 --- a/README.md +++ b/README.md @@ -45,30 +45,6 @@ to generate adapter code for Javalin and Helidon SE/Nima. provided ``` -If there are other annotation processors and they are specified via maven-compiler-plugin then we add avaje-http-generator there instead. -```xml - - org.apache.maven.plugins - maven-compiler-plugin - - - - io.avaje - avaje-inject-generator - ${avaje-inject.version} - - - io.avaje - avaje-http-javalin-generator - ${avaje-http.version} - - - ... other annotation processor ... - - - - -``` ## Define a Controller (These APT processors work with both Java and Kotlin.) ```java From 736da4e195365abf3bf888e3abe91044ff332ccb Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Tue, 21 Mar 2023 00:16:01 -0400 Subject: [PATCH 0705/1323] RC8 --- tests/test-nima-jsonb/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 24a525fed..ab1e88647 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -31,7 +31,7 @@ io.avaje avaje-jsonb - 1.4-RC7 + 1.4-RC8 io.helidon.nima.webserver @@ -79,7 +79,7 @@ io.avaje avaje-jsonb-generator - 1.4-RC7 + 1.4-RC8 From 5766c9cd551cf35dac6110f8520c7815f8ea02ad Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Sun, 2 Apr 2023 18:10:55 +1200 Subject: [PATCH 0706/1323] Version 1.34 --- http-api/pom.xml | 2 +- http-client-gson-adapter/pom.xml | 4 ++-- http-client/pom.xml | 2 +- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 2 +- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-generator-nima/pom.xml | 2 +- pom.xml | 2 +- tests/pom.xml | 2 +- tests/test-client-generation/pom.xml | 2 +- tests/test-client/pom.xml | 2 +- tests/test-helidon/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- 19 files changed, 20 insertions(+), 20 deletions(-) diff --git a/http-api/pom.xml b/http-api/pom.xml index 6217b9af8..fa4672167 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.34-RC1 + 1.34 .. diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index bf8cc13cd..10fa868cd 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.34-RC1 + 1.34 avaje-http-client-gson @@ -20,7 +20,7 @@ io.avaje avaje-http-client - 1.34-RC1 + 1.34 provided diff --git a/http-client/pom.xml b/http-client/pom.xml index df2c72ecc..524e76e8a 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.34-RC1 + 1.34 avaje-http-client diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index 94709aa03..2642e7d48 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.34-RC1 + 1.34 avaje-http-client-generator diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 5bb54bb3c..d58f954ff 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.34-RC1 + 1.34 avaje-http-generator-core diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index 1e6af82b1..998aec9e0 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.34-RC1 + 1.34 avaje-http-helidon-generator diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index 0b9cd4e2d..97989f936 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.34-RC1 + 1.34 avaje-http-javalin-generator diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index b38ba3400..848d02378 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.34-RC1 + 1.34 avaje-http-jex-generator diff --git a/http-generator-nima/pom.xml b/http-generator-nima/pom.xml index dcaf2cfde..c43426c5e 100644 --- a/http-generator-nima/pom.xml +++ b/http-generator-nima/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 1.34-RC1 + 1.34 avaje-http-nima-generator diff --git a/pom.xml b/pom.xml index 0ead8f45c..e49d33e58 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-parent - 1.34-RC1 + 1.34 pom diff --git a/tests/pom.xml b/tests/pom.xml index 4102e705b..38d12a99f 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 1.34-RC1 + 1.34 tests diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index 883c25fe8..c5ade2b62 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.34-RC1 + 1.34 test-client-generation diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index 402fe45d2..8524573f8 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 1.34-RC1 + 1.34 test-client diff --git a/tests/test-helidon/pom.xml b/tests/test-helidon/pom.xml index 4e77b2e57..5fb2454af 100644 --- a/tests/test-helidon/pom.xml +++ b/tests/test-helidon/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.34-RC1 + 1.34 test-helidon diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index aa81e43d9..224c0c92e 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 1.34-RC1 + 1.34 test-javalin-jsonb diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index d296e7d88..606bd037e 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.34-RC1 + 1.34 test-javalin diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 77ec604e3..4d1bc6460 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.34-RC1 + 1.34 test-jex diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index ab1e88647..1669adfa2 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.34-RC1 + 1.34 test-nima-jsonb diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index f5745fae7..314fb4c94 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 1.34-RC1 + 1.34 test-nima From fcbbd0773b59c3c5ec93fba3cb9a43c7886b6cc3 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sun, 2 Apr 2023 12:16:31 -0400 Subject: [PATCH 0707/1323] use more generic type --- .../io/avaje/http/client/BodyAdapter.java | 14 ++++++------ .../avaje/http/client/DHttpClientContext.java | 10 ++++----- .../avaje/http/client/DHttpClientRequest.java | 22 +++++++++---------- .../avaje/http/client/HttpClientRequest.java | 4 ++-- .../avaje/http/client/HttpClientResponse.java | 14 ++++++------ .../avaje/http/client/JsonbBodyAdapter.java | 4 ++-- 6 files changed, 34 insertions(+), 34 deletions(-) diff --git a/http-client/src/main/java/io/avaje/http/client/BodyAdapter.java b/http-client/src/main/java/io/avaje/http/client/BodyAdapter.java index 31e4efba1..5cb9f2ee3 100644 --- a/http-client/src/main/java/io/avaje/http/client/BodyAdapter.java +++ b/http-client/src/main/java/io/avaje/http/client/BodyAdapter.java @@ -1,6 +1,6 @@ package io.avaje.http.client; -import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; import java.util.List; /** @@ -22,9 +22,9 @@ public interface BodyAdapter { * * @param type The type of the bean this writer is for */ - default BodyWriter beanWriter(ParameterizedType type) { + default BodyWriter beanWriter(Type type) { - throw new UnsupportedOperationException("Parameterized types not supported for this adapter"); + throw new UnsupportedOperationException("java.lang.reflect.Type is not supported for this adapter"); } /** @@ -39,8 +39,8 @@ default BodyWriter beanWriter(ParameterizedType type) { * * @param type The bean type to convert the content to. */ - default BodyReader beanReader(ParameterizedType type) { - throw new UnsupportedOperationException("Parameterized types not supported for this adapter"); + default BodyReader beanReader(Type type) { + throw new UnsupportedOperationException("java.lang.reflect.Type is not supported for this adapter"); } /** @@ -55,7 +55,7 @@ default BodyReader beanReader(ParameterizedType type) { * * @param type The bean type to convert the content to. */ - default BodyReader> listReader(ParameterizedType type) { - throw new UnsupportedOperationException("Parameterized types not supported for this adapter"); + default BodyReader> listReader(Type type) { + throw new UnsupportedOperationException("java.lang.reflect.Type is not supported for this adapter"); } } diff --git a/http-client/src/main/java/io/avaje/http/client/DHttpClientContext.java b/http-client/src/main/java/io/avaje/http/client/DHttpClientContext.java index 598110f18..7eb7b0979 100644 --- a/http-client/src/main/java/io/avaje/http/client/DHttpClientContext.java +++ b/http-client/src/main/java/io/avaje/http/client/DHttpClientContext.java @@ -2,7 +2,7 @@ import java.io.IOException; import java.lang.reflect.Constructor; -import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; import java.net.http.HttpHeaders; import java.net.http.HttpRequest; import java.net.http.HttpResponse; @@ -269,7 +269,7 @@ BodyContent write(T bean, Class type, String contentType) { return bodyAdapter.beanWriter(type).write(bean, contentType); } - BodyContent write(T bean, ParameterizedType type, String contentType) { + BodyContent write(T bean, Type type, String contentType) { return bodyAdapter.beanWriter(type).write(bean, contentType); } @@ -277,7 +277,7 @@ BodyReader beanReader(Class type) { return bodyAdapter.beanReader(type); } - BodyReader beanReader(ParameterizedType type) { + BodyReader beanReader(Type type) { return bodyAdapter.beanReader(type); } @@ -290,12 +290,12 @@ List readList(Class type, BodyContent content) { } @SuppressWarnings("unchecked") - T readBean(ParameterizedType type, BodyContent content) { + T readBean(Type type, BodyContent content) { return (T) bodyAdapter.beanReader(type).read(content); } @SuppressWarnings("unchecked") - List readList(ParameterizedType type, BodyContent content) { + List readList(Type type, BodyContent content) { return (List) bodyAdapter.listReader(type).read(content); } diff --git a/http-client/src/main/java/io/avaje/http/client/DHttpClientRequest.java b/http-client/src/main/java/io/avaje/http/client/DHttpClientRequest.java index 9728fa585..19d4414f5 100644 --- a/http-client/src/main/java/io/avaje/http/client/DHttpClientRequest.java +++ b/http-client/src/main/java/io/avaje/http/client/DHttpClientRequest.java @@ -3,7 +3,7 @@ import javax.net.ssl.SSLSession; import java.io.FileNotFoundException; import java.io.InputStream; -import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; import java.net.URI; import java.net.URLEncoder; import java.net.http.HttpClient; @@ -282,7 +282,7 @@ public HttpClientRequest body(Object bean, Class type) { } @Override - public HttpClientRequest body(Object bean, ParameterizedType type) { + public HttpClientRequest body(Object bean, Type type) { encodedRequestBody = context.write(bean, type, null); return this; } @@ -465,7 +465,7 @@ public HttpResponse as(Class type) { } @Override - public HttpResponse as(ParameterizedType type) { + public HttpResponse as(Type type) { return new HttpWrapperResponse<>(bean(type), httpResponse); } @@ -476,7 +476,7 @@ public T bean(Class type) { } @Override - public T bean(ParameterizedType type) { + public T bean(Type type) { readResponseContent(); return context.readBean(type, encodedResponseBody); } @@ -487,7 +487,7 @@ public HttpResponse> asList(Class type) { } @Override - public HttpResponse> asList(ParameterizedType type) { + public HttpResponse> asList(Type type) { return new HttpWrapperResponse<>(list(type), httpResponse); } @@ -498,7 +498,7 @@ public List list(Class type) { } @Override - public List list(ParameterizedType type) { + public List list(Type type) { readResponseContent(); return context.readList(type, encodedResponseBody); } @@ -509,7 +509,7 @@ public HttpResponse> asStream(Class type) { } @Override - public HttpResponse> asStream(ParameterizedType type) { + public HttpResponse> asStream(Type type) { return new HttpWrapperResponse<>(stream(type), httpResponse); } @@ -519,7 +519,7 @@ public Stream stream(Class type) { } @Override - public Stream stream(ParameterizedType type) { + public Stream stream(Type type) { return stream(context.beanReader(type)); } @@ -577,7 +577,7 @@ protected HttpResponse asyncBean(Class type, HttpResponse resp return new HttpWrapperResponse<>(context.readBean(type, encodedResponseBody), httpResponse); } - protected E asyncBean(ParameterizedType type, HttpResponse response) { + protected E asyncBean(Type type, HttpResponse response) { afterAsyncEncoded(response); return context.readBean(type, encodedResponseBody); } @@ -587,7 +587,7 @@ protected HttpResponse> asyncList(Class type, HttpResponse(context.readList(type, encodedResponseBody), httpResponse); } - protected HttpResponse> asyncList(ParameterizedType type, HttpResponse response) { + protected HttpResponse> asyncList(Type type, HttpResponse response) { afterAsyncEncoded(response); return new HttpWrapperResponse<>(context.readList(type, encodedResponseBody), httpResponse); } @@ -603,7 +603,7 @@ protected HttpResponse> asyncStream(Class type, HttpResponse(response.body().map(bodyReader::readBody), httpResponse); } - protected HttpResponse> asyncStream(ParameterizedType type, HttpResponse> response) { + protected HttpResponse> asyncStream(Type type, HttpResponse> response) { responseTimeNanos = System.nanoTime() - startAsyncNanos; httpResponse = response; context.afterResponse(this); diff --git a/http-client/src/main/java/io/avaje/http/client/HttpClientRequest.java b/http-client/src/main/java/io/avaje/http/client/HttpClientRequest.java index c2e846905..fd31804d5 100644 --- a/http-client/src/main/java/io/avaje/http/client/HttpClientRequest.java +++ b/http-client/src/main/java/io/avaje/http/client/HttpClientRequest.java @@ -1,7 +1,7 @@ package io.avaje.http.client; import java.io.InputStream; -import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; import java.net.http.HttpRequest; import java.net.http.HttpResponse; import java.nio.file.Path; @@ -324,7 +324,7 @@ default HttpClientRequest queryParam(String name, Collection values) { * @param type The parameterized type used by the body content adapter to write the body content * @return The request being built */ - HttpClientRequest body(Object bean, ParameterizedType type); + HttpClientRequest body(Object bean, Type type); /** * Set the body as a bean with the given content type and additionally specifying diff --git a/http-client/src/main/java/io/avaje/http/client/HttpClientResponse.java b/http-client/src/main/java/io/avaje/http/client/HttpClientResponse.java index 4695213f8..39523aea7 100644 --- a/http-client/src/main/java/io/avaje/http/client/HttpClientResponse.java +++ b/http-client/src/main/java/io/avaje/http/client/HttpClientResponse.java @@ -1,7 +1,7 @@ package io.avaje.http.client; import java.io.InputStream; -import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; import java.net.http.HttpResponse; import java.nio.file.Path; import java.util.List; @@ -83,7 +83,7 @@ public interface HttpClientResponse { * @return The response containing the converted body. * @throws HttpException when the response has error status codes */ - HttpResponse as(ParameterizedType type); + HttpResponse as(Type type); /** * Return the response with the body containing a list of the given type. @@ -109,7 +109,7 @@ public interface HttpClientResponse { * @return The response containing the converted body. * @throws HttpException when the response has error status codes */ - HttpResponse> asList(ParameterizedType type); + HttpResponse> asList(Type type); /** * Return the response with the body containing a stream of beans of the given type. @@ -151,7 +151,7 @@ public interface HttpClientResponse { * @return The response containing the converted body. * @throws HttpException when the response has error status codes */ - HttpResponse> asStream(ParameterizedType type); + HttpResponse> asStream(Type type); /** * Return the response as a single bean. @@ -210,7 +210,7 @@ public interface HttpClientResponse { * @return The bean the response is converted into. * @throws HttpException when the response has error status codes */ - T bean(ParameterizedType type); + T bean(Type type); /** * Return the response as a list of beans. @@ -222,7 +222,7 @@ public interface HttpClientResponse { * @return The list of beans the response is converted into. * @throws HttpException when the response has error status codes */ - List list(ParameterizedType type); + List list(Type type); /** * Return the response as a stream of beans. @@ -242,7 +242,7 @@ public interface HttpClientResponse { * @return The stream of beans from the response * @throws HttpException when the response has error status codes */ - Stream stream(ParameterizedType type); + Stream stream(Type type); /** * Return the response with check for 200 range status code. diff --git a/http-client/src/main/java/io/avaje/http/client/JsonbBodyAdapter.java b/http-client/src/main/java/io/avaje/http/client/JsonbBodyAdapter.java index 95b7b94bf..838ffd052 100644 --- a/http-client/src/main/java/io/avaje/http/client/JsonbBodyAdapter.java +++ b/http-client/src/main/java/io/avaje/http/client/JsonbBodyAdapter.java @@ -49,7 +49,7 @@ public BodyWriter beanWriter(Class cls) { @SuppressWarnings("unchecked") @Override - public BodyWriter beanWriter(ParameterizedType type) { + public BodyWriter beanWriter(Type type) { return (BodyWriter) beanWriterCache.computeIfAbsent(type, aClass -> new JWriter<>(jsonb.type(type))); } @@ -61,7 +61,7 @@ public BodyReader beanReader(Class cls) { @SuppressWarnings("unchecked") @Override - public BodyReader beanReader(ParameterizedType type) { + public BodyReader beanReader(Type type) { return (BodyReader) beanReaderCache.computeIfAbsent(type, aClass -> new JReader<>(jsonb.type(type))); } From 41c41673a977f551f3fac5ee9c2cf1f3e916755d Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sun, 2 Apr 2023 13:08:53 -0400 Subject: [PATCH 0708/1323] Update JsonbBodyAdapter.java --- .../src/main/java/io/avaje/http/client/JsonbBodyAdapter.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/http-client/src/main/java/io/avaje/http/client/JsonbBodyAdapter.java b/http-client/src/main/java/io/avaje/http/client/JsonbBodyAdapter.java index 838ffd052..e6ef607e9 100644 --- a/http-client/src/main/java/io/avaje/http/client/JsonbBodyAdapter.java +++ b/http-client/src/main/java/io/avaje/http/client/JsonbBodyAdapter.java @@ -1,6 +1,5 @@ package io.avaje.http.client; -import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.List; import java.util.concurrent.ConcurrentHashMap; @@ -67,7 +66,7 @@ public BodyReader beanReader(Type type) { @SuppressWarnings("unchecked") @Override - public BodyReader> listReader(ParameterizedType type) { + public BodyReader> listReader(Type type) { return (BodyReader>) listReaderCache.computeIfAbsent(type, aClass -> new JReader<>(jsonb.type(type).list())); } From 25845702a4758bde739595500cea7deb013c2d93 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sun, 2 Apr 2023 14:28:55 -0400 Subject: [PATCH 0709/1323] now httpexception actually has a useful message --- .../src/main/java/io/avaje/http/client/HttpException.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/http-client/src/main/java/io/avaje/http/client/HttpException.java b/http-client/src/main/java/io/avaje/http/client/HttpException.java index f97049fb2..922e12b5a 100644 --- a/http-client/src/main/java/io/avaje/http/client/HttpException.java +++ b/http-client/src/main/java/io/avaje/http/client/HttpException.java @@ -75,7 +75,7 @@ public HttpException(int statusCode, Throwable cause) { } HttpException(HttpResponse httpResponse, DHttpClientContext context) { - super(); + super("Http Call failed with status: " + httpResponse.statusCode()); this.httpResponse = httpResponse; this.statusCode = httpResponse.statusCode(); this.context = context; @@ -83,7 +83,7 @@ public HttpException(int statusCode, Throwable cause) { } HttpException(DHttpClientContext context, HttpResponse httpResponse) { - super(); + super("Http Call failed with status: " + httpResponse.statusCode()); this.httpResponse = httpResponse; this.statusCode = httpResponse.statusCode(); this.context = context; From 44492968b6ff8086468173c90d7d7656f3373c59 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Mon, 3 Apr 2023 14:20:35 +1200 Subject: [PATCH 0710/1323] Client HttpException default message to use call (lower case) --- .../src/main/java/io/avaje/http/client/HttpException.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/http-client/src/main/java/io/avaje/http/client/HttpException.java b/http-client/src/main/java/io/avaje/http/client/HttpException.java index 922e12b5a..dd71c4255 100644 --- a/http-client/src/main/java/io/avaje/http/client/HttpException.java +++ b/http-client/src/main/java/io/avaje/http/client/HttpException.java @@ -75,7 +75,7 @@ public HttpException(int statusCode, Throwable cause) { } HttpException(HttpResponse httpResponse, DHttpClientContext context) { - super("Http Call failed with status: " + httpResponse.statusCode()); + super("Http call failed with status: " + httpResponse.statusCode()); this.httpResponse = httpResponse; this.statusCode = httpResponse.statusCode(); this.context = context; @@ -83,7 +83,7 @@ public HttpException(int statusCode, Throwable cause) { } HttpException(DHttpClientContext context, HttpResponse httpResponse) { - super("Http Call failed with status: " + httpResponse.statusCode()); + super("Http call failed with status: " + httpResponse.statusCode()); this.httpResponse = httpResponse; this.statusCode = httpResponse.statusCode(); this.context = context; From 5da5ea8f960780aa5440d85190de136271db7700 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Mon, 3 Apr 2023 15:14:34 +1200 Subject: [PATCH 0711/1323] Client HttpException, make all fields final --- .../main/java/io/avaje/http/client/HttpException.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/http-client/src/main/java/io/avaje/http/client/HttpException.java b/http-client/src/main/java/io/avaje/http/client/HttpException.java index dd71c4255..c9dce9993 100644 --- a/http-client/src/main/java/io/avaje/http/client/HttpException.java +++ b/http-client/src/main/java/io/avaje/http/client/HttpException.java @@ -44,8 +44,8 @@ public class HttpException extends RuntimeException { private final int statusCode; private final boolean responseAsBytes; - private DHttpClientContext context; - private HttpResponse httpResponse; + private final DHttpClientContext context; + private final HttpResponse httpResponse; /** * Create with status code and message. @@ -54,6 +54,8 @@ public HttpException(int statusCode, String message) { super(message); this.statusCode = statusCode; this.responseAsBytes = false; + this.context = null; + this.httpResponse = null; } /** @@ -63,6 +65,8 @@ public HttpException(int statusCode, String message, Throwable cause) { super(message, cause); this.statusCode = statusCode; this.responseAsBytes = false; + this.context = null; + this.httpResponse = null; } /** @@ -72,6 +76,8 @@ public HttpException(int statusCode, Throwable cause) { super(cause); this.statusCode = statusCode; this.responseAsBytes = false; + this.context = null; + this.httpResponse = null; } HttpException(HttpResponse httpResponse, DHttpClientContext context) { From e8d40cd1182c4f959213dcdf8800fe562c8574c5 Mon Sep 17 00:00:00 2001 From: Mechite <50027352+Mechite@users.noreply.github.com> Date: Mon, 3 Apr 2023 04:41:54 +0100 Subject: [PATCH 0712/1323] Update JavalinAdapter.java --- .../java/io/avaje/http/generator/javalin/JavalinAdapter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinAdapter.java b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinAdapter.java index a22914629..a6eeb3001 100644 --- a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinAdapter.java +++ b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinAdapter.java @@ -39,7 +39,7 @@ public String bodyAsClass(UType type) { if (useJsonB) { return type.shortName() + "JsonType.fromJson(ctx.bodyInputStream())"; } - return "ctx.bodyAsClass(" + type.mainType() + ".class)"; + return "ctx.<" + type.mainType() + ">bodyStreamAsClass(" + type.mainType() + ".class)"; } } From 42841decd1ef5ec1f7c35ac4839548c557b57ea2 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Mon, 3 Apr 2023 01:39:13 -0400 Subject: [PATCH 0713/1323] Async Generic Reflect Type --- .../java/io/avaje/http/client/DHttpAsync.java | 14 +++---- .../java/io/avaje/http/client/DHttpCall.java | 38 +++++++++---------- .../avaje/http/client/HttpAsyncResponse.java | 20 +++++----- .../avaje/http/client/HttpCallResponse.java | 14 +++---- .../avaje/http/client/HttpClientRequest.java | 2 +- .../avaje/http/client/HttpClientResponse.java | 14 +++---- 6 files changed, 51 insertions(+), 51 deletions(-) diff --git a/http-client/src/main/java/io/avaje/http/client/DHttpAsync.java b/http-client/src/main/java/io/avaje/http/client/DHttpAsync.java index c69638438..a4f150350 100644 --- a/http-client/src/main/java/io/avaje/http/client/DHttpAsync.java +++ b/http-client/src/main/java/io/avaje/http/client/DHttpAsync.java @@ -1,7 +1,7 @@ package io.avaje.http.client; import java.io.InputStream; -import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; import java.net.http.HttpResponse; import java.util.List; import java.util.concurrent.CompletableFuture; @@ -65,7 +65,7 @@ public CompletableFuture bean(Class type) { } @Override - public CompletableFuture bean(ParameterizedType type) { + public CompletableFuture bean(Type type) { final CompletableFuture> future = as(type); return future.thenApply(HttpResponse::body); } @@ -76,7 +76,7 @@ public CompletableFuture> as(Class type) { } @Override - public CompletableFuture> as(ParameterizedType type) { + public CompletableFuture> as(Type type) { return asyncAsBytes().thenApply(httpResponse -> request.asyncBean(type, httpResponse)); } @@ -86,7 +86,7 @@ public CompletableFuture> list(Class type) { } @Override - public CompletableFuture> list(ParameterizedType type) { + public CompletableFuture> list(Type type) { final CompletableFuture>> future = asList(type); return future.thenApply(HttpResponse::body); } @@ -97,7 +97,7 @@ public CompletableFuture>> asList(Class type) { } @Override - public CompletableFuture>> asList(ParameterizedType type) { + public CompletableFuture>> asList(Type type) { return asyncAsBytes().thenApply(httpResponse -> request.asyncList(type, httpResponse)); } @@ -107,7 +107,7 @@ public CompletableFuture> stream(Class type) { } @Override - public CompletableFuture> stream(ParameterizedType type) { + public CompletableFuture> stream(Type type) { final CompletableFuture>> future = asStream(type); return future.thenApply(HttpResponse::body); } @@ -118,7 +118,7 @@ public CompletableFuture>> asStream(Class type) { } @Override - public CompletableFuture>> asStream(ParameterizedType type) { + public CompletableFuture>> asStream(Type type) { return asyncAsLines().thenApply(httpResponse -> request.asyncStream(type, httpResponse)); } diff --git a/http-client/src/main/java/io/avaje/http/client/DHttpCall.java b/http-client/src/main/java/io/avaje/http/client/DHttpCall.java index 7882c0664..1a5a667e5 100644 --- a/http-client/src/main/java/io/avaje/http/client/DHttpCall.java +++ b/http-client/src/main/java/io/avaje/http/client/DHttpCall.java @@ -1,7 +1,7 @@ package io.avaje.http.client; import java.io.InputStream; -import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; import java.net.http.HttpResponse; import java.util.List; import java.util.concurrent.CompletableFuture; @@ -61,7 +61,7 @@ public HttpCall> as(Class type) { } @Override - public HttpCall> as(ParameterizedType type) { + public HttpCall> as(Type type) { return new CallAs<>(type); } @@ -71,7 +71,7 @@ public HttpCall>> asList(Class type) { } @Override - public HttpCall>> asList(ParameterizedType type) { + public HttpCall>> asList(Type type) { return new CallAsList<>(type); } @@ -81,7 +81,7 @@ public HttpCall>> asStream(Class type) { } @Override - public HttpCall>> asStream(ParameterizedType type) { + public HttpCall>> asStream(Type type) { return new CallAsStream<>(type); } @@ -96,17 +96,17 @@ public HttpCall> stream(Class type) { } @Override - public HttpCall bean(ParameterizedType type) { + public HttpCall bean(Type type) { return new CallBean<>(type); } @Override - public HttpCall> list(ParameterizedType type) { + public HttpCall> list(Type type) { return new CallList<>(type); } @Override - public HttpCall> stream(ParameterizedType type) { + public HttpCall> stream(Type type) { return new CallStream<>(type); } @@ -184,7 +184,7 @@ public CompletableFuture> async() { private class CallAs implements HttpCall> { private final Class type; - private final ParameterizedType genericType; + private final Type genericType; private final boolean isGeneric; CallAs(Class type) { @@ -193,7 +193,7 @@ private class CallAs implements HttpCall> { this.genericType = null; } - CallAs(ParameterizedType type) { + CallAs(Type type) { this.isGeneric = true; this.type = null; this.genericType = type; @@ -212,7 +212,7 @@ public CompletableFuture> async() { private class CallAsList implements HttpCall>> { private final Class type; - private final ParameterizedType genericType; + private final Type genericType; private final boolean isGeneric; CallAsList(Class type) { @@ -221,7 +221,7 @@ private class CallAsList implements HttpCall>> { this.genericType = null; } - CallAsList(ParameterizedType type) { + CallAsList(Type type) { this.isGeneric = true; this.type = null; this.genericType = type; @@ -240,7 +240,7 @@ public CompletableFuture>> async() { private class CallAsStream implements HttpCall>> { private final Class type; - private final ParameterizedType genericType; + private final Type genericType; private final boolean isGeneric; CallAsStream(Class type) { @@ -249,7 +249,7 @@ private class CallAsStream implements HttpCall>> { this.genericType = null; } - CallAsStream(ParameterizedType type) { + CallAsStream(Type type) { this.isGeneric = true; this.type = null; this.genericType = type; @@ -268,7 +268,7 @@ public CompletableFuture>> async() { private class CallBean implements HttpCall { private final Class type; - private final ParameterizedType genericType; + private final Type genericType; private final boolean isGeneric; CallBean(Class type) { @@ -277,7 +277,7 @@ private class CallBean implements HttpCall { this.genericType = null; } - CallBean(ParameterizedType type) { + CallBean(Type type) { this.isGeneric = true; this.type = null; this.genericType = type; @@ -296,7 +296,7 @@ public CompletableFuture async() { private class CallList implements HttpCall> { private final Class type; - private final ParameterizedType genericType; + private final Type genericType; private final boolean isGeneric; CallList(Class type) { @@ -305,7 +305,7 @@ private class CallList implements HttpCall> { this.genericType = null; } - CallList(ParameterizedType type) { + CallList(Type type) { this.isGeneric = true; this.type = null; this.genericType = type; @@ -324,7 +324,7 @@ public CompletableFuture> async() { private class CallStream implements HttpCall> { private final Class type; - private final ParameterizedType genericType; + private final Type genericType; private final boolean isGeneric; CallStream(Class type) { @@ -333,7 +333,7 @@ private class CallStream implements HttpCall> { this.genericType = null; } - CallStream(ParameterizedType type) { + CallStream(Type type) { this.isGeneric = true; this.type = null; this.genericType = type; diff --git a/http-client/src/main/java/io/avaje/http/client/HttpAsyncResponse.java b/http-client/src/main/java/io/avaje/http/client/HttpAsyncResponse.java index a7ec8e3db..ca39b400b 100644 --- a/http-client/src/main/java/io/avaje/http/client/HttpAsyncResponse.java +++ b/http-client/src/main/java/io/avaje/http/client/HttpAsyncResponse.java @@ -1,7 +1,7 @@ package io.avaje.http.client; import java.io.InputStream; -import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; import java.net.http.HttpResponse; import java.util.List; import java.util.concurrent.CompletableFuture; @@ -270,7 +270,7 @@ default CompletableFuture> withHandler(HttpResponse.BodyHand /** * The same as {@link #as(Class)} but using a generic type. */ - CompletableFuture> as(ParameterizedType type); + CompletableFuture> as(Type type); /** * Process expecting a bean response body (typically from json content). @@ -346,7 +346,7 @@ default CompletableFuture> withHandler(HttpResponse.BodyHand /** * The same as {@link #asList(Class)} but using a generic type. */ - CompletableFuture>> asList(ParameterizedType type); + CompletableFuture>> asList(Type type); /** * Process expecting a list of beans response body (typically from json content). @@ -419,7 +419,7 @@ default CompletableFuture> withHandler(HttpResponse.BodyHand /** * The same as {@link #asStream(Class)} but using a generic type. */ - CompletableFuture>> asStream(ParameterizedType type); + CompletableFuture>> asStream(Type type); /** * Process response as a stream of beans (x-json-stream). @@ -463,25 +463,25 @@ default CompletableFuture> withHandler(HttpResponse.BodyHand /** * Process expecting a bean response body (typically from json content). * - * @param type The parameterized type to convert the content to + * @param type The type to convert the content to * @return The CompletableFuture of the response */ - CompletableFuture bean(ParameterizedType type); + CompletableFuture bean(Type type); /** * Process expecting a list of beans response body (typically from json content). * - * @param type The parameterized type to convert the content to + * @param type The type to convert the content to * @return The CompletableFuture of the response */ - CompletableFuture> list(ParameterizedType type); + CompletableFuture> list(Type type); /** * Process response as a stream of beans (x-json-stream). * - * @param type The parameterized type to convert the content to + * @param type The type to convert the content to * @return The CompletableFuture of the response */ - CompletableFuture> stream(ParameterizedType type); + CompletableFuture> stream(Type type); } diff --git a/http-client/src/main/java/io/avaje/http/client/HttpCallResponse.java b/http-client/src/main/java/io/avaje/http/client/HttpCallResponse.java index 9001106b9..51040422d 100644 --- a/http-client/src/main/java/io/avaje/http/client/HttpCallResponse.java +++ b/http-client/src/main/java/io/avaje/http/client/HttpCallResponse.java @@ -1,7 +1,7 @@ package io.avaje.http.client; import java.io.InputStream; -import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; import java.net.http.HttpResponse; import java.util.List; import java.util.stream.Stream; @@ -150,7 +150,7 @@ default HttpCall> withHandler(HttpResponse.BodyHandler bo /** * Same as {@link #as(Class)} but takes a generic parameterized type. */ - HttpCall> as(ParameterizedType type); + HttpCall> as(Type type); /** * Same as {@link #as(Class)} but returns {@code HttpResponse>}. @@ -160,7 +160,7 @@ default HttpCall> withHandler(HttpResponse.BodyHandler bo /** * Same as {@link #as(Class)} but returns {@code HttpResponse>}. */ - HttpCall>> asList(ParameterizedType type); + HttpCall>> asList(Type type); /** * Same as {@link #as(Class)} but returns {@code HttpResponse>}. @@ -170,7 +170,7 @@ default HttpCall> withHandler(HttpResponse.BodyHandler bo /** * Same as {@link #as(Class)} but returns {@code HttpResponse>}. */ - HttpCall>> asStream(ParameterizedType type); + HttpCall>> asStream(Type type); /** * A bean response to execute async or sync. @@ -239,7 +239,7 @@ default HttpCall> withHandler(HttpResponse.BodyHandler bo * @param type The parameterized type to convert the content to * @return The HttpCall to allow sync or async execution */ - HttpCall bean(ParameterizedType type); + HttpCall bean(Type type); /** * Process expecting a list of beans response body (typically from json content). @@ -247,7 +247,7 @@ default HttpCall> withHandler(HttpResponse.BodyHandler bo * @param type The parameterized type to convert the content to * @return The HttpCall to execute sync or async */ - HttpCall> list(ParameterizedType type); + HttpCall> list(Type type); /** * Process expecting a stream of beans response body (typically from json content). @@ -255,6 +255,6 @@ default HttpCall> withHandler(HttpResponse.BodyHandler bo * @param type The parameterized type to convert the content to * @return The HttpCall to execute sync or async */ - HttpCall> stream(ParameterizedType type); + HttpCall> stream(Type type); } diff --git a/http-client/src/main/java/io/avaje/http/client/HttpClientRequest.java b/http-client/src/main/java/io/avaje/http/client/HttpClientRequest.java index fd31804d5..44c2ac230 100644 --- a/http-client/src/main/java/io/avaje/http/client/HttpClientRequest.java +++ b/http-client/src/main/java/io/avaje/http/client/HttpClientRequest.java @@ -321,7 +321,7 @@ default HttpClientRequest queryParam(String name, Collection values) { * a type that is known to JsonbAdapter / the body content adapter used. * * @param bean The body content as an instance - * @param type The parameterized type used by the body content adapter to write the body content + * @param type The type used by the body content adapter to write the body content * @return The request being built */ HttpClientRequest body(Object bean, Type type); diff --git a/http-client/src/main/java/io/avaje/http/client/HttpClientResponse.java b/http-client/src/main/java/io/avaje/http/client/HttpClientResponse.java index 39523aea7..299e0bb98 100644 --- a/http-client/src/main/java/io/avaje/http/client/HttpClientResponse.java +++ b/http-client/src/main/java/io/avaje/http/client/HttpClientResponse.java @@ -74,12 +74,12 @@ public interface HttpClientResponse { HttpResponse as(Class type); /** - * Return the response with the body containing a single instance of the given parameterized type. + * Return the response with the body containing a single instance of the given type. *

* If the HTTP statusCode is not in the 2XX range a HttpException is throw which contains * the HttpResponse. This is the cause in the CompletionException when using an async request. * - * @param type The parameterized type of the bean to convert the response content into. + * @param type The type of the bean to convert the response content into. * @return The response containing the converted body. * @throws HttpException when the response has error status codes */ @@ -99,7 +99,7 @@ public interface HttpClientResponse { HttpResponse> asList(Class type); /** - * Return the response with the body containing a list of the given parameterized type. + * Return the response with the body containing a list of the given type. *

* If the HTTP statusCode is not in the 2XX range a HttpException is throw which contains * the HttpResponse. This is the cause in the CompletionException when using an async request. @@ -133,7 +133,7 @@ public interface HttpClientResponse { HttpResponse> asStream(Class type); /** - * Return the response with the body containing a stream of beans of the given parameterized type. + * Return the response with the body containing a stream of beans of the given type. *

* Typically the response is expected to be {@literal application/x-json-stream} * newline delimited json payload. @@ -206,7 +206,7 @@ public interface HttpClientResponse { * If the HTTP statusCode is not in the 2XX range a HttpException is throw which contains * the HttpResponse. This is the cause in the CompletionException when using an async request. * - * @param type The parameterized type of the bean to convert the response content into. + * @param type The type of the bean to convert the response content into. * @return The bean the response is converted into. * @throws HttpException when the response has error status codes */ @@ -218,7 +218,7 @@ public interface HttpClientResponse { * If the HTTP statusCode is not in the 2XX range a HttpException is throw which contains * the HttpResponse. This is the cause in the CompletionException when using an async request. * - * @param type The parameterized type of the bean to convert the response content into. + * @param type The type of the bean to convert the response content into. * @return The list of beans the response is converted into. * @throws HttpException when the response has error status codes */ @@ -238,7 +238,7 @@ public interface HttpClientResponse { * If the HTTP statusCode is not in the 2XX range a HttpException is throw which contains * the HttpResponse. This is the cause in the CompletionException when using an async request. * - * @param type The parameterized type of the bean to convert the response content into. + * @param type The type of the bean to convert the response content into. * @return The stream of beans from the response * @throws HttpException when the response has error status codes */ From 3eea70bcba91d4eb16323b4021ce2ea0a5936b90 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Mon, 3 Apr 2023 17:31:36 -0400 Subject: [PATCH 0714/1323] Add io.avaje.http.api @Valid Annotation to support custom validators (#195) * valid * ignore BeanField * Revert "ignore BeanField" This reverts commit bd70d8a23fbe9f54bbfb56572d5806c06f4fdcd2. * Update MethodReader.java * Update README.md * Update README.md --- README.md | 20 ++++++++-------- .../main/java/io/avaje/http/api/Valid.java | 23 +++++++++++++++++++ .../http/generator/core/ControllerReader.java | 1 + .../http/generator/core/ElementReader.java | 4 +++- .../http/generator/core/MethodReader.java | 1 + .../http/generator/core/package-info.java | 5 ++-- .../example/myapp/web/HelloController.java | 3 +-- 7 files changed, 42 insertions(+), 15 deletions(-) create mode 100644 http-api/src/main/java/io/avaje/http/api/Valid.java diff --git a/README.md b/README.md index d859b557f..0e2486c0f 100644 --- a/README.md +++ b/README.md @@ -80,16 +80,16 @@ The annotation processor will generate controller adapters that can register rou There isn't a hard requirement to use Avaje for dependency injection. In the absence of avaje-inject the generated class will use `@jakarta.inject.Singleton` or `@javax.inject.Singleton` depending on what's on the classpath. Any DI library that can find and wire the generated @Singleton beans can be used. You can even use Dagger2 or Guice to wire the controllers if you so desire. To force the AP to generate with `@javax.inject.Singleton`(in the case where you have both jakarta and javax on the classpath), use the compiler arg `-AuseJavax=true` -``` - - org.apache.maven.plugins - maven-compiler-plugin - - - -AuseJavax=true - - - +```xml + + org.apache.maven.plugins + maven-compiler-plugin + + + -AuseJavax=true + + + ``` ### Usage with Javalin diff --git a/http-api/src/main/java/io/avaje/http/api/Valid.java b/http-api/src/main/java/io/avaje/http/api/Valid.java new file mode 100644 index 000000000..1f0e266ab --- /dev/null +++ b/http-api/src/main/java/io/avaje/http/api/Valid.java @@ -0,0 +1,23 @@ +package io.avaje.http.api; + +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.PARAMETER; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.SOURCE; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +/** + * + * Add @Valid annotation on a controller/method/BeanParam that we want bean validation to be included for. + * When we do this controller methods that take a request payload will then have the request bean + * (populated by JSON payload or form parameters) validated before it is passed to the controller + * method. + * + * When trying to validate a @BeanParam bean, this will need to be placed on the BeanParam type + + */ +@Retention(SOURCE) +@Target({METHOD, TYPE, PARAMETER}) +public @interface Valid {} diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java index 99be109ec..415ec17a7 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java @@ -162,6 +162,7 @@ private boolean initDocHidden() { private boolean initHasValid() { return findAnnotation(JavaxValidPrism::getOptionalOn).isPresent() + || findAnnotation(JakartaValidPrism::getOptionalOn).isPresent() || findAnnotation(ValidPrism::getOptionalOn).isPresent(); } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java index a4f1d9329..4e1706c0e 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java @@ -129,7 +129,9 @@ private boolean useValidation() { } final var elementType = typeElement(rawType); return elementType != null - && (ValidPrism.isPresent(elementType) || JavaxValidPrism.isPresent(elementType)); + && (ValidPrism.isPresent(elementType) + || JavaxValidPrism.isPresent(elementType) + || JakartaValidPrism.isPresent(elementType)); } private void readAnnotations(Element element, ParamType defaultType) { diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java index d48feb797..66d438dbc 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java @@ -92,6 +92,7 @@ private Javadoc buildJavadoc(ExecutableElement element) { private boolean initValid() { return findAnnotation(ValidPrism::getOptionalOn).isPresent() || findAnnotation(JavaxValidPrism::getOptionalOn).isPresent() + || findAnnotation(JakartaValidPrism::getOptionalOn).isPresent() || superMethodHasValid(); } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/package-info.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/package-info.java index 0c8822c3d..1888eb33f 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/package-info.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/package-info.java @@ -26,12 +26,13 @@ @GeneratePrism(value = io.avaje.http.api.OpenAPIResponse.class, publicAccess = true) @GeneratePrism(value = io.avaje.http.api.OpenAPIResponses.class, publicAccess = true) @GeneratePrism(value = io.swagger.v3.oas.annotations.Hidden.class, publicAccess = true) -@GeneratePrism(value = javax.validation.Valid.class, name = "JavaxValidPrism", publicAccess = true) -@GeneratePrism(value = jakarta.validation.Valid.class, publicAccess = true) @GeneratePrism(value = org.jetbrains.annotations.NotNull.class, publicAccess = true) @GeneratePrism(value = io.avaje.http.api.Client.class, publicAccess = true) @GeneratePrism(value = io.avaje.http.api.Client.Import.class, publicAccess = true) @GeneratePrism(value = io.avaje.http.api.RequestTimeout.class, publicAccess = true) +@GeneratePrism(value = javax.validation.Valid.class, name = "JavaxValidPrism") +@GeneratePrism(value = jakarta.validation.Valid.class, name = "JakartaValidPrism") +@GeneratePrism(value = io.avaje.http.api.Valid.class) package io.avaje.http.generator.core; import io.avaje.prism.GeneratePrism; diff --git a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/HelloController.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/HelloController.java index e5e5915d2..e2d4d7de2 100644 --- a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/HelloController.java +++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/HelloController.java @@ -8,8 +8,6 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.Executors; -import javax.validation.Valid; - import org.example.myapp.service.MyService; import io.avaje.http.api.BeanParam; @@ -23,6 +21,7 @@ import io.avaje.http.api.Post; import io.avaje.http.api.Produces; import io.avaje.http.api.QueryParam; +import io.avaje.http.api.Valid; import io.javalin.http.Context; import io.swagger.v3.oas.annotations.Hidden; import jakarta.inject.Inject; From d712402dd1c7a6adf6331cbf0f2c5fa057b8b6ad Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 4 Apr 2023 09:37:05 +1200 Subject: [PATCH 0715/1323] Javadoc on api Valid annotation --- .../main/java/io/avaje/http/api/Valid.java | 21 +++++++++++-------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/http-api/src/main/java/io/avaje/http/api/Valid.java b/http-api/src/main/java/io/avaje/http/api/Valid.java index 1f0e266ab..bc3fbe772 100644 --- a/http-api/src/main/java/io/avaje/http/api/Valid.java +++ b/http-api/src/main/java/io/avaje/http/api/Valid.java @@ -9,15 +9,18 @@ import java.lang.annotation.Target; /** - * - * Add @Valid annotation on a controller/method/BeanParam that we want bean validation to be included for. - * When we do this controller methods that take a request payload will then have the request bean - * (populated by JSON payload or form parameters) validated before it is passed to the controller - * method. - * - * When trying to validate a @BeanParam bean, this will need to be placed on the BeanParam type - + * Add {@code @Valid} annotation on a controller/method/BeanParam that we want bean validation to + * be included for. When we do this controller methods that take a request payload will then have + * the request bean (populated by JSON payload or form parameters) validated before it is passed + * to the controller method. + *

+ * When trying to validate a {@code @BeanParam} bean, this will need to be placed on the BeanParam type. + *

+ * When using this annotation we need to provide an implementation of {@link Validator} to use. + *

+ * Alternatively we can use the Jakarta {@code @Valid} along with a Jakarta validator implementation. */ @Retention(SOURCE) @Target({METHOD, TYPE, PARAMETER}) -public @interface Valid {} +public @interface Valid { +} From cd6fe76d305bac3bc4b2813468498f6386d70061 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Mon, 3 Apr 2023 17:43:46 -0400 Subject: [PATCH 0716/1323] Add @Ignore for ignoring a BeanParam field (or query param field) (#197) * Ignore BeanFields * rename annotation --- http-api/src/main/java/io/avaje/http/api/Ignore.java | 12 ++++++++++++ .../avaje/http/generator/core/BeanParamReader.java | 4 ++++ .../io/avaje/http/generator/core/package-info.java | 1 + .../main/java/org/example/myapp/web/GetBeanForm.java | 7 +++++++ 4 files changed, 24 insertions(+) create mode 100644 http-api/src/main/java/io/avaje/http/api/Ignore.java diff --git a/http-api/src/main/java/io/avaje/http/api/Ignore.java b/http-api/src/main/java/io/avaje/http/api/Ignore.java new file mode 100644 index 000000000..f79d46256 --- /dev/null +++ b/http-api/src/main/java/io/avaje/http/api/Ignore.java @@ -0,0 +1,12 @@ +package io.avaje.http.api; + +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.RetentionPolicy.SOURCE; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +/** Mark a field on a BeanParam/FormParam class as not a request parameter of any kind */ +@Target(FIELD) +@Retention(SOURCE) +public @interface Ignore {} diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/BeanParamReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/BeanParamReader.java index dfd6b56a9..65f28e885 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/BeanParamReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/BeanParamReader.java @@ -40,6 +40,10 @@ private void read() { } private void readField(Element enclosedElement) { + + if (IgnorePrism.isPresent(enclosedElement)) { + return; + } FieldReader field = new FieldReader(enclosedElement, defaultParamType); fieldMap.put(field.varName(), field); } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/package-info.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/package-info.java index 1888eb33f..727efae68 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/package-info.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/package-info.java @@ -1,6 +1,7 @@ /** Generate the prisms to access annotation info */ @GeneratePrism(value = io.avaje.http.api.Controller.class, publicAccess = true) @GeneratePrism(value = io.avaje.http.api.BeanParam.class, publicAccess = true) +@GeneratePrism(value = io.avaje.http.api.Ignore.class, publicAccess = true) @GeneratePrism(value = io.avaje.http.api.QueryParam.class, publicAccess = true) @GeneratePrism(value = io.avaje.http.api.Client.class, publicAccess = true) @GeneratePrism(value = io.avaje.http.api.Cookie.class, publicAccess = true) diff --git a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/GetBeanForm.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/GetBeanForm.java index 573048b2a..dd54b25e8 100644 --- a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/GetBeanForm.java +++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/GetBeanForm.java @@ -9,6 +9,7 @@ import javax.validation.constraints.Size; import io.avaje.http.api.Header; +import io.avaje.http.api.Ignore; import io.avaje.http.api.QueryParam; import io.avaje.jsonb.Json; @@ -30,6 +31,12 @@ public class GetBeanForm { @QueryParam private Set type; + @Json.Ignore @Ignore private String ignored; + + public String getIgnored() { + return ignored; + } + public String getName() { return name; } From 831f644e33b734feb6edaf28db968d2cebe986d2 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Tue, 4 Apr 2023 00:42:35 -0400 Subject: [PATCH 0717/1323] [http-client] Fix Non-Json bodytypes/Add InputStream body method (#200) * input stream body * fix non json generation --- .../avaje/http/client/DHttpClientRequest.java | 6 ++++ .../avaje/http/client/HttpClientRequest.java | 8 +++++ .../generator/client/ClientMethodWriter.java | 31 ++++++++++++++++--- .../io/avaje/http/generator/core/UType.java | 5 +-- 4 files changed, 44 insertions(+), 6 deletions(-) diff --git a/http-client/src/main/java/io/avaje/http/client/DHttpClientRequest.java b/http-client/src/main/java/io/avaje/http/client/DHttpClientRequest.java index 19d4414f5..74fe3ef14 100644 --- a/http-client/src/main/java/io/avaje/http/client/DHttpClientRequest.java +++ b/http-client/src/main/java/io/avaje/http/client/DHttpClientRequest.java @@ -312,6 +312,12 @@ public HttpClientRequest body(Supplier streamSupplier) { return this; } + @Override + public HttpClientRequest body(InputStream stream) { + this.body = HttpRequest.BodyPublishers.ofInputStream(() -> stream); + return this; + } + @Override public HttpClientRequest body(Path file) { try { diff --git a/http-client/src/main/java/io/avaje/http/client/HttpClientRequest.java b/http-client/src/main/java/io/avaje/http/client/HttpClientRequest.java index 44c2ac230..36dca062f 100644 --- a/http-client/src/main/java/io/avaje/http/client/HttpClientRequest.java +++ b/http-client/src/main/java/io/avaje/http/client/HttpClientRequest.java @@ -364,6 +364,14 @@ default HttpClientRequest queryParam(String name, Collection values) { */ HttpClientRequest body(Supplier supplier); + /** + * Set the body content with supplied InputStream. + * + * @param supplier The InputStream content to send as body content + * @return The request being built + */ + HttpClientRequest body(InputStream stream); + /** * Set the body content with supplied InputStream. * diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java index 475efd08d..541f9d16d 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java @@ -55,7 +55,11 @@ private void methodStart(Append writer) { if (count++ > 0) { writer.append(", "); } - writer.append(param.utype().shortType()).append(" "); + var paramType = + "java.util.function.Supplier".equals(param.utype().full()) + ? "Supplier" + : param.utype().shortType(); + writer.append(paramType).append(" "); writer.append(param.name()); } writer.append(") {").eol(); @@ -250,10 +254,29 @@ private void writeFormParam(MethodParam param, ParamType paramType) { private void writeBody() { for (MethodParam param : method.params()) { ParamType paramType = param.paramType(); + if (paramType == ParamType.BODY) { - writer.append(" .body(%s, ", param.name()); - writeGeneric(param.utype()); - writer.append(")").eol(); + + var type = param.utype().full(); + if ("java.net.http.HttpRequest.BodyPublisher".equals(type) + || "java.lang.String".equals(type) + || "byte[]".equals(type) + || "java.io.InputStream".equals(type) + || "java.util.function.Supplier".equals(type) + || "java.util.function.Supplier".equals(type) + || "java.nio.file.Path".equals(type) + || "io.avaje.http.client.BodyContent".equals(type)) { + + writer.append(" .body(%s)", param.name()).eol(); + + } else { + + writer.append(" .body(%s, ", param.name()); + writeGeneric(param.utype()); + writer.append(")").eol(); + } + + return; } } } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java index 43b9c4bf1..dd8a5e93f 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java @@ -203,12 +203,13 @@ public Set importTypes() { for (String type : allTypes) { if (!type.startsWith("java.lang.") && type.indexOf('.') > -1) { if (type.startsWith("java")) { - set.add(type.replace("[]", "")); + set.add(type.replace("[]", "").replace("?extends", "")); } else { - set.add(innerTypesImport(type).replace("[]", "")); + set.add(innerTypesImport(type).replace("[]", "").replace("?extends", "")); } } } + set.remove("?"); return set; } From f03f28c76cc0cf060eb29847526bad2825d2f867 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 4 Apr 2023 16:43:41 +1200 Subject: [PATCH 0718/1323] Format only change on Ignore --- http-api/src/main/java/io/avaje/http/api/Ignore.java | 7 +++++-- .../java/io/avaje/http/generator/core/BeanParamReader.java | 1 - 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/http-api/src/main/java/io/avaje/http/api/Ignore.java b/http-api/src/main/java/io/avaje/http/api/Ignore.java index f79d46256..687891841 100644 --- a/http-api/src/main/java/io/avaje/http/api/Ignore.java +++ b/http-api/src/main/java/io/avaje/http/api/Ignore.java @@ -6,7 +6,10 @@ import java.lang.annotation.Retention; import java.lang.annotation.Target; -/** Mark a field on a BeanParam/FormParam class as not a request parameter of any kind */ +/** + * Mark a field on a BeanParam/FormParam class as not a request parameter of any kind. + */ @Target(FIELD) @Retention(SOURCE) -public @interface Ignore {} +public @interface Ignore { +} diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/BeanParamReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/BeanParamReader.java index 65f28e885..17a1d309e 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/BeanParamReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/BeanParamReader.java @@ -40,7 +40,6 @@ private void read() { } private void readField(Element enclosedElement) { - if (IgnorePrism.isPresent(enclosedElement)) { return; } From c95f71c9e018d87ef312bfb003c1b0e454134f88 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 4 Apr 2023 16:48:25 +1200 Subject: [PATCH 0719/1323] Tidy HttpClientRequest javadoc, refactor internal method in ClientMethodWriter --- .../avaje/http/client/HttpClientRequest.java | 2 +- .../generator/client/ClientMethodWriter.java | 32 +++++++++---------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/http-client/src/main/java/io/avaje/http/client/HttpClientRequest.java b/http-client/src/main/java/io/avaje/http/client/HttpClientRequest.java index 36dca062f..6376cf75e 100644 --- a/http-client/src/main/java/io/avaje/http/client/HttpClientRequest.java +++ b/http-client/src/main/java/io/avaje/http/client/HttpClientRequest.java @@ -367,7 +367,7 @@ default HttpClientRequest queryParam(String name, Collection values) { /** * Set the body content with supplied InputStream. * - * @param supplier The InputStream content to send as body content + * @param stream The InputStream content to send as body content * @return The request being built */ HttpClientRequest body(InputStream stream); diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java index 541f9d16d..01963feed 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java @@ -253,34 +253,34 @@ private void writeFormParam(MethodParam param, ParamType paramType) { private void writeBody() { for (MethodParam param : method.params()) { - ParamType paramType = param.paramType(); - - if (paramType == ParamType.BODY) { - + if (param.paramType() == ParamType.BODY) { var type = param.utype().full(); - if ("java.net.http.HttpRequest.BodyPublisher".equals(type) - || "java.lang.String".equals(type) - || "byte[]".equals(type) - || "java.io.InputStream".equals(type) - || "java.util.function.Supplier".equals(type) - || "java.util.function.Supplier".equals(type) - || "java.nio.file.Path".equals(type) - || "io.avaje.http.client.BodyContent".equals(type)) { - + if (directBodyType(type)) { writer.append(" .body(%s)", param.name()).eol(); - } else { - writer.append(" .body(%s, ", param.name()); writeGeneric(param.utype()); writer.append(")").eol(); } - return; } } } + /** + * Return true for body types that are directly supported. + */ + private static boolean directBodyType(String type) { + return "java.net.http.HttpRequest.BodyPublisher".equals(type) + || "java.lang.String".equals(type) + || "byte[]".equals(type) + || "java.io.InputStream".equals(type) + || "java.util.function.Supplier".equals(type) + || "java.util.function.Supplier".equals(type) + || "java.nio.file.Path".equals(type) + || "io.avaje.http.client.BodyContent".equals(type); + } + private void writePaths(Set segments) { if (!segments.isEmpty()) { writer.append(" "); From 3899cfbff13573296ba3ffe713f7501b73a0284f Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 4 Apr 2023 18:43:18 +1200 Subject: [PATCH 0720/1323] @Ignore should not be included in openapi generation (#201) --- .../http/generator/core/ElementReader.java | 17 +++++++++++++---- .../core/openapi/OpenAPISerializer.java | 6 +++--- .../core/openapi/SchemaDocBuilder.java | 1 - 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java index 4e1706c0e..61607b352 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java @@ -9,9 +9,7 @@ import java.util.Optional; import java.util.Set; -import javax.lang.model.element.Element; -import javax.lang.model.element.ElementKind; -import javax.lang.model.element.TypeElement; +import javax.lang.model.element.*; import io.avaje.http.generator.core.openapi.MethodDocBuilder; import io.avaje.http.generator.core.openapi.MethodParamDocBuilder; @@ -252,8 +250,19 @@ void writeParamName(Append writer) { */ void buildApiDocumentation(MethodDocBuilder methodDoc) { if (!isPlatformContext() && !isParamMap && paramType != ParamType.BEANPARAM) { - new MethodParamDocBuilder(methodDoc, this).build(); + if (includeParam()) { + new MethodParamDocBuilder(methodDoc, this).build(); + } + } + } + + private boolean includeParam() { + for (AnnotationMirror annotationMirror : element.getAnnotationMirrors()) { + if ("io.avaje.http.api.Ignore".equals(annotationMirror.getAnnotationType().toString())) { + return false; + } } + return true; } void writeValidate(Append writer) { diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/OpenAPISerializer.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/OpenAPISerializer.java index c26961899..942a05d41 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/OpenAPISerializer.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/OpenAPISerializer.java @@ -165,10 +165,10 @@ static Object extractPrimitiveValue(Object object) { * @throws IllegalAccessException if the fields of the value object cannot be accessed */ static void write(StringBuilder sb, Object value) throws IllegalAccessException { - final var isprimitiveWrapper = isPrimitiveWrapperType(value); + final var isPrimitiveWrapper = isPrimitiveWrapperType(value); // Append primitive or string value as is - if (value.getClass().isPrimitive() || value instanceof String || isprimitiveWrapper) { - if (isprimitiveWrapper) { + if (value.getClass().isPrimitive() || value instanceof String || isPrimitiveWrapper) { + if (isPrimitiveWrapper) { sb.append(extractPrimitiveValue(value)); } else { sb.append("\""); diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/SchemaDocBuilder.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/SchemaDocBuilder.java index d5e2a5134..db0b5ac56 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/SchemaDocBuilder.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/SchemaDocBuilder.java @@ -25,7 +25,6 @@ import javax.lang.model.util.Types; import io.avaje.http.generator.core.HiddenPrism; -import io.avaje.http.generator.core.UType; import io.avaje.http.generator.core.Util; import io.avaje.prism.GeneratePrism; import io.swagger.v3.oas.models.Operation; From f3fd134c348b9e33e22379102673345de24f4e7e Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Tue, 4 Apr 2023 20:09:38 -0400 Subject: [PATCH 0721/1323] Add BodyString annotation, to support controllers with body of type String (#198) * Body String * professionals have standards * fix bodyPublisher * rename to body * import * Update Body.java * Revert "rename to body" * fix other body types * input stream body * Update BodyString.java * Update ElementReader.java * now will use application/text fo string --- .../java/io/avaje/http/api/BodyString.java | 15 +++++++++ .../http/generator/core/ElementReader.java | 33 ++++++++----------- .../core/openapi/SchemaDocBuilder.java | 4 +++ .../http/generator/core/package-info.java | 1 + .../generator/javalin/JavalinAdapter.java | 14 +++++--- .../avaje/http/generator/jex/JexAdapter.java | 3 ++ .../main/java/org/example/TestController.java | 6 ++++ .../myapp/web/test/TestController2.java | 6 ++++ .../java/org/example/web/TestController.java | 6 ++++ .../main/java/org/example/TestController.java | 6 ++++ 10 files changed, 71 insertions(+), 23 deletions(-) create mode 100644 http-api/src/main/java/io/avaje/http/api/BodyString.java diff --git a/http-api/src/main/java/io/avaje/http/api/BodyString.java b/http-api/src/main/java/io/avaje/http/api/BodyString.java new file mode 100644 index 000000000..cf12b6339 --- /dev/null +++ b/http-api/src/main/java/io/avaje/http/api/BodyString.java @@ -0,0 +1,15 @@ +package io.avaje.http.api; + +import static java.lang.annotation.ElementType.PARAMETER; +import static java.lang.annotation.RetentionPolicy.SOURCE; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +/** + * Marks a controller string method parameter to be a string body. Use when you expect to receive an + * application/text or similar body request. + */ +@Retention(SOURCE) +@Target(PARAMETER) +public @interface BodyString {} diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java index 61607b352..577cf3d72 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java @@ -38,7 +38,6 @@ public class ElementReader { private boolean isParamCollection; private boolean isParamMap; private final Set imports = new HashSet<>(); - // private boolean notNullJavax; ElementReader(Element element, ParamType defaultType, boolean formMarker) { this(element, null, Util.typeDef(element.asType()), defaultType, formMarker); @@ -140,13 +139,11 @@ private void readAnnotations(Element element, ParamType defaultType) { if (defaultVal != null) { this.paramDefault = defaultVal.value(); } - final var form = FormPrism.getInstanceOn(element); - if (form != null) { + if (FormPrism.isPresent(element)) { this.paramType = ParamType.FORM; return; } - final var beanParam = BeanParamPrism.getInstanceOn(element); - if (beanParam != null) { + if (BeanParamPrism.isPresent(element)) { this.paramType = ParamType.BEANPARAM; return; } @@ -185,6 +182,12 @@ private void readAnnotations(Element element, ParamType defaultType) { return; } + if ("java.lang.String".equals(element.asType().toString()) + && BodyStringPrism.isPresent(element)) { + this.paramType = ParamType.BODY; + return; + } + if (paramType == null) { this.impliedParamType = true; if (typeHandler != null) { @@ -249,22 +252,14 @@ void writeParamName(Append writer) { * Build the OpenAPI documentation for this parameter. */ void buildApiDocumentation(MethodDocBuilder methodDoc) { - if (!isPlatformContext() && !isParamMap && paramType != ParamType.BEANPARAM) { - if (includeParam()) { - new MethodParamDocBuilder(methodDoc, this).build(); - } + if (!isPlatformContext() + && !isParamMap + && paramType != ParamType.BEANPARAM + && !IgnorePrism.isPresent(element)) { + new MethodParamDocBuilder(methodDoc, this).build(); } } - private boolean includeParam() { - for (AnnotationMirror annotationMirror : element.getAnnotationMirrors()) { - if ("io.avaje.http.api.Ignore".equals(annotationMirror.getAnnotationType().toString())) { - return false; - } - } - return true; - } - void writeValidate(Append writer) { if (!contextType && typeHandler == null) { if (useValidation) { @@ -338,7 +333,7 @@ private boolean setValue(Append writer, PathSegments segments, String shortType) writer.append(asMethod); } - if (typeHandler == null) { + if (typeHandler == null || paramType == ParamType.BODY) { // this is a body (POST, PATCH) writer.append(platform().bodyAsClass(type)); diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/SchemaDocBuilder.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/SchemaDocBuilder.java index db0b5ac56..7ad274788 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/SchemaDocBuilder.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/SchemaDocBuilder.java @@ -45,6 +45,7 @@ class SchemaDocBuilder { private static final String APP_FORM = "application/x-www-form-urlencoded"; private static final String APP_JSON = "application/json"; + private static final String APP_TXT = "application/text"; private final Elements elements; private final Types types; @@ -113,6 +114,9 @@ void addRequestBody(Operation operation, Schema schema, boolean asForm, String d mt.schema(schema); String mime = asForm ? APP_FORM : APP_JSON; + if (schema instanceof StringSchema) { + mime = APP_TXT; + } body.getContent().addMediaType(mime, mt); } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/package-info.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/package-info.java index 727efae68..bb2c116ea 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/package-info.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/package-info.java @@ -5,6 +5,7 @@ @GeneratePrism(value = io.avaje.http.api.QueryParam.class, publicAccess = true) @GeneratePrism(value = io.avaje.http.api.Client.class, publicAccess = true) @GeneratePrism(value = io.avaje.http.api.Cookie.class, publicAccess = true) +@GeneratePrism(value = io.avaje.http.api.BodyString.class, publicAccess = true) @GeneratePrism(value = io.avaje.http.api.Default.class, publicAccess = true) @GeneratePrism(value = io.avaje.http.api.Delete.class, publicAccess = true) @GeneratePrism(value = io.avaje.http.api.Form.class, publicAccess = true) diff --git a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinAdapter.java b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinAdapter.java index a6eeb3001..a1653155e 100644 --- a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinAdapter.java +++ b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinAdapter.java @@ -1,9 +1,13 @@ package io.avaje.http.generator.javalin; -import io.avaje.http.generator.core.*; - import java.util.List; +import io.avaje.http.generator.core.Append; +import io.avaje.http.generator.core.ControllerReader; +import io.avaje.http.generator.core.ParamType; +import io.avaje.http.generator.core.PlatformAdapter; +import io.avaje.http.generator.core.UType; + class JavalinAdapter implements PlatformAdapter { static final String JAVALIN3_CONTEXT = "io.javalin.http.Context"; @@ -31,9 +35,11 @@ public boolean isBodyMethodParam() { @Override public String bodyAsClass(UType type) { - if (type.full().startsWith("java.io.InputStream")) { + if ("java.io.InputStream".equals(type.full())) { return "ctx.bodyInputStream()"; - } else if (type.full().startsWith("byte[]")) { + } else if ("java.lang.String".equals(type.full())) { + return "ctx.body()"; + } else if ("byte[]".equals(type.full())) { return "ctx.bodyAsBytes()"; } else { if (useJsonB) { diff --git a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/JexAdapter.java b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/JexAdapter.java index 157fd6f0f..f417f306f 100644 --- a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/JexAdapter.java +++ b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/JexAdapter.java @@ -29,6 +29,9 @@ public boolean isBodyMethodParam() { @Override public String bodyAsClass(UType uType) { + if ("java.lang.String".equals(uType.full())) { + return "ctx.body()"; + } return "ctx.bodyAsClass(" + uType.mainType() + ".class)"; } diff --git a/tests/test-helidon/src/main/java/org/example/TestController.java b/tests/test-helidon/src/main/java/org/example/TestController.java index 04ba98201..16ab956b2 100644 --- a/tests/test-helidon/src/main/java/org/example/TestController.java +++ b/tests/test-helidon/src/main/java/org/example/TestController.java @@ -4,6 +4,7 @@ import java.util.Map; import java.util.Set; +import io.avaje.http.api.BodyString; import io.avaje.http.api.Controller; import io.avaje.http.api.Cookie; import io.avaje.http.api.Default; @@ -40,4 +41,9 @@ String enumQueryImplied(String s, @QueryParam ServerType type) { String mapTest(Map> strings, @Cookie Map> cookie) { return strings.toString(); } + + @Post("/strBody") + String strBody(@BodyString String body) { + return body; + } } diff --git a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController2.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController2.java index 33aa67993..b7b3392ce 100644 --- a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController2.java +++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController2.java @@ -6,6 +6,7 @@ import org.example.myapp.web.ServerType; +import io.avaje.http.api.BodyString; import io.avaje.http.api.Controller; import io.avaje.http.api.Default; import io.avaje.http.api.Form; @@ -54,4 +55,9 @@ String stream(InputStream stream) { String bytes(byte[] array) { return array.toString(); } + + @Post("/strBody") + String strBody(@BodyString String body) { + return body; + } } diff --git a/tests/test-jex/src/main/java/org/example/web/TestController.java b/tests/test-jex/src/main/java/org/example/web/TestController.java index 69fe686e7..9d995faad 100644 --- a/tests/test-jex/src/main/java/org/example/web/TestController.java +++ b/tests/test-jex/src/main/java/org/example/web/TestController.java @@ -2,12 +2,14 @@ import java.util.Set; +import io.avaje.http.api.BodyString; import io.avaje.http.api.Controller; import io.avaje.http.api.Default; import io.avaje.http.api.Get; import io.avaje.http.api.Path; import io.avaje.http.api.Post; import io.avaje.http.api.QueryParam; +import io.avaje.jex.Context; @Path("test/") @Controller @@ -33,4 +35,8 @@ String enumQueryImplied(String s, @QueryParam ServerType type) { return type.name(); } + @Post("/strBody") + String strBody(@BodyString String body, Context ctx) { + return body; + } } diff --git a/tests/test-nima-jsonb/src/main/java/org/example/TestController.java b/tests/test-nima-jsonb/src/main/java/org/example/TestController.java index 03a7ea2ab..2d26227cb 100644 --- a/tests/test-nima-jsonb/src/main/java/org/example/TestController.java +++ b/tests/test-nima-jsonb/src/main/java/org/example/TestController.java @@ -4,6 +4,7 @@ import java.util.List; import java.util.Set; +import io.avaje.http.api.BodyString; import io.avaje.http.api.Controller; import io.avaje.http.api.Default; import io.avaje.http.api.Form; @@ -57,4 +58,9 @@ String enumQueryImplied(String s, @QueryParam ServerType type) { String stream(InputStream stream) { return stream.toString(); } + + @Post("/strBody") + String strBody(@BodyString String body) { + return body; + } } From 0797eff6736ea9889223a3206c7c325a6aa3a295 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Tue, 4 Apr 2023 20:20:22 -0400 Subject: [PATCH 0722/1323] Add @Consumes annotation (#202) * Body String * professionals have standards * fix bodyPublisher * rename to body * import * Update Body.java * Revert "rename to body" * fix other body types * input stream body * Update BodyString.java * Update ElementReader.java * now will use application/text fo string * work * byte array openAPI * Update SchemaDocBuilder.java --- .../main/java/io/avaje/http/api/Consumes.java | 35 +++++++++++++++++++ .../main/java/io/avaje/http/api/Produces.java | 8 ++--- .../http/generator/core/MethodReader.java | 25 ++++++++++--- .../generator/core/openapi/DocContext.java | 4 +-- .../generator/core/openapi/KnownTypes.java | 8 +++++ .../core/openapi/MethodDocBuilder.java | 9 +++++ .../core/openapi/MethodParamDocBuilder.java | 32 +++++++++++++---- .../core/openapi/SchemaDocBuilder.java | 13 ++----- .../http/generator/core/package-info.java | 1 + .../myapp/web/test/TestController2.java | 2 ++ 10 files changed, 111 insertions(+), 26 deletions(-) create mode 100644 http-api/src/main/java/io/avaje/http/api/Consumes.java diff --git a/http-api/src/main/java/io/avaje/http/api/Consumes.java b/http-api/src/main/java/io/avaje/http/api/Consumes.java new file mode 100644 index 000000000..c3a511284 --- /dev/null +++ b/http-api/src/main/java/io/avaje/http/api/Consumes.java @@ -0,0 +1,35 @@ +package io.avaje.http.api; + +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +/** + * Specify endpoint request media type for the generated OpenAPI json. + * + *

When not specified the default MediaType is application/json, so we specify this on + * controllers or methods where the responses return a different media type. + * + *

{@code
+ * @Path("/customers")
+ * @Consumes(MediaType.TEXT_PLAIN)
+ * class CustomerController {
+ *   ...
+ * }
+ *
+ * }
+ */ +@Target({TYPE, METHOD}) +@Retention(RUNTIME) +public @interface Consumes { + + /** + * Specify request media type. + * + *

When not specified the default MediaType is application/json + */ + String value() default MediaType.APPLICATION_JSON; +} diff --git a/http-api/src/main/java/io/avaje/http/api/Produces.java b/http-api/src/main/java/io/avaje/http/api/Produces.java index de0aa3bcf..6af67d961 100644 --- a/http-api/src/main/java/io/avaje/http/api/Produces.java +++ b/http-api/src/main/java/io/avaje/http/api/Produces.java @@ -10,7 +10,7 @@ /** * Specify endpoint response media type. * - * When not specified the default MediaType is APPLICATION_JSON + * When not specified the default MediaType is application/json, * so we specify this on controllers or methods where the responses * return a different media type. * @@ -24,14 +24,14 @@ * * }

*/ -@Target(value = {TYPE, METHOD}) -@Retention(value = RUNTIME) +@Target({TYPE, METHOD}) +@Retention(RUNTIME) public @interface Produces { /** * Specify response media type. * - *

When not specified the default MediaType is APPLICATION_JSON + *

When not specified the default MediaType is application/json */ String value() default MediaType.APPLICATION_JSON; diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java index 66d438dbc..6812f3521 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java @@ -1,8 +1,10 @@ package io.avaje.http.generator.core; -import static io.avaje.http.generator.core.ProcessingContext.*; -import io.avaje.http.generator.core.javadoc.Javadoc; -import io.avaje.http.generator.core.openapi.MethodDocBuilder; +import static io.avaje.http.generator.core.ProcessingContext.doc; +import static io.avaje.http.generator.core.ProcessingContext.docComment; +import static io.avaje.http.generator.core.ProcessingContext.platform; +import static io.avaje.http.generator.core.ProcessingContext.superMethods; + import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -12,6 +14,7 @@ import java.util.function.Predicate; import java.util.stream.Collectors; import java.util.stream.Stream; + import javax.lang.model.element.AnnotationMirror; import javax.lang.model.element.Element; import javax.lang.model.element.ExecutableElement; @@ -20,6 +23,9 @@ import javax.lang.model.type.TypeKind; import javax.lang.model.type.TypeMirror; +import io.avaje.http.generator.core.javadoc.Javadoc; +import io.avaje.http.generator.core.openapi.MethodDocBuilder; + public class MethodReader { private final ControllerReader bean; @@ -32,6 +38,7 @@ public class MethodReader { */ private final List methodRoles; private final Optional producesAnnotation; + private final Optional consumesAnnotation; private final List securityRequirements; private final List apiResponses; private final ExecutableType actualExecutable; @@ -52,7 +59,13 @@ public class MethodReader { this.actualParams = (actualExecutable == null) ? null : actualExecutable.getParameterTypes(); this.isVoid = element.getReturnType().getKind() == TypeKind.VOID; this.methodRoles = Util.findRoles(element); - this.producesAnnotation = findAnnotation(ProducesPrism::getOptionalOn); + this.producesAnnotation = + findAnnotation(ProducesPrism::getOptionalOn) + .or(() -> ProducesPrism.getOptionalOn(bean.beanType())); + this.consumesAnnotation = + findAnnotation(ConsumesPrism::getOptionalOn) + .or(() -> ConsumesPrism.getOptionalOn(bean.beanType())); + initWebMethodViaAnnotation(); this.superMethods = @@ -303,6 +316,10 @@ public String produces() { return producesAnnotation.map(ProducesPrism::value).orElseGet(bean::produces); } + public Optional consumesAnnotation() { + return consumesAnnotation; + } + public List securityRequirements() { return securityRequirements; } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/DocContext.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/DocContext.java index 8be2fee4a..590e03c0c 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/DocContext.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/DocContext.java @@ -102,8 +102,8 @@ void addFormParam(Operation operation, String varName, Schema schema) { schemaBuilder.addFormParam(operation, varName, schema); } - void addRequestBody(Operation operation, Schema schema, boolean asForm, String description) { - schemaBuilder.addRequestBody(operation, schema, asForm, description); + void addRequestBody(Operation operation, Schema schema, String mediaType, String description) { + schemaBuilder.addRequestBody(operation, schema, mediaType, description); } /** diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/KnownTypes.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/KnownTypes.java index 2a0e549c3..41be90d40 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/KnownTypes.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/KnownTypes.java @@ -1,6 +1,7 @@ package io.avaje.http.generator.core.openapi; import java.io.File; +import java.io.InputStream; import java.math.BigDecimal; import java.math.BigInteger; import java.net.URI; @@ -46,6 +47,7 @@ interface KnownType { add(new IntegerType(), Integer.class); add(new PLongType(), long.class); add(new LongType(), Long.class); + add(new BytesType(), byte[].class, InputStream.class); add(new PNumberType(), double.class, float.class); add(new NumberType(), Double.class, Float.class, BigDecimal.class, BigInteger.class); @@ -174,6 +176,12 @@ private URIType() { } } + private class BytesType extends StringBaseType { + private BytesType() { + super("byte"); + } + } + private class StringBaseType implements KnownType { private final String format; diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/MethodDocBuilder.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/MethodDocBuilder.java index 9d0a9a70d..83d84071c 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/MethodDocBuilder.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/MethodDocBuilder.java @@ -1,5 +1,8 @@ package io.avaje.http.generator.core.openapi; +import java.util.Optional; + +import io.avaje.http.generator.core.ConsumesPrism; import io.avaje.http.generator.core.HiddenPrism; import io.avaje.http.generator.core.MethodParam; import io.avaje.http.generator.core.MethodReader; @@ -21,11 +24,13 @@ public class MethodDocBuilder { private final DocContext ctx; private final Operation operation = new Operation(); + private Optional consumeOp; public MethodDocBuilder(MethodReader methodReader, DocContext ctx) { this.methodReader = methodReader; this.ctx = ctx; this.javadoc = methodReader.javadoc(); + this.consumeOp = methodReader.consumesAnnotation(); } public void build() { @@ -129,6 +134,10 @@ Operation getOperation() { return operation; } + public Optional consumeOp() { + return consumeOp; + } + private boolean isEmpty(String value) { return value == null || value.isEmpty(); } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/MethodParamDocBuilder.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/MethodParamDocBuilder.java index 6248b2aa4..dc1093baa 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/MethodParamDocBuilder.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/MethodParamDocBuilder.java @@ -1,19 +1,25 @@ package io.avaje.http.generator.core.openapi; +import java.util.Optional; + +import javax.lang.model.element.Element; + +import io.avaje.http.generator.core.ConsumesPrism; import io.avaje.http.generator.core.ElementReader; import io.avaje.http.generator.core.ParamType; import io.avaje.http.generator.core.javadoc.Javadoc; import io.swagger.v3.oas.models.Operation; import io.swagger.v3.oas.models.media.Schema; +import io.swagger.v3.oas.models.media.StringSchema; import io.swagger.v3.oas.models.parameters.Parameter; -import javax.lang.model.element.Element; - /** * Build the OpenAPI for a method parameter. */ public class MethodParamDocBuilder { - + private static final String APP_FORM = "application/x-www-form-urlencoded"; + private static final String APP_JSON = "application/json"; + private static final String APP_TXT = "application/text"; private final DocContext ctx; private final Javadoc javadoc; private final Operation operation; @@ -22,12 +28,14 @@ public class MethodParamDocBuilder { private final String rawType; private final ParamType paramType; private final Element element; + private Optional consumeOp; public MethodParamDocBuilder(MethodDocBuilder methodDoc, ElementReader param) { this.ctx = methodDoc.getContext(); this.javadoc = methodDoc.getJavadoc(); this.operation = methodDoc.getOperation(); + this.consumeOp = methodDoc.consumeOp(); this.paramType = param.paramType(); this.paramName = param.paramName(); @@ -65,9 +73,21 @@ private void addMetaRequestBody(DocContext ctx, Javadoc javadoc, Operation opera Schema schema = ctx.toSchema(rawType, element); String description = javadoc.getParams().get(paramName); - - boolean asForm = (paramType == ParamType.FORM); - ctx.addRequestBody(operation, schema, asForm, description); + var mediaType = + consumeOp + .map(ConsumesPrism::value) + .orElseGet( + () -> { + boolean asForm = (paramType == ParamType.FORM); + var mime = asForm ? APP_FORM : APP_JSON; + + if (schema instanceof StringSchema) { + mime = APP_TXT; + } + return mime; + }); + + ctx.addRequestBody(operation, schema, mediaType, description); } } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/SchemaDocBuilder.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/SchemaDocBuilder.java index 7ad274788..4c08b73f6 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/SchemaDocBuilder.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/SchemaDocBuilder.java @@ -45,7 +45,6 @@ class SchemaDocBuilder { private static final String APP_FORM = "application/x-www-form-urlencoded"; private static final String APP_JSON = "application/json"; - private static final String APP_TXT = "application/text"; private final Elements elements; private final Types types; @@ -103,21 +102,15 @@ private Schema requestFormParamSchema(RequestBody body) { return schema; } - /** - * Add as request body. - */ - void addRequestBody(Operation operation, Schema schema, boolean asForm, String description) { + /** Add as request body. */ + void addRequestBody(Operation operation, Schema schema, String mediaType, String description) { RequestBody body = requestBody(operation); body.setDescription(description); MediaType mt = new MediaType(); mt.schema(schema); - String mime = asForm ? APP_FORM : APP_JSON; - if (schema instanceof StringSchema) { - mime = APP_TXT; - } - body.getContent().addMediaType(mime, mt); + body.getContent().addMediaType(mediaType, mt); } private RequestBody requestBody(Operation operation) { diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/package-info.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/package-info.java index bb2c116ea..3dd017405 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/package-info.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/package-info.java @@ -17,6 +17,7 @@ @GeneratePrism(value = io.avaje.http.api.Path.class, publicAccess = true) @GeneratePrism(value = io.avaje.http.api.Post.class, publicAccess = true) @GeneratePrism(value = io.avaje.http.api.Produces.class, publicAccess = true) +@GeneratePrism(value = io.avaje.http.api.Consumes.class, publicAccess = true) @GeneratePrism(value = io.avaje.http.api.Put.class, publicAccess = true) @GeneratePrism(value = io.swagger.v3.oas.annotations.OpenAPIDefinition.class, publicAccess = true) @GeneratePrism(value = io.swagger.v3.oas.annotations.tags.Tag.class, publicAccess = true) diff --git a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController2.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController2.java index b7b3392ce..7268ea18d 100644 --- a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController2.java +++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController2.java @@ -6,6 +6,7 @@ import org.example.myapp.web.ServerType; +import io.avaje.http.api.Consumes; import io.avaje.http.api.BodyString; import io.avaje.http.api.Controller; import io.avaje.http.api.Default; @@ -47,6 +48,7 @@ String mapTest(Map> strings) { } @Get("/inputStream") + @Consumes("application/bson") String stream(InputStream stream) { return stream.toString(); } From 444d34af950e83018ab2dd078f7c242dbb5766a3 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Wed, 5 Apr 2023 12:23:29 +1200 Subject: [PATCH 0723/1323] Updates to the test openapi.json that is generated --- .../src/main/resources/public/openapi.json | 56 +++++++++++++------ .../src/main/resources/public/openapi.json | 31 ++++++++++ 2 files changed, 70 insertions(+), 17 deletions(-) diff --git a/tests/test-javalin-jsonb/src/main/resources/public/openapi.json b/tests/test-javalin-jsonb/src/main/resources/public/openapi.json index 3eee94924..2fb2fd819 100644 --- a/tests/test-javalin-jsonb/src/main/resources/public/openapi.json +++ b/tests/test-javalin-jsonb/src/main/resources/public/openapi.json @@ -1158,10 +1158,8 @@ "content" : { "image/png" : { "schema" : { - "type" : "array", - "items" : { - "$ref" : "#/components/schemas/byte" - } + "type" : "string", + "format" : "byte" } } } @@ -1178,12 +1176,10 @@ "description" : "", "requestBody" : { "content" : { - "application/json" : { + "application/text" : { "schema" : { - "type" : "array", - "items" : { - "$ref" : "#/components/schemas/byte" - } + "type" : "string", + "format" : "byte" } } }, @@ -1553,9 +1549,10 @@ "description" : "", "requestBody" : { "content" : { - "application/json" : { + "application/bson" : { "schema" : { - "$ref" : "#/components/schemas/InputStream" + "type" : "string", + "format" : "byte" } } }, @@ -1840,6 +1837,37 @@ } } }, + "/test/strBody" : { + "post" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "requestBody" : { + "content" : { + "application/text" : { + "schema" : { + "type" : "string" + } + } + }, + "required" : true + }, + "responses" : { + "201" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, "/test/withMatrixParam/{type-1_segment}/{range_segment}" : { "get" : { "tags" : [ @@ -1988,9 +2016,6 @@ } } }, - "InputStream" : { - "type" : "object" - }, "MyForm" : { "type" : "object", "properties" : { @@ -2017,9 +2042,6 @@ "type" : "string" } } - }, - "byte" : { - "type" : "object" } }, "securitySchemes" : { diff --git a/tests/test-jex/src/main/resources/public/openapi.json b/tests/test-jex/src/main/resources/public/openapi.json index cbf18157e..0a2817d9f 100644 --- a/tests/test-jex/src/main/resources/public/openapi.json +++ b/tests/test-jex/src/main/resources/public/openapi.json @@ -326,6 +326,37 @@ } } }, + "/test/strBody" : { + "post" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "requestBody" : { + "content" : { + "application/text" : { + "schema" : { + "type" : "string" + } + } + }, + "required" : true + }, + "responses" : { + "201" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, "/withDefault/{name}" : { "get" : { "tags" : [ From f778f780c1b3e2127060d5e50b847f90faa352e4 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Wed, 5 Apr 2023 12:32:16 +1200 Subject: [PATCH 0724/1323] Update Javadoc for Consumes and tidy generator internals --- .../main/java/io/avaje/http/api/Consumes.java | 2 +- .../core/openapi/MethodDocBuilder.java | 6 ++-- .../core/openapi/MethodParamDocBuilder.java | 31 ++++++++----------- 3 files changed, 16 insertions(+), 23 deletions(-) diff --git a/http-api/src/main/java/io/avaje/http/api/Consumes.java b/http-api/src/main/java/io/avaje/http/api/Consumes.java index c3a511284..61b955eeb 100644 --- a/http-api/src/main/java/io/avaje/http/api/Consumes.java +++ b/http-api/src/main/java/io/avaje/http/api/Consumes.java @@ -11,7 +11,7 @@ * Specify endpoint request media type for the generated OpenAPI json. * *

When not specified the default MediaType is application/json, so we specify this on - * controllers or methods where the responses return a different media type. + * controllers or methods where the request consumes a different media type. * *

{@code
  * @Path("/customers")
diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/MethodDocBuilder.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/MethodDocBuilder.java
index 83d84071c..105fb646a 100644
--- a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/MethodDocBuilder.java
+++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/MethodDocBuilder.java
@@ -24,7 +24,7 @@ public class MethodDocBuilder {
   private final DocContext ctx;
 
   private final Operation operation = new Operation();
-  private Optional consumeOp;
+  private final Optional consumeOp;
 
   public MethodDocBuilder(MethodReader methodReader, DocContext ctx) {
     this.methodReader = methodReader;
@@ -34,9 +34,7 @@ public MethodDocBuilder(MethodReader methodReader, DocContext ctx) {
   }
 
   public void build() {
-
-    if (ctx.isOpenApiAvailable()
-        && methodReader.findAnnotation(HiddenPrism::getOptionalOn).isPresent()) {
+    if (ctx.isOpenApiAvailable() && methodReader.findAnnotation(HiddenPrism::getOptionalOn).isPresent()) {
       return;
     }
 
diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/MethodParamDocBuilder.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/MethodParamDocBuilder.java
index dc1093baa..80485ff09 100644
--- a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/MethodParamDocBuilder.java
+++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/MethodParamDocBuilder.java
@@ -28,15 +28,13 @@ public class MethodParamDocBuilder {
   private final String rawType;
   private final ParamType paramType;
   private final Element element;
-  private Optional consumeOp;
+  private final Optional consumeOp;
 
   public MethodParamDocBuilder(MethodDocBuilder methodDoc, ElementReader param) {
-
     this.ctx = methodDoc.getContext();
     this.javadoc = methodDoc.getJavadoc();
     this.operation = methodDoc.getOperation();
     this.consumeOp = methodDoc.consumeOp();
-
     this.paramType = param.paramType();
     this.paramName = param.paramName();
     this.varName = param.varName();
@@ -48,7 +46,6 @@ public MethodParamDocBuilder(MethodDocBuilder methodDoc, ElementReader param) {
    * Build the OpenAPI documentation for the method parameter.
    */
   public void build() {
-
     if (paramType == ParamType.FORM || paramType == ParamType.BODY) {
       addMetaRequestBody(ctx, javadoc, operation);
 
@@ -57,7 +54,7 @@ public void build() {
       param.setName(varName);
       param.setDescription(javadoc.getParams().get(paramName));
 
-      Schema schema = ctx.toSchema(rawType, element);
+      Schema schema = ctx.toSchema(rawType, element);
       if (paramType == ParamType.FORMPARAM) {
         ctx.addFormParam(operation, varName, schema);
 
@@ -70,24 +67,22 @@ public void build() {
   }
 
   private void addMetaRequestBody(DocContext ctx, Javadoc javadoc, Operation operation) {
-
-    Schema schema = ctx.toSchema(rawType, element);
-    String description = javadoc.getParams().get(paramName);
+    final var schema = ctx.toSchema(rawType, element);
+    final var description = javadoc.getParams().get(paramName);
     var mediaType =
         consumeOp
             .map(ConsumesPrism::value)
-            .orElseGet(
-                () -> {
-                  boolean asForm = (paramType == ParamType.FORM);
-                  var mime = asForm ? APP_FORM : APP_JSON;
-
-                  if (schema instanceof StringSchema) {
-                    mime = APP_TXT;
-                  }
-                  return mime;
-                });
+            .orElseGet(() -> requestMedia(schema));
 
     ctx.addRequestBody(operation, schema, mediaType, description);
   }
 
+  private String requestMedia(Schema schema) {
+    if (schema instanceof StringSchema) {
+      return APP_TXT;
+    }
+    boolean asForm = (paramType == ParamType.FORM);
+    return asForm ? APP_FORM : APP_JSON;
+  }
+
 }

From b1f6819c28fd4712bced50255d21c9be155f65ee Mon Sep 17 00:00:00 2001
From: Rob Bygrave 
Date: Wed, 5 Apr 2023 12:44:49 +1200
Subject: [PATCH 0725/1323] Bump avaje-inject and avaje-jsonb dependency
 versions

---
 http-client/pom.xml                                         | 6 +++---
 .../src/test/java/org/example/github/RepoJsonAdapter.java   | 5 ++---
 http-hibernate-validator/pom.xml                            | 2 +-
 tests/pom.xml                                               | 2 +-
 tests/test-javalin-jsonb/pom.xml                            | 2 +-
 tests/test-nima-jsonb/pom.xml                               | 4 ++--
 6 files changed, 10 insertions(+), 11 deletions(-)

diff --git a/http-client/pom.xml b/http-client/pom.xml
index 524e76e8a..7e3c800f0 100644
--- a/http-client/pom.xml
+++ b/http-client/pom.xml
@@ -36,14 +36,14 @@
     
       io.avaje
       avaje-jsonb
-      1.3
+      1.4
       true
     
 
     
       io.avaje
       avaje-inject
-      9.0-RC3
+      9.0
       true
     
 
@@ -106,7 +106,7 @@
                 
                   io.avaje
                   avaje-inject-generator
-                  9.0-RC3
+                  9.0
                 
               
             
diff --git a/http-client/src/test/java/org/example/github/RepoJsonAdapter.java b/http-client/src/test/java/org/example/github/RepoJsonAdapter.java
index 69e5b2ab2..f6e87a548 100644
--- a/http-client/src/test/java/org/example/github/RepoJsonAdapter.java
+++ b/http-client/src/test/java/org/example/github/RepoJsonAdapter.java
@@ -46,8 +46,7 @@ public void build(ViewBuilder builder, String name, MethodHandle handle) {
 
   @Override
   public void toJson(JsonWriter writer, Repo repo) {
-    writer.beginObject();
-    writer.names(names);
+    writer.beginObject(names);
     writer.name(0);
     plongJsonAdapter.toJson(writer, repo.id);
     writer.name(1);
@@ -60,7 +59,7 @@ public Repo fromJson(JsonReader reader) {
     Repo _$repo = new Repo();
 
     // read json
-    reader.beginObject();
+    reader.beginObject(names);
     while (reader.hasNextField()) {
       String fieldName = reader.nextField();
       switch (fieldName) {
diff --git a/http-hibernate-validator/pom.xml b/http-hibernate-validator/pom.xml
index 8a6d7e38d..07a2a4ce9 100644
--- a/http-hibernate-validator/pom.xml
+++ b/http-hibernate-validator/pom.xml
@@ -43,7 +43,7 @@
     
       io.avaje
       avaje-inject
-      9.0-RC2
+      9.0
       provided
     
 
diff --git a/tests/pom.xml b/tests/pom.xml
index 38d12a99f..cf6e66d26 100644
--- a/tests/pom.xml
+++ b/tests/pom.xml
@@ -16,7 +16,7 @@
     3.24.1
     2.14.1
     2.5
-    8.12-RC3
+    9.0
   
 
   
diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml
index 224c0c92e..97cf54310 100644
--- a/tests/test-javalin-jsonb/pom.xml
+++ b/tests/test-javalin-jsonb/pom.xml
@@ -81,7 +81,7 @@
     
       io.avaje
       avaje-jsonb-generator
-      1.1
+      1.4
       provided
     
 
diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml
index 1669adfa2..366585e5b 100644
--- a/tests/test-nima-jsonb/pom.xml
+++ b/tests/test-nima-jsonb/pom.xml
@@ -31,7 +31,7 @@
 		
 			io.avaje
 			avaje-jsonb
-			1.4-RC8
+			1.4
 		
 		
 			io.helidon.nima.webserver
@@ -79,7 +79,7 @@
 						
 							io.avaje
 							avaje-jsonb-generator
-							1.4-RC8
+							1.4
 						
 					
 				

From 4d9136db3d8502c514215c9bd1f2312e697c8ffb Mon Sep 17 00:00:00 2001
From: Rob Bygrave 
Date: Wed, 5 Apr 2023 15:24:53 +1200
Subject: [PATCH 0726/1323] Version 1.35

---
 http-api/pom.xml                     | 2 +-
 http-client-gson-adapter/pom.xml     | 4 ++--
 http-client/pom.xml                  | 2 +-
 http-generator-client/pom.xml        | 2 +-
 http-generator-core/pom.xml          | 2 +-
 http-generator-helidon/pom.xml       | 2 +-
 http-generator-javalin/pom.xml       | 2 +-
 http-generator-jex/pom.xml           | 2 +-
 http-generator-nima/pom.xml          | 2 +-
 pom.xml                              | 2 +-
 tests/pom.xml                        | 2 +-
 tests/test-client-generation/pom.xml | 2 +-
 tests/test-client/pom.xml            | 2 +-
 tests/test-helidon/pom.xml           | 2 +-
 tests/test-javalin-jsonb/pom.xml     | 2 +-
 tests/test-javalin/pom.xml           | 2 +-
 tests/test-jex/pom.xml               | 2 +-
 tests/test-nima-jsonb/pom.xml        | 2 +-
 tests/test-nima/pom.xml              | 2 +-
 19 files changed, 20 insertions(+), 20 deletions(-)

diff --git a/http-api/pom.xml b/http-api/pom.xml
index fa4672167..50d69c4d1 100644
--- a/http-api/pom.xml
+++ b/http-api/pom.xml
@@ -4,7 +4,7 @@
   
     io.avaje
     avaje-http-parent
-    1.34
+    1.35
     ..
   
 
diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml
index 10fa868cd..253fd35d3 100644
--- a/http-client-gson-adapter/pom.xml
+++ b/http-client-gson-adapter/pom.xml
@@ -4,7 +4,7 @@
   
     io.avaje
     avaje-http-parent
-    1.34
+    1.35
   
 
   avaje-http-client-gson
@@ -20,7 +20,7 @@
     
       io.avaje
       avaje-http-client
-      1.34
+      1.35
       provided
     
 
diff --git a/http-client/pom.xml b/http-client/pom.xml
index 7e3c800f0..0d436a0d5 100644
--- a/http-client/pom.xml
+++ b/http-client/pom.xml
@@ -4,7 +4,7 @@
   
     io.avaje
     avaje-http-parent
-    1.34
+    1.35
   
 
   avaje-http-client
diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml
index 2642e7d48..7940df3e1 100644
--- a/http-generator-client/pom.xml
+++ b/http-generator-client/pom.xml
@@ -4,7 +4,7 @@
   
     io.avaje
     avaje-http-parent
-    1.34
+    1.35
   
 
   avaje-http-client-generator
diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml
index d58f954ff..5d4e66982 100644
--- a/http-generator-core/pom.xml
+++ b/http-generator-core/pom.xml
@@ -4,7 +4,7 @@
   
     io.avaje
     avaje-http-parent
-    1.34
+    1.35
   
 
   avaje-http-generator-core
diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml
index 998aec9e0..7468e1eac 100644
--- a/http-generator-helidon/pom.xml
+++ b/http-generator-helidon/pom.xml
@@ -4,7 +4,7 @@
   
     io.avaje
     avaje-http-parent
-    1.34
+    1.35
   
 
   avaje-http-helidon-generator
diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml
index 97989f936..f87c2fe28 100644
--- a/http-generator-javalin/pom.xml
+++ b/http-generator-javalin/pom.xml
@@ -4,7 +4,7 @@
   
     io.avaje
     avaje-http-parent
-    1.34
+    1.35
   
 
   avaje-http-javalin-generator
diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml
index 848d02378..50907910d 100644
--- a/http-generator-jex/pom.xml
+++ b/http-generator-jex/pom.xml
@@ -4,7 +4,7 @@
   
     io.avaje
     avaje-http-parent
-    1.34
+    1.35
   
 
   avaje-http-jex-generator
diff --git a/http-generator-nima/pom.xml b/http-generator-nima/pom.xml
index c43426c5e..8d6135c66 100644
--- a/http-generator-nima/pom.xml
+++ b/http-generator-nima/pom.xml
@@ -4,7 +4,7 @@
   
     avaje-http-parent
     io.avaje
-    1.34
+    1.35
   
 
   avaje-http-nima-generator
diff --git a/pom.xml b/pom.xml
index e49d33e58..3d57bf979 100644
--- a/pom.xml
+++ b/pom.xml
@@ -9,7 +9,7 @@
 
   io.avaje
   avaje-http-parent
-  1.34
+  1.35
   pom
 
   
diff --git a/tests/pom.xml b/tests/pom.xml
index cf6e66d26..88b55115b 100644
--- a/tests/pom.xml
+++ b/tests/pom.xml
@@ -4,7 +4,7 @@
   
     avaje-http-parent
     io.avaje
-    1.34
+    1.35
   
 
   tests
diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml
index c5ade2b62..13a6543ce 100644
--- a/tests/test-client-generation/pom.xml
+++ b/tests/test-client-generation/pom.xml
@@ -4,7 +4,7 @@
   
     io.avaje
     tests
-    1.34
+    1.35
   
 
   test-client-generation
diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml
index 8524573f8..6dcd0bc61 100644
--- a/tests/test-client/pom.xml
+++ b/tests/test-client/pom.xml
@@ -6,7 +6,7 @@
   
     io.avaje
     tests
-    1.34
+    1.35
   
 
   test-client
diff --git a/tests/test-helidon/pom.xml b/tests/test-helidon/pom.xml
index 5fb2454af..45c3e2c2a 100644
--- a/tests/test-helidon/pom.xml
+++ b/tests/test-helidon/pom.xml
@@ -4,7 +4,7 @@
   
     io.avaje
     tests
-    1.34
+    1.35
   
 
   test-helidon
diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml
index 97cf54310..5c733cd40 100644
--- a/tests/test-javalin-jsonb/pom.xml
+++ b/tests/test-javalin-jsonb/pom.xml
@@ -5,7 +5,7 @@
   
     io.avaje
     tests
-    1.34
+    1.35
   
 
   test-javalin-jsonb
diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml
index 606bd037e..db8758993 100644
--- a/tests/test-javalin/pom.xml
+++ b/tests/test-javalin/pom.xml
@@ -4,7 +4,7 @@
   
     io.avaje
     tests
-    1.34
+    1.35
   
 
   test-javalin
diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml
index 4d1bc6460..0d908e07f 100644
--- a/tests/test-jex/pom.xml
+++ b/tests/test-jex/pom.xml
@@ -4,7 +4,7 @@
   
     io.avaje
     tests
-    1.34
+    1.35
   
 
   test-jex
diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml
index 366585e5b..d2b58a3ed 100644
--- a/tests/test-nima-jsonb/pom.xml
+++ b/tests/test-nima-jsonb/pom.xml
@@ -4,7 +4,7 @@
   
     io.avaje
     tests
-    1.34
+    1.35
   
 
 	test-nima-jsonb
diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml
index 314fb4c94..bbc7104d8 100644
--- a/tests/test-nima/pom.xml
+++ b/tests/test-nima/pom.xml
@@ -6,7 +6,7 @@
   
     io.avaje
     tests
-    1.34
+    1.35
   
 
   test-nima

From 11d24f877c8ba3a7ff94889e87493e17525cd165 Mon Sep 17 00:00:00 2001
From: Rob Bygrave 
Date: Wed, 5 Apr 2023 15:25:46 +1200
Subject: [PATCH 0727/1323] Bump to next snapshot version

---
 http-api/pom.xml                     | 2 +-
 http-client-gson-adapter/pom.xml     | 4 ++--
 http-client/pom.xml                  | 2 +-
 http-generator-client/pom.xml        | 2 +-
 http-generator-core/pom.xml          | 2 +-
 http-generator-helidon/pom.xml       | 2 +-
 http-generator-javalin/pom.xml       | 2 +-
 http-generator-jex/pom.xml           | 2 +-
 http-generator-nima/pom.xml          | 2 +-
 pom.xml                              | 2 +-
 tests/pom.xml                        | 2 +-
 tests/test-client-generation/pom.xml | 2 +-
 tests/test-client/pom.xml            | 2 +-
 tests/test-helidon/pom.xml           | 2 +-
 tests/test-javalin-jsonb/pom.xml     | 2 +-
 tests/test-javalin/pom.xml           | 2 +-
 tests/test-jex/pom.xml               | 2 +-
 tests/test-nima-jsonb/pom.xml        | 2 +-
 tests/test-nima/pom.xml              | 2 +-
 19 files changed, 20 insertions(+), 20 deletions(-)

diff --git a/http-api/pom.xml b/http-api/pom.xml
index 50d69c4d1..9c2f74994 100644
--- a/http-api/pom.xml
+++ b/http-api/pom.xml
@@ -4,7 +4,7 @@
   
     io.avaje
     avaje-http-parent
-    1.35
+    1.36-SNAPSHOT
     ..
   
 
diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml
index 253fd35d3..6bce8c6bb 100644
--- a/http-client-gson-adapter/pom.xml
+++ b/http-client-gson-adapter/pom.xml
@@ -4,7 +4,7 @@
   
     io.avaje
     avaje-http-parent
-    1.35
+    1.36-SNAPSHOT
   
 
   avaje-http-client-gson
@@ -20,7 +20,7 @@
     
       io.avaje
       avaje-http-client
-      1.35
+      1.36-SNAPSHOT
       provided
     
 
diff --git a/http-client/pom.xml b/http-client/pom.xml
index 0d436a0d5..d205698ab 100644
--- a/http-client/pom.xml
+++ b/http-client/pom.xml
@@ -4,7 +4,7 @@
   
     io.avaje
     avaje-http-parent
-    1.35
+    1.36-SNAPSHOT
   
 
   avaje-http-client
diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml
index 7940df3e1..a5b908269 100644
--- a/http-generator-client/pom.xml
+++ b/http-generator-client/pom.xml
@@ -4,7 +4,7 @@
   
     io.avaje
     avaje-http-parent
-    1.35
+    1.36-SNAPSHOT
   
 
   avaje-http-client-generator
diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml
index 5d4e66982..cc83b9349 100644
--- a/http-generator-core/pom.xml
+++ b/http-generator-core/pom.xml
@@ -4,7 +4,7 @@
   
     io.avaje
     avaje-http-parent
-    1.35
+    1.36-SNAPSHOT
   
 
   avaje-http-generator-core
diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml
index 7468e1eac..5d1155593 100644
--- a/http-generator-helidon/pom.xml
+++ b/http-generator-helidon/pom.xml
@@ -4,7 +4,7 @@
   
     io.avaje
     avaje-http-parent
-    1.35
+    1.36-SNAPSHOT
   
 
   avaje-http-helidon-generator
diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml
index f87c2fe28..f09c70216 100644
--- a/http-generator-javalin/pom.xml
+++ b/http-generator-javalin/pom.xml
@@ -4,7 +4,7 @@
   
     io.avaje
     avaje-http-parent
-    1.35
+    1.36-SNAPSHOT
   
 
   avaje-http-javalin-generator
diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml
index 50907910d..96777a2fe 100644
--- a/http-generator-jex/pom.xml
+++ b/http-generator-jex/pom.xml
@@ -4,7 +4,7 @@
   
     io.avaje
     avaje-http-parent
-    1.35
+    1.36-SNAPSHOT
   
 
   avaje-http-jex-generator
diff --git a/http-generator-nima/pom.xml b/http-generator-nima/pom.xml
index 8d6135c66..feb21a048 100644
--- a/http-generator-nima/pom.xml
+++ b/http-generator-nima/pom.xml
@@ -4,7 +4,7 @@
   
     avaje-http-parent
     io.avaje
-    1.35
+    1.36-SNAPSHOT
   
 
   avaje-http-nima-generator
diff --git a/pom.xml b/pom.xml
index 3d57bf979..6438be347 100644
--- a/pom.xml
+++ b/pom.xml
@@ -9,7 +9,7 @@
 
   io.avaje
   avaje-http-parent
-  1.35
+  1.36-SNAPSHOT
   pom
 
   
diff --git a/tests/pom.xml b/tests/pom.xml
index 88b55115b..66043d95d 100644
--- a/tests/pom.xml
+++ b/tests/pom.xml
@@ -4,7 +4,7 @@
   
     avaje-http-parent
     io.avaje
-    1.35
+    1.36-SNAPSHOT
   
 
   tests
diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml
index 13a6543ce..c86e4bc27 100644
--- a/tests/test-client-generation/pom.xml
+++ b/tests/test-client-generation/pom.xml
@@ -4,7 +4,7 @@
   
     io.avaje
     tests
-    1.35
+    1.36-SNAPSHOT
   
 
   test-client-generation
diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml
index 6dcd0bc61..ab2dae722 100644
--- a/tests/test-client/pom.xml
+++ b/tests/test-client/pom.xml
@@ -6,7 +6,7 @@
   
     io.avaje
     tests
-    1.35
+    1.36-SNAPSHOT
   
 
   test-client
diff --git a/tests/test-helidon/pom.xml b/tests/test-helidon/pom.xml
index 45c3e2c2a..8b360d0bb 100644
--- a/tests/test-helidon/pom.xml
+++ b/tests/test-helidon/pom.xml
@@ -4,7 +4,7 @@
   
     io.avaje
     tests
-    1.35
+    1.36-SNAPSHOT
   
 
   test-helidon
diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml
index 5c733cd40..ec9933dc5 100644
--- a/tests/test-javalin-jsonb/pom.xml
+++ b/tests/test-javalin-jsonb/pom.xml
@@ -5,7 +5,7 @@
   
     io.avaje
     tests
-    1.35
+    1.36-SNAPSHOT
   
 
   test-javalin-jsonb
diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml
index db8758993..fc8d58d25 100644
--- a/tests/test-javalin/pom.xml
+++ b/tests/test-javalin/pom.xml
@@ -4,7 +4,7 @@
   
     io.avaje
     tests
-    1.35
+    1.36-SNAPSHOT
   
 
   test-javalin
diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml
index 0d908e07f..4d5fffd6f 100644
--- a/tests/test-jex/pom.xml
+++ b/tests/test-jex/pom.xml
@@ -4,7 +4,7 @@
   
     io.avaje
     tests
-    1.35
+    1.36-SNAPSHOT
   
 
   test-jex
diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml
index d2b58a3ed..9b12359f5 100644
--- a/tests/test-nima-jsonb/pom.xml
+++ b/tests/test-nima-jsonb/pom.xml
@@ -4,7 +4,7 @@
   
     io.avaje
     tests
-    1.35
+    1.36-SNAPSHOT
   
 
 	test-nima-jsonb
diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml
index bbc7104d8..d4715b237 100644
--- a/tests/test-nima/pom.xml
+++ b/tests/test-nima/pom.xml
@@ -6,7 +6,7 @@
   
     io.avaje
     tests
-    1.35
+    1.36-SNAPSHOT
   
 
   test-nima

From 5fd620d4164537db231c9b40ca7205a369b92ab0 Mon Sep 17 00:00:00 2001
From: Josiah Noel <32279667+SentryMan@users.noreply.github.com>
Date: Thu, 13 Apr 2023 06:28:08 -0400
Subject: [PATCH 0728/1323] vararg interceptors (#203)

---
 .../avaje/http/client/DHttpClientBuilder.java  |  9 +++++----
 .../http/client/DHttpClientContextBuilder.java | 18 ++++++++++--------
 .../java/io/avaje/http/client/HttpClient.java  |  4 ++--
 .../avaje/http/client/HttpClientContext.java   |  4 ++--
 4 files changed, 19 insertions(+), 16 deletions(-)

diff --git a/http-client/src/main/java/io/avaje/http/client/DHttpClientBuilder.java b/http-client/src/main/java/io/avaje/http/client/DHttpClientBuilder.java
index 1641c23f1..c0426385f 100644
--- a/http-client/src/main/java/io/avaje/http/client/DHttpClientBuilder.java
+++ b/http-client/src/main/java/io/avaje/http/client/DHttpClientBuilder.java
@@ -8,6 +8,7 @@
 import java.net.CookieHandler;
 import java.net.ProxySelector;
 import java.time.Duration;
+import java.util.Collections;
 import java.util.concurrent.Executor;
 
 final class DHttpClientBuilder extends DBaseBuilder implements HttpClient.Builder, HttpClient.Builder.State {
@@ -58,14 +59,14 @@ public HttpClient.Builder requestLogging(boolean requestLogging) {
   }
 
   @Override
-  public HttpClient.Builder requestListener(RequestListener requestListener) {
-    this.listeners.add(requestListener);
+  public HttpClient.Builder requestListener(RequestListener... requestListener) {
+    Collections.addAll(listeners, requestListener);
     return this;
   }
 
   @Override
-  public HttpClient.Builder requestIntercept(RequestIntercept requestIntercept) {
-    this.interceptors.add(requestIntercept);
+  public HttpClient.Builder requestIntercept(RequestIntercept... requestIntercept) {
+    Collections.addAll(interceptors, requestIntercept);
     return this;
   }
 
diff --git a/http-client/src/main/java/io/avaje/http/client/DHttpClientContextBuilder.java b/http-client/src/main/java/io/avaje/http/client/DHttpClientContextBuilder.java
index 98ba0a801..d6dd785bd 100644
--- a/http-client/src/main/java/io/avaje/http/client/DHttpClientContextBuilder.java
+++ b/http-client/src/main/java/io/avaje/http/client/DHttpClientContextBuilder.java
@@ -1,16 +1,18 @@
 package io.avaje.http.client;
 
-import io.avaje.inject.BeanScope;
-
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.SSLParameters;
 import java.net.Authenticator;
 import java.net.CookieHandler;
 import java.net.ProxySelector;
 import java.net.http.HttpClient;
 import java.time.Duration;
+import java.util.Collections;
 import java.util.concurrent.Executor;
 
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLParameters;
+
+import io.avaje.inject.BeanScope;
+
 final class DHttpClientContextBuilder extends DBaseBuilder implements HttpClientContext.Builder, HttpClientContext.Builder.State {
 
   DHttpClientContextBuilder() {
@@ -59,14 +61,14 @@ public HttpClientContext.Builder requestLogging(boolean requestLogging) {
   }
 
   @Override
-  public HttpClientContext.Builder requestListener(RequestListener requestListener) {
-    this.listeners.add(requestListener);
+  public HttpClientContext.Builder requestListener(RequestListener... requestListener) {
+    Collections.addAll(listeners, requestListener);
     return this;
   }
 
   @Override
-  public HttpClientContext.Builder requestIntercept(RequestIntercept requestIntercept) {
-    this.interceptors.add(requestIntercept);
+  public HttpClientContext.Builder requestIntercept(RequestIntercept... requestIntercept) {
+    Collections.addAll(interceptors, requestIntercept);
     return this;
   }
 
diff --git a/http-client/src/main/java/io/avaje/http/client/HttpClient.java b/http-client/src/main/java/io/avaje/http/client/HttpClient.java
index ca9501244..f6b9b976e 100644
--- a/http-client/src/main/java/io/avaje/http/client/HttpClient.java
+++ b/http-client/src/main/java/io/avaje/http/client/HttpClient.java
@@ -188,12 +188,12 @@ interface Builder {
      *
      * @see RequestLogger
      */
-    Builder requestListener(RequestListener requestListener);
+    Builder requestListener(RequestListener... requestListener);
 
     /**
      * Add a request interceptor. Multiple interceptors may be added.
      */
-    Builder requestIntercept(RequestIntercept requestIntercept);
+    Builder requestIntercept(RequestIntercept... requestIntercept);
 
     /**
      * Add a Authorization token provider.
diff --git a/http-client/src/main/java/io/avaje/http/client/HttpClientContext.java b/http-client/src/main/java/io/avaje/http/client/HttpClientContext.java
index 12ce33d3d..d34f9e42a 100644
--- a/http-client/src/main/java/io/avaje/http/client/HttpClientContext.java
+++ b/http-client/src/main/java/io/avaje/http/client/HttpClientContext.java
@@ -165,12 +165,12 @@ interface Builder {
      *
      * @see RequestLogger
      */
-    Builder requestListener(RequestListener requestListener);
+    Builder requestListener(RequestListener... requestListener);
 
     /**
      * Add a request interceptor. Multiple interceptors may be added.
      */
-    Builder requestIntercept(RequestIntercept requestIntercept);
+    Builder requestIntercept(RequestIntercept... requestIntercept);
 
     /**
      * Add a Authorization token provider.

From c04103fe75eb6a0a0bafbb4cd6216104732248a5 Mon Sep 17 00:00:00 2001
From: Rob Bygrave 
Date: Mon, 17 Apr 2023 19:09:45 +1200
Subject: [PATCH 0729/1323] [http client] Expose UrlBuilder url() method on
 client

---
 .../java/io/avaje/http/client/HttpClient.java |  5 +++
 .../io/avaje/http/client/SpiHttpClient.java   |  6 ----
 .../http/client/DHttpClientContextTest.java   | 33 +++++++++----------
 3 files changed, 21 insertions(+), 23 deletions(-)

diff --git a/http-client/src/main/java/io/avaje/http/client/HttpClient.java b/http-client/src/main/java/io/avaje/http/client/HttpClient.java
index ca9501244..049818b53 100644
--- a/http-client/src/main/java/io/avaje/http/client/HttpClient.java
+++ b/http-client/src/main/java/io/avaje/http/client/HttpClient.java
@@ -65,6 +65,11 @@ static Builder builder() {
    */
   HttpClientRequest request();
 
+  /**
+   * Return a UrlBuilder to use to build an URL taking into account the base URL.
+   */
+  UrlBuilder url();
+
   /**
    * Deprecated - migrate to {@link #bodyAdapter()}.
    * 

diff --git a/http-client/src/main/java/io/avaje/http/client/SpiHttpClient.java b/http-client/src/main/java/io/avaje/http/client/SpiHttpClient.java index b7a1c1fb1..fe7835ec8 100644 --- a/http-client/src/main/java/io/avaje/http/client/SpiHttpClient.java +++ b/http-client/src/main/java/io/avaje/http/client/SpiHttpClient.java @@ -8,12 +8,6 @@ */ interface SpiHttpClient { - /** - * Return a UrlBuilder to use to build an URL taking into - * account the base URL. - */ - UrlBuilder url(); - /** * Return the underlying http client. */ diff --git a/http-client/src/test/java/io/avaje/http/client/DHttpClientContextTest.java b/http-client/src/test/java/io/avaje/http/client/DHttpClientContextTest.java index 0811224af..6a9e2f4d2 100644 --- a/http-client/src/test/java/io/avaje/http/client/DHttpClientContextTest.java +++ b/http-client/src/test/java/io/avaje/http/client/DHttpClientContextTest.java @@ -3,7 +3,6 @@ import org.example.github.BasicClientInterface; import org.junit.jupiter.api.Test; -import java.net.http.HttpClient; import java.nio.charset.StandardCharsets; import static org.assertj.core.api.Assertions.assertThat; @@ -40,49 +39,49 @@ void gzip_contentDecode() { @Test void build_basic() { - final HttpClientContext context = - HttpClientContext.builder() + final HttpClient client = + HttpClient.builder() .baseUrl("http://localhost") .build(); - SpiHttpClient spi = (SpiHttpClient)context; + SpiHttpClient spi = (SpiHttpClient)client; // has default client created assertThat(spi.httpClient()).isNotNull(); - assertThat(spi.httpClient().version()).isEqualTo(HttpClient.Version.HTTP_2); + assertThat(spi.httpClient().version()).isEqualTo(java.net.http.HttpClient.Version.HTTP_2); assertThat(spi.httpClient().cookieHandler()).isPresent(); // has expected url building - assertThat(spi.url().build()).isEqualTo("http://localhost"); - assertThat(spi.url().path("hello").build()).isEqualTo("http://localhost/hello"); - assertThat(spi.url().queryParam("hello","there").build()).isEqualTo("http://localhost?hello=there"); + assertThat(client.url().build()).isEqualTo("http://localhost"); + assertThat(client.url().path("hello").build()).isEqualTo("http://localhost/hello"); + assertThat(client.url().queryParam("hello","there").build()).isEqualTo("http://localhost?hello=there"); } @Test void build_noCookieHandler() { - final HttpClientContext context = - HttpClientContext.builder() + final HttpClient client = + HttpClient.builder() .baseUrl("http://localhost") .cookieHandler(null) - .redirect(HttpClient.Redirect.ALWAYS) + .redirect(java.net.http.HttpClient.Redirect.ALWAYS) .build(); - SpiHttpClient spi = (SpiHttpClient)context; + SpiHttpClient spi = (SpiHttpClient)client; // has default client created assertThat(spi.httpClient()).isNotNull(); - assertThat(spi.httpClient().version()).isEqualTo(HttpClient.Version.HTTP_2); + assertThat(spi.httpClient().version()).isEqualTo(java.net.http.HttpClient.Version.HTTP_2); assertThat(spi.httpClient().cookieHandler()).isEmpty(); // has expected url building - assertThat(spi.url().build()).isEqualTo("http://localhost"); - assertThat(spi.url().path("hello").build()).isEqualTo("http://localhost/hello"); - assertThat(spi.url().queryParam("hello","there").build()).isEqualTo("http://localhost?hello=there"); + assertThat(client.url().build()).isEqualTo("http://localhost"); + assertThat(client.url().path("hello").build()).isEqualTo("http://localhost/hello"); + assertThat(client.url().queryParam("hello","there").build()).isEqualTo("http://localhost?hello=there"); } @Test void build_missingBaseUrl() { try { - HttpClientContext.builder().build(); + HttpClient.builder().build(); } catch (NullPointerException e) { assertThat(e.getMessage()).contains("baseUrl is not specified"); } From 492897939f8ce5b828352eee91bd2c75ecf18203 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Tue, 18 Apr 2023 04:54:21 -0400 Subject: [PATCH 0730/1323] Add RequestContextResolver Feature (#204) * now adds request resolver * Update BaseControllerWriter.java * add for other generators * works * lowercase b * Update JsonBUtil.java * pr comment * add ServerContext class to hold both req and res * prevent rebinding context * add hibernate plugin --- .github/workflows/build.yml | 2 +- http-api/pom.xml | 22 +++ .../java/io/avaje/http/api/Controller.java | 3 + .../main/java/io/avaje/http/api/Delete.java | 12 +- .../src/main/java/io/avaje/http/api/Get.java | 10 +- .../main/java/io/avaje/http/api/Patch.java | 20 +- .../src/main/java/io/avaje/http/api/Post.java | 10 +- .../src/main/java/io/avaje/http/api/Put.java | 10 +- .../api/context/RequestContextResolver.java | 49 +++++ .../avaje/http/api/context/ServerContext.java | 31 +++ .../ThreadLocalRequestContextResolver.java | 54 ++++++ .../http/api/spi/DefaultResolverProvider.java | 20 ++ http-api/src/main/java/module-info.java | 7 +- .../services/io.avaje.inject.spi.Plugin | 1 + ...ThreadLocalRequestContextResolverTest.java | 94 +++++++++ .../generator/core/BaseControllerWriter.java | 11 +- .../http/generator/core/BaseProcessor.java | 3 +- .../http/generator/core/ControllerReader.java | 12 +- .../avaje/http/generator/core/JsonBUtil.java | 2 +- .../http/generator/core/MethodReader.java | 48 ++++- .../generator/core/ProcessingContext.java | 8 +- .../http/generator/core/package-info.java | 1 + .../helidon/ControllerMethodWriter.java | 23 ++- .../generator/helidon/ControllerWriter.java | 11 ++ .../javalin/ControllerMethodWriter.java | 17 +- .../generator/javalin/ControllerWriter.java | 22 ++- .../generator/jex/ControllerMethodWriter.java | 9 +- .../http/generator/jex/ControllerWriter.java | 11 ++ http-generator-nima/pom.xml | 4 +- .../helidon/nima/ControllerMethodWriter.java | 20 +- .../helidon/nima/ControllerWriter.java | 28 ++- tests/test-helidon/pom.xml | 13 ++ .../java/org/example/ReqScopedController.java | 3 +- .../myapp/web/test/TestController2.java | 15 +- .../org/example/myapp/web/BarInterface.java | 2 +- .../java/org/example/web/TestController.java | 2 +- tests/test-nima-jsonb/.classpath | 6 - tests/test-nima-jsonb/pom.xml | 178 ++++++++++-------- .../java/org/example/HelloController.java | 2 + .../src/main/java/org/example/MyForm.java | 3 + .../main/java/org/example/TestController.java | 3 +- tests/test-nima/pom.xml | 10 +- 42 files changed, 650 insertions(+), 162 deletions(-) create mode 100644 http-api/src/main/java/io/avaje/http/api/context/RequestContextResolver.java create mode 100644 http-api/src/main/java/io/avaje/http/api/context/ServerContext.java create mode 100644 http-api/src/main/java/io/avaje/http/api/context/ThreadLocalRequestContextResolver.java create mode 100644 http-api/src/main/java/io/avaje/http/api/spi/DefaultResolverProvider.java create mode 100644 http-api/src/main/resources/META-INF/services/io.avaje.inject.spi.Plugin create mode 100644 http-api/src/test/java/io/avaje/http/api/context/ThreadLocalRequestContextResolverTest.java diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 031109b75..f6d717324 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -10,7 +10,7 @@ jobs: strategy: fail-fast: false matrix: - java_version: [11, 17, 19] + java_version: [11, 17, 20] os: [ubuntu-latest] steps: diff --git a/http-api/pom.xml b/http-api/pom.xml index 9c2f74994..9330dcb2f 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -15,4 +15,26 @@ avaje-http-parent-1.19 + + + io.avaje + avaje-inject + 9.0 + provided + true + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 3.0.0 + + 0 + + + + diff --git a/http-api/src/main/java/io/avaje/http/api/Controller.java b/http-api/src/main/java/io/avaje/http/api/Controller.java index e920e7352..575eeb643 100644 --- a/http-api/src/main/java/io/avaje/http/api/Controller.java +++ b/http-api/src/main/java/io/avaje/http/api/Controller.java @@ -23,4 +23,7 @@ /** Specify the path mapping request to the controller. */ String value() default ""; + + /** Specify if the http request context should be instrumented via RequestContextResolver */ + boolean instrumentRequestContext() default false; } diff --git a/http-api/src/main/java/io/avaje/http/api/Delete.java b/http-api/src/main/java/io/avaje/http/api/Delete.java index 62c26c2d4..ab82fc551 100644 --- a/http-api/src/main/java/io/avaje/http/api/Delete.java +++ b/http-api/src/main/java/io/avaje/http/api/Delete.java @@ -19,13 +19,13 @@ * * }

*/ -@Target(value=METHOD) -@Retention(value=RUNTIME) -@HttpMethod(value="DELETE") +@Target(METHOD) +@Retention(RUNTIME) +@HttpMethod("DELETE") public @interface Delete { - /** - * Specify the path. - */ + /** Specify the path. */ String value() default ""; + + boolean instrumentRequestContext() default false; } diff --git a/http-api/src/main/java/io/avaje/http/api/Get.java b/http-api/src/main/java/io/avaje/http/api/Get.java index 95dcd27f7..7238b90cc 100644 --- a/http-api/src/main/java/io/avaje/http/api/Get.java +++ b/http-api/src/main/java/io/avaje/http/api/Get.java @@ -49,9 +49,13 @@ * * }
*/ -@Target(value=METHOD) -@Retention(value=RUNTIME) -@HttpMethod(value="GET") +@Target(METHOD) +@Retention(RUNTIME) +@HttpMethod("GET") public @interface Get { + + /** Specify the path. */ String value() default ""; + + boolean instrumentRequestContext() default false; } diff --git a/http-api/src/main/java/io/avaje/http/api/Patch.java b/http-api/src/main/java/io/avaje/http/api/Patch.java index 2f05fa59f..afed8854b 100644 --- a/http-api/src/main/java/io/avaje/http/api/Patch.java +++ b/http-api/src/main/java/io/avaje/http/api/Patch.java @@ -1,17 +1,19 @@ package io.avaje.http.api; -import java.lang.annotation.Retention; -import java.lang.annotation.Target; - import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.RetentionPolicy.RUNTIME; -/** - * Marks a method that handles HTTP PATCH requests. - */ -@Target(value = METHOD) -@Retention(value = RUNTIME) -@HttpMethod(value = "PATCH") +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +/** Marks a method that handles HTTP PATCH requests. */ +@Target(METHOD) +@Retention(RUNTIME) +@HttpMethod("PATCH") public @interface Patch { + + /** Specify the path. */ String value() default ""; + + boolean instrumentRequestContext() default false; } diff --git a/http-api/src/main/java/io/avaje/http/api/Post.java b/http-api/src/main/java/io/avaje/http/api/Post.java index 7a381e62f..158461f39 100644 --- a/http-api/src/main/java/io/avaje/http/api/Post.java +++ b/http-api/src/main/java/io/avaje/http/api/Post.java @@ -16,9 +16,13 @@ ... * } */ -@Target(value=METHOD) -@Retention(value=RUNTIME) -@HttpMethod(value="POST") +@Target(METHOD) +@Retention(RUNTIME) +@HttpMethod("POST") public @interface Post { + + /** Specify the path. */ String value() default ""; + + boolean instrumentRequestContext() default false; } diff --git a/http-api/src/main/java/io/avaje/http/api/Put.java b/http-api/src/main/java/io/avaje/http/api/Put.java index 2dd353fe2..e3b23c8a1 100644 --- a/http-api/src/main/java/io/avaje/http/api/Put.java +++ b/http-api/src/main/java/io/avaje/http/api/Put.java @@ -9,9 +9,13 @@ /** * Marks a method that handles HTTP PUT requests. */ -@Target(value=METHOD) -@Retention(value=RUNTIME) -@HttpMethod(value="PUT") +@Target(METHOD) +@Retention(RUNTIME) +@HttpMethod("PUT") public @interface Put { + + /** Specify the path. */ String value() default ""; + + boolean instrumentRequestContext() default false; } diff --git a/http-api/src/main/java/io/avaje/http/api/context/RequestContextResolver.java b/http-api/src/main/java/io/avaje/http/api/context/RequestContextResolver.java new file mode 100644 index 000000000..a85d72bc1 --- /dev/null +++ b/http-api/src/main/java/io/avaje/http/api/context/RequestContextResolver.java @@ -0,0 +1,49 @@ +package io.avaje.http.api.context; + +import java.util.Optional; +import java.util.concurrent.Callable; +import java.util.function.Supplier; + +/** + * The holder for the current request context that is bound to instrumented threads. Allowing lookup + * of the current request if it is present. The Default implementation uses ThreadLocal. If you are + * able, you should provide an implementation using ScopedValues. + */ +public interface RequestContextResolver { + + /** + * Wraps the execution of the given callable in request context processing. + * + * @param ctx The request context + * @param callable The callable + * @param The return type of the callable + * @return The return value of the callable + * @throws Exception if the callable throws an exception + */ + T callWith(ServerContext ctx, Callable callable) throws Exception; + + /** + * Wraps the execution of the given supplier in request context processing. + * + * @param ctx The request context + * @param supplier The supplier + * @param The return type of the supplier + * @return The return value of the supplier + */ + T supplyWith(ServerContext ctx, Supplier supplier); + + /** + * Wraps the execution of the given runnable in request context processing. + * + * @param ctx The request context + * @param runnable The runnable + */ + void runWith(ServerContext request, Runnable runnable); + + /** + * Retrieve the current server context. + * + * @return The request context if it is present + */ + Optional currentRequest(); +} diff --git a/http-api/src/main/java/io/avaje/http/api/context/ServerContext.java b/http-api/src/main/java/io/avaje/http/api/context/ServerContext.java new file mode 100644 index 000000000..c09f76f72 --- /dev/null +++ b/http-api/src/main/java/io/avaje/http/api/context/ServerContext.java @@ -0,0 +1,31 @@ +package io.avaje.http.api.context; + +/** Holder for the Server Request/Response Classes */ +public class ServerContext { + + private final Object request; + private final Object response; + + public ServerContext(Object req, Object res) { + request = req; + response = res; + } + + /** + * Retrieve the current server request. + * + * @return The request + */ + T request() { + return (T) request; + } + + /** + * Retrieve the current server response. + * + * @return The request + */ + T response() { + return (T) response; + } +} diff --git a/http-api/src/main/java/io/avaje/http/api/context/ThreadLocalRequestContextResolver.java b/http-api/src/main/java/io/avaje/http/api/context/ThreadLocalRequestContextResolver.java new file mode 100644 index 000000000..d042c1cd8 --- /dev/null +++ b/http-api/src/main/java/io/avaje/http/api/context/ThreadLocalRequestContextResolver.java @@ -0,0 +1,54 @@ +package io.avaje.http.api.context; + +import java.util.Optional; +import java.util.concurrent.Callable; +import java.util.function.Supplier; + +public final class ThreadLocalRequestContextResolver implements RequestContextResolver { + + private static final ThreadLocal REQUEST = new ThreadLocal<>(); + + @Override + public T callWith(ServerContext request, Callable callable) throws Exception { + throwIfSet(); + try { + REQUEST.set(request); + return callable.call(); + } finally { + REQUEST.remove(); + } + } + + @Override + public T supplyWith(ServerContext request, Supplier supplier) { + throwIfSet(); + try { + REQUEST.set(request); + return supplier.get(); + } finally { + REQUEST.remove(); + } + } + + @Override + public void runWith(ServerContext request, Runnable runnable) { + throwIfSet(); + try { + REQUEST.set(request); + runnable.run(); + } finally { + REQUEST.remove(); + } + } + + @Override + public Optional currentRequest() { + return Optional.ofNullable(REQUEST.get()); + } + + private void throwIfSet() { + if (REQUEST.get() != null) { + throw new IllegalStateException("Rebinding the ServerContext is not permitted"); + } + } +} diff --git a/http-api/src/main/java/io/avaje/http/api/spi/DefaultResolverProvider.java b/http-api/src/main/java/io/avaje/http/api/spi/DefaultResolverProvider.java new file mode 100644 index 000000000..e2c49ffb3 --- /dev/null +++ b/http-api/src/main/java/io/avaje/http/api/spi/DefaultResolverProvider.java @@ -0,0 +1,20 @@ +package io.avaje.http.api.spi; + +import io.avaje.http.api.context.RequestContextResolver; +import io.avaje.http.api.context.ThreadLocalRequestContextResolver; +import io.avaje.inject.BeanScopeBuilder; +import io.avaje.inject.spi.Plugin; + +/** Plugin for avaje inject that provides a default RequestContextResolver instance. */ +public final class DefaultResolverProvider implements Plugin { + + @Override + public Class[] provides() { + return new Class[] {RequestContextResolver.class}; + } + + @Override + public void apply(BeanScopeBuilder builder) { + builder.provideDefault(null, RequestContextResolver.class, ThreadLocalRequestContextResolver::new); + } +} diff --git a/http-api/src/main/java/module-info.java b/http-api/src/main/java/module-info.java index deb09ce9e..30ae62a71 100644 --- a/http-api/src/main/java/module-info.java +++ b/http-api/src/main/java/module-info.java @@ -1,5 +1,10 @@ module io.avaje.http.api { - exports io.avaje.http.api; + exports io.avaje.http.api; + exports io.avaje.http.api.context; + exports io.avaje.http.api.spi; + requires static io.avaje.inject; + + provides io.avaje.inject.spi.Plugin with io.avaje.http.api.spi.DefaultResolverProvider; } diff --git a/http-api/src/main/resources/META-INF/services/io.avaje.inject.spi.Plugin b/http-api/src/main/resources/META-INF/services/io.avaje.inject.spi.Plugin new file mode 100644 index 000000000..4d6993ea6 --- /dev/null +++ b/http-api/src/main/resources/META-INF/services/io.avaje.inject.spi.Plugin @@ -0,0 +1 @@ +io.avaje.http.api.spi.DefaultResolverProvider diff --git a/http-api/src/test/java/io/avaje/http/api/context/ThreadLocalRequestContextResolverTest.java b/http-api/src/test/java/io/avaje/http/api/context/ThreadLocalRequestContextResolverTest.java new file mode 100644 index 000000000..54383f458 --- /dev/null +++ b/http-api/src/test/java/io/avaje/http/api/context/ThreadLocalRequestContextResolverTest.java @@ -0,0 +1,94 @@ +package io.avaje.http.api.context; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatIllegalStateException; + +import java.util.concurrent.CompletableFuture; + +import org.junit.jupiter.api.Test; + +class ThreadLocalRequestContextResolverTest { + + RequestContextResolver resolver = new ThreadLocalRequestContextResolver(); + + @Test + void testCallWith() throws Exception { + + resolver.callWith( + new ServerContext("request", "response"), + () -> { + assertThat(resolver.currentRequest().isPresent()).isTrue(); + return 1234; + }); + + assertThat(resolver.currentRequest().isPresent()).isFalse(); + } + + @Test + void testCallWithRebind() throws Exception { + + assertThatIllegalStateException() + .isThrownBy( + () -> { + resolver.callWith( + new ServerContext("request", "response"), + () -> { + assertThat(resolver.currentRequest().isPresent()).isTrue(); + return resolver.callWith( + resolver.currentRequest().orElseThrow(), + () -> { + assertThat(resolver.currentRequest().isPresent()).isTrue(); + return 1234; + }); + }); + }); + + assertThat(resolver.currentRequest().isPresent()).isFalse(); + } + + @Test + void testFuture() throws Exception { + + resolver + .callWith( + new ServerContext("request", "response"), + () -> { + assertThat(resolver.currentRequest().isPresent()).isTrue(); + + return CompletableFuture.supplyAsync( + () -> { + assertThat(resolver.currentRequest().isPresent()).isFalse(); + + return "d"; + }); + }) + .join(); + + assertThat(resolver.currentRequest().isPresent()).isFalse(); + } + + @Test + void testSupplyWith() { + + resolver.supplyWith( + new ServerContext("request", "response"), + () -> { + assertThat(resolver.currentRequest().isPresent()).isTrue(); + return 1234; + }); + + assertThat(resolver.currentRequest().isPresent()).isFalse(); + } + + @Test + void testRunWith() throws Exception { + + resolver.runWith( + new ServerContext("request", "response"), + () -> { + assertThat(resolver.currentRequest().isPresent()).isTrue(); + }); + + assertThat(resolver.currentRequest().isPresent()).isFalse(); + } +} diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseControllerWriter.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseControllerWriter.java index 44ae01495..aa6479278 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseControllerWriter.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseControllerWriter.java @@ -5,6 +5,7 @@ import javax.tools.JavaFileObject; import java.io.IOException; import java.io.Writer; +import java.util.Map; /** * Common controller writer. @@ -18,6 +19,7 @@ public abstract class BaseControllerWriter { protected final String packageName; protected final boolean router; protected Append writer; + protected boolean instrumentContext; protected BaseControllerWriter(ControllerReader reader) throws IOException { this(reader, "$Route"); @@ -26,13 +28,18 @@ protected BaseControllerWriter(ControllerReader reader) throws IOException { protected BaseControllerWriter(ControllerReader reader, String suffix) throws IOException { this.reader = reader; this.router = "$Route".equals(suffix); - TypeElement origin = reader.beanType(); + final TypeElement origin = reader.beanType(); this.originName = origin.getQualifiedName().toString(); this.shortName = origin.getSimpleName().toString(); this.packageName = initPackageName(originName); this.fullName = packageName + "." + shortName + suffix; initWriter(); + this.instrumentContext = reader.methods().stream().anyMatch(MethodReader::instrumentContext); + if (instrumentContext) { + reader.addImportType("io.avaje.http.api.context.RequestContextResolver"); + reader.addImportType("io.avaje.http.api.context.ServerContext"); + } } protected boolean isRequestScoped() { @@ -40,7 +47,7 @@ protected boolean isRequestScoped() { } protected String initPackageName(String originName) { - int dp = originName.lastIndexOf('.'); + final int dp = originName.lastIndexOf('.'); return dp > -1 ? originName.substring(0, dp) : null; } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java index 9b1acd321..7e4e8be92 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java @@ -11,10 +11,9 @@ import javax.lang.model.element.Element; import javax.lang.model.element.TypeElement; -@SupportedOptions({"useJavax", "useSingleton"}) +@SupportedOptions({"useJavax", "useSingleton", "instrumentRequests"}) public abstract class BaseProcessor extends AbstractProcessor { - @Override public SourceVersion getSupportedSourceVersion() { return SourceVersion.latest(); diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java index 415ec17a7..1b71404ca 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java @@ -44,6 +44,7 @@ public final class ControllerReader { */ private boolean requestScope; private boolean docHidden; + private final boolean hasInstrument; public ControllerReader(TypeElement beanType) { this.beanType = beanType; @@ -56,6 +57,11 @@ public ControllerReader(TypeElement beanType) { this.hasValid = initHasValid(); this.producesPrism = initProduces(); this.apiResponses = buildApiResponses(); + hasInstrument = + instrumentAllWebMethods() + || findAnnotation(ControllerPrism::getOptionalOn) + .map(ControllerPrism::instrumentRequestContext) + .orElse(false); } private List buildApiResponses() { @@ -299,7 +305,7 @@ public void addImportType(String rawType) { } public void addImportTypes(Set types) { - for (String type : types) { + for (final String type : types) { addImportType(type); } } @@ -315,4 +321,8 @@ public Set staticImportTypes() { public Set importTypes() { return importTypes; } + + public boolean hasInstrument() { + return hasInstrument; + } } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java index b3555b23a..4f40e1c39 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java @@ -58,7 +58,7 @@ private static void addJsonBodyType(MethodReader methodReader, Consumer a } public static void writeJsonbType(UType type, Append writer) { - writer.append(" this.%sJsonType = jsonB.type(", type.shortName()); + writer.append(" this.%sJsonType = jsonb.type(", type.shortName()); if (!type.isGeneric()) { writer.append("%s.class)", Util.shortName(PrimitiveUtil.wrap(type.full()))); } else { diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java index 6812f3521..f1a67043f 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java @@ -51,6 +51,8 @@ public class MethodReader { private WebMethod webMethod; private String webMethodPath; private boolean formMarker; + private final boolean instrumentContext; + private final boolean hasThrows; MethodReader(ControllerReader bean, ExecutableElement element, ExecutableType actualExecutable) { this.bean = bean; @@ -71,7 +73,7 @@ public class MethodReader { this.superMethods = superMethods(element.getEnclosingElement(), element.getSimpleName().toString()); superMethods.forEach(m -> methodRoles.addAll(Util.findRoles(m))); - + this.hasThrows = !element.getThrownTypes().isEmpty(); this.securityRequirements = readSecurityRequirements(); this.apiResponses = buildApiResponses(); this.javadoc = buildJavadoc(element); @@ -83,11 +85,29 @@ public class MethodReader { }); if (isWebMethod()) { this.hasValid = initValid(); + this.instrumentContext = initResolver(); this.pathSegments = PathSegments.parse(Util.combinePath(bean.path(), webMethodPath)); } else { this.hasValid = false; this.pathSegments = null; + this.instrumentContext = false; + } + } + + private boolean initResolver() { + return bean.hasInstrument() + || hasInstrument(element) + || superMethods.stream().anyMatch(this::hasInstrument); + } + + private boolean hasInstrument(Element e) { + for (final var a : e.getAnnotationMirrors()) { + if (HttpMethodPrism.isPresent(a.getAnnotationType().asElement())) { + + return a.getElementValues().values().stream().anyMatch(v -> v.getValue().equals(true)); + } } + return false; } private Javadoc buildJavadoc(ExecutableElement element) { @@ -373,7 +393,7 @@ public boolean isFormBody() { } public String bodyType() { - for (MethodParam param : params) { + for (final MethodParam param : params) { if (param.isBody()) { return param.shortType(); } @@ -382,7 +402,7 @@ public String bodyType() { } public String bodyName() { - for (MethodParam param : params) { + for (final MethodParam param : params) { if (param.isBody()) { return param.name(); } @@ -393,4 +413,26 @@ public String bodyName() { public Optional timeout() { return timeout; } + + public boolean instrumentContext() { + return instrumentContext; + } + + public void writeContext(Append writer, String reqName,String resName) { + + if (isVoid) { + + writer.append("resolver.runWith"); + + } else if (hasThrows) { + + writer.append("resolver.callWith"); + + } else { + + writer.append("resolver.supplyWith"); + } + + writer.append("(new ServerContext(%s, %s), () -> ", reqName, resName); + } } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java index 46b22802a..e778d0cff 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java @@ -40,6 +40,7 @@ private static final class Ctx { private final boolean useComponent; private final boolean useJavax; private final String diAnnotation; + private final boolean instrumentAllMethods; Ctx(ProcessingEnvironment env, PlatformAdapter adapter, boolean generateOpenAPI) { readAdapter = adapter; @@ -55,6 +56,7 @@ private static final class Ctx { final var options = env.getOptions(); final var singletonOverride = options.get("useSingleton"); + this.instrumentAllMethods = Boolean.parseBoolean(options.get("instrumentRequests")); if (singletonOverride != null) { useComponent = !Boolean.parseBoolean(singletonOverride); } else { @@ -64,7 +66,7 @@ private static final class Ctx { final var javax = elementUtils.getTypeElement(Constants.SINGLETON_JAVAX) != null; final var jakarta = elementUtils.getTypeElement(Constants.SINGLETON_JAKARTA) != null; - final var override = env.getOptions().get("useJavax"); + final var override = options.get("useJavax"); if (override != null || (javax && jakarta)) { useJavax = Boolean.parseBoolean(override); } else { @@ -162,4 +164,8 @@ public static void setPlatform(PlatformAdapter platform) { public static String diAnnotation() { return CTX.get().diAnnotation; } + + public static boolean instrumentAllWebMethods() { + return CTX.get().instrumentAllMethods; + } } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/package-info.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/package-info.java index 3dd017405..c41bf74f7 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/package-info.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/package-info.java @@ -12,6 +12,7 @@ @GeneratePrism(value = io.avaje.http.api.FormParam.class, publicAccess = true) @GeneratePrism(value = io.avaje.http.api.Get.class, publicAccess = true) @GeneratePrism(value = io.avaje.http.api.Header.class, publicAccess = true) +@GeneratePrism(value = io.avaje.http.api.HttpMethod.class, publicAccess = true) @GeneratePrism(value = io.avaje.http.api.MatrixParam.class, publicAccess = true) @GeneratePrism(value = io.avaje.http.api.Patch.class, publicAccess = true) @GeneratePrism(value = io.avaje.http.api.Path.class, publicAccess = true) diff --git a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/ControllerMethodWriter.java b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/ControllerMethodWriter.java index 4d0a75d2f..349a2a8c5 100644 --- a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/ControllerMethodWriter.java +++ b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/ControllerMethodWriter.java @@ -1,6 +1,7 @@ package io.avaje.http.generator.helidon; import static io.avaje.http.generator.core.ProcessingContext.platform; + import java.util.List; import io.avaje.http.generator.core.Append; @@ -18,11 +19,13 @@ class ControllerMethodWriter { private final MethodReader method; private final Append writer; private final WebMethod webMethod; + private final boolean instrumentContext; ControllerMethodWriter(MethodReader method, Append writer) { this.method = method; this.writer = writer; this.webMethod = method.webMethod(); + this.instrumentContext = method.instrumentContext(); } void writeRule() { @@ -57,19 +60,26 @@ void writeHandler(boolean requestScoped) { } final List params = method.params(); - for (MethodParam param : params) { + for (final MethodParam param : params) { param.writeCtxGet(writer, segments); } + + if (method.includeValidate()) { + for (final MethodParam param : params) { + writer.append(" "); + param.writeValidate(writer); + } + } + writer.append(" "); if (!method.isVoid()) { writer.append("res.send("); } - if (method.includeValidate()) { - for (MethodParam param : params) { - param.writeValidate(writer); - } + if (instrumentContext) { + method.writeContext(writer, "req", "res"); } + if (requestScoped) { writer.append("factory.create(req, res)."); } else { @@ -86,6 +96,9 @@ void writeHandler(boolean requestScoped) { if (!method.isVoid()) { writer.append(")"); } + if (instrumentContext) { + writer.append(")"); + } writer.append(";").eol(); writer.append(" }").eol().eol(); } diff --git a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/ControllerWriter.java b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/ControllerWriter.java index b052ab278..78e680ddc 100644 --- a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/ControllerWriter.java +++ b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/ControllerWriter.java @@ -74,17 +74,28 @@ private void writeClassStart() { if (reader.isIncludeValidator()) { writer.append(" private final Validator validator;").eol(); } + if (instrumentContext) { + writer.append(" private final RequestContextResolver resolver;").eol(); + } writer.eol(); writer.append(" public %s$Route(%s %s", shortName, controllerType, controllerName); if (reader.isIncludeValidator()) { writer.append(", Validator validator"); } + + if (instrumentContext) { + writer.append(", RequestContextResolver resolver").eol(); + } + writer.append(") {").eol(); writer.append(" this.%s = %s;", controllerName, controllerName).eol(); if (reader.isIncludeValidator()) { writer.append(" this.validator = validator;").eol(); } + if (instrumentContext) { + writer.append(" this.resolver = resolver;").eol(); + } writer.append(" }").eol().eol(); } diff --git a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java index 1ee63cffa..0d7852c43 100644 --- a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java +++ b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java @@ -1,6 +1,7 @@ package io.avaje.http.generator.javalin; import static io.avaje.http.generator.core.ProcessingContext.platform; + import io.avaje.http.generator.core.Append; import io.avaje.http.generator.core.MethodParam; import io.avaje.http.generator.core.MethodReader; @@ -19,12 +20,14 @@ class ControllerMethodWriter { private final Append writer; private final WebMethod webMethod; private final boolean useJsonB; + private final boolean instrumentContext; ControllerMethodWriter(MethodReader method, Append writer, boolean useJsonB) { this.method = method; this.writer = writer; this.webMethod = method.webMethod(); this.useJsonB = useJsonB; + this.instrumentContext = method.instrumentContext(); } void write(boolean requestScoped) { @@ -55,6 +58,10 @@ void write(boolean requestScoped) { writer.append("var result = "); } + if (instrumentContext) { + method.writeContext(writer, "ctx", "ctx"); + } + if (requestScoped) { writer.append("factory.create(ctx)."); } else { @@ -68,7 +75,13 @@ void write(boolean requestScoped) { params.get(i).buildParamName(writer); } + if (instrumentContext) { + + writer.append(")"); + } + writer.append(");").eol(); + if (!method.isVoid()) { writeContextReturn(); writer.eol(); @@ -92,7 +105,7 @@ void write(boolean requestScoped) { private void writeContextReturn() { // Support for CompletableFuture's. final UType type = UType.parse(method.returnType()); - if (type.mainType().equals("java.util.concurrent.CompletableFuture")) { + if ("java.util.concurrent.CompletableFuture".equals(type.mainType())) { if (!type.isGeneric()) { throw new IllegalStateException("CompletableFuture must be generic type (e.g. CompletableFuture, CompletableFuture)."); } @@ -117,7 +130,7 @@ private void writeContextReturn(final String resultVariableName) { if (produces == null || MediaType.APPLICATION_JSON.getValue().equalsIgnoreCase(produces)) { if (useJsonB) { var uType = UType.parse(method.returnType()); - if (uType.mainType().equals("java.util.concurrent.CompletableFuture")) { + if ("java.util.concurrent.CompletableFuture".equals(uType.mainType())) { uType = uType.paramRaw(); } diff --git a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java index 5325f426c..a88ccbef5 100644 --- a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java +++ b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java @@ -1,6 +1,7 @@ package io.avaje.http.generator.javalin; import static io.avaje.http.generator.core.ProcessingContext.diAnnotation; + import java.io.IOException; import java.util.Map; @@ -22,9 +23,10 @@ class ControllerWriter extends BaseControllerWriter { private final boolean useJsonB; private final Map jsonTypes; - ControllerWriter(ControllerReader reader, boolean jsonB) throws IOException { + ControllerWriter(ControllerReader reader, boolean jsonb) throws IOException { super(reader); - this.useJsonB = jsonB; + this.useJsonB = jsonb; + if (useJsonB) { reader.addImportType("io.avaje.jsonb.Jsonb"); reader.addImportType("io.avaje.jsonb.JsonType"); @@ -87,7 +89,11 @@ private void writeClassStart() { writer.append(" private final Validator validator;").eol(); } - for (UType type : jsonTypes.values()) { + if (instrumentContext) { + writer.append(" private final RequestContextResolver resolver;").eol(); + } + + for (final UType type : jsonTypes.values()) { final var typeString = PrimitiveUtil.wrap(type.shortType()).replace(",", ", "); writer.append(" private final JsonType<%s> %sJsonType;", typeString, type.shortName()).eol(); } @@ -98,15 +104,21 @@ private void writeClassStart() { writer.append(", Validator validator"); } if (useJsonB) { - writer.append(", Jsonb jsonB"); + writer.append(", Jsonb jsonb"); + } + if (instrumentContext) { + writer.append(", RequestContextResolver resolver"); } writer.append(") {").eol(); writer.append(" this.%s = %s;", controllerName, controllerName).eol(); if (reader.isIncludeValidator()) { writer.append(" this.validator = validator;").eol(); } + if (instrumentContext) { + writer.append(" this.resolver = resolver;").eol(); + } if (useJsonB) { - for (UType type : jsonTypes.values()) { + for (final UType type : jsonTypes.values()) { JsonBUtil.writeJsonbType(type, writer); } } diff --git a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java index b5a548300..0fddbf324 100644 --- a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java +++ b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java @@ -19,11 +19,13 @@ class ControllerMethodWriter { private final MethodReader method; private final Append writer; private final WebMethod webMethod; + private boolean instrumentContext; ControllerMethodWriter(MethodReader method, Append writer) { this.method = method; this.writer = writer; this.webMethod = method.webMethod(); + this.instrumentContext = method.instrumentContext(); } void write(boolean requestScoped) { @@ -52,7 +54,9 @@ void write(boolean requestScoped) { if (!method.isVoid()) { writeContextReturn(); } - + if (instrumentContext) { + method.writeContext(writer, "ctx", "ctx"); + } if (requestScoped) { writer.append("factory.create(ctx)."); } else { @@ -69,6 +73,9 @@ void write(boolean requestScoped) { if (!method.isVoid()) { writer.append(")"); } + if (instrumentContext) { + writer.append(")"); + } writer.append(";").eol(); writer.append(" }"); diff --git a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerWriter.java b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerWriter.java index c3faeb3a0..5f8bcad00 100644 --- a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerWriter.java +++ b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerWriter.java @@ -62,17 +62,28 @@ private void writeClassStart() { if (reader.isIncludeValidator()) { writer.append(" private final Validator validator;").eol(); } + + if (instrumentContext) { + writer.append(" private final RequestContextResolver resolver;").eol(); + } + writer.eol(); writer.append(" public %s$Route(%s %s", shortName, controllerType, controllerName); if (reader.isIncludeValidator()) { writer.append(", Validator validator"); } + if (instrumentContext) { + writer.append(", RequestContextResolver resolver"); + } writer.append(") {").eol(); writer.append(" this.%s = %s;", controllerName, controllerName).eol(); if (reader.isIncludeValidator()) { writer.append(" this.validator = validator;").eol(); } + if (instrumentContext) { + writer.append(" this.resolver = resolver;").eol(); + } writer.append(" }").eol().eol(); } diff --git a/http-generator-nima/pom.xml b/http-generator-nima/pom.xml index feb21a048..6a5d9424f 100644 --- a/http-generator-nima/pom.xml +++ b/http-generator-nima/pom.xml @@ -33,8 +33,8 @@ maven-compiler-plugin 3.10.1 - 19 - 19 + 20 + 20 -proc:none diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java index 8d80988d0..6a20eb7aa 100644 --- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java +++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java @@ -23,12 +23,14 @@ class ControllerMethodWriter { private final Append writer; private final WebMethod webMethod; private final boolean useJsonB; + private final boolean instrumentContext; ControllerMethodWriter(MethodReader method, Append writer, boolean useJsonB) { this.method = method; this.writer = writer; this.webMethod = method.webMethod(); this.useJsonB = useJsonB; + this.instrumentContext = method.instrumentContext(); } void writeRule() { @@ -89,6 +91,14 @@ void writeHandler(boolean requestScoped) { for (final MethodParam param : params) { param.writeCtxGet(writer, segments); } + + if (method.includeValidate()) { + for (final MethodParam param : params) { + writer.append(" "); + param.writeValidate(writer); + } + } + writer.append(" "); if (!method.isVoid()) { writer.append("var result = "); @@ -96,11 +106,10 @@ void writeHandler(boolean requestScoped) { throw new IllegalStateException("Void controller methods must have a ServerResponse parameter"); } - if (method.includeValidate()) { - for (final MethodParam param : params) { - param.writeValidate(writer); - } + if (instrumentContext) { + method.writeContext(writer, "req", "res"); } + if (requestScoped) { writer.append("factory.create(req, res)."); } else { @@ -113,6 +122,9 @@ void writeHandler(boolean requestScoped) { } params.get(i).buildParamName(writer); } + if (instrumentContext) { + writer.append(")"); + } writer.append(");").eol(); if (!method.isVoid()) { writeContextReturn(); diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java index 38f811ff0..9d0b32794 100644 --- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java +++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java @@ -1,12 +1,19 @@ package io.avaje.http.generator.helidon.nima; import static io.avaje.http.generator.core.ProcessingContext.diAnnotation; -import io.avaje.http.generator.core.*; import java.io.IOException; import java.util.List; import java.util.Map; +import io.avaje.http.generator.core.BaseControllerWriter; +import io.avaje.http.generator.core.Constants; +import io.avaje.http.generator.core.ControllerReader; +import io.avaje.http.generator.core.JsonBUtil; +import io.avaje.http.generator.core.MethodReader; +import io.avaje.http.generator.core.PrimitiveUtil; +import io.avaje.http.generator.core.UType; + /** * Write Helidon specific web route adapter (a Helidon Service). */ @@ -16,9 +23,9 @@ class ControllerWriter extends BaseControllerWriter { private final boolean useJsonB; private final Map jsonTypes; - ControllerWriter(ControllerReader reader, boolean jsonB) throws IOException { + ControllerWriter(ControllerReader reader, boolean jsonb) throws IOException { super(reader); - this.useJsonB = jsonB; + this.useJsonB = jsonb; if (useJsonB) { reader.addImportType("io.avaje.jsonb.Jsonb"); reader.addImportType("io.avaje.jsonb.JsonType"); @@ -92,6 +99,11 @@ private void writeClassStart() { if (reader.isIncludeValidator()) { writer.append(" private final Validator validator;").eol(); } + + if (instrumentContext) { + writer.append(" private final RequestContextResolver resolver;").eol(); + } + for (final UType type : jsonTypes.values()) { final var typeString = PrimitiveUtil.wrap(type.shortType()).replace(",", ", "); writer.append(" private final JsonType<%s> %sJsonType;", typeString, type.shortName()).eol(); @@ -103,13 +115,21 @@ private void writeClassStart() { writer.append(", Validator validator"); } if (useJsonB) { - writer.append(", Jsonb jsonB"); + writer.append(", Jsonb jsonb"); } + if (instrumentContext) { + writer.append(", RequestContextResolver resolver"); + } + writer.append(") {").eol(); writer.append(" this.%s = %s;", controllerName, controllerName).eol(); if (reader.isIncludeValidator()) { writer.append(" this.validator = validator;").eol(); } + if (instrumentContext) { + writer.append(" this.resolver = resolver;").eol(); + } + if (useJsonB) { for (final UType type : jsonTypes.values()) { JsonBUtil.writeJsonbType(type, writer); diff --git a/tests/test-helidon/pom.xml b/tests/test-helidon/pom.xml index 8b360d0bb..b3bce206f 100644 --- a/tests/test-helidon/pom.xml +++ b/tests/test-helidon/pom.xml @@ -138,6 +138,19 @@ + + io.avaje + avaje-inject-maven-plugin + 1.0 + + + process-sources + + provides + + + + diff --git a/tests/test-helidon/src/main/java/org/example/ReqScopedController.java b/tests/test-helidon/src/main/java/org/example/ReqScopedController.java index 2ae951ef4..ec5c2b37e 100644 --- a/tests/test-helidon/src/main/java/org/example/ReqScopedController.java +++ b/tests/test-helidon/src/main/java/org/example/ReqScopedController.java @@ -6,10 +6,9 @@ import io.avaje.http.api.Produces; import io.helidon.webserver.ServerRequest; import io.helidon.webserver.ServerResponse; - import jakarta.inject.Inject; -@Controller +@Controller(instrumentRequestContext = true) @Path("/req-scoped") public class ReqScopedController { diff --git a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController2.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController2.java index 7268ea18d..e24bed13f 100644 --- a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController2.java +++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController2.java @@ -6,8 +6,8 @@ import org.example.myapp.web.ServerType; -import io.avaje.http.api.Consumes; import io.avaje.http.api.BodyString; +import io.avaje.http.api.Consumes; import io.avaje.http.api.Controller; import io.avaje.http.api.Default; import io.avaje.http.api.Form; @@ -16,19 +16,20 @@ import io.avaje.http.api.Path; import io.avaje.http.api.Post; import io.avaje.http.api.QueryParam; +import io.javalin.http.Context; @Path("test/") @Controller public class TestController2 { @Form - @Get("/enumForm") - String enumForm(String s, ServerType type) { - return type.name(); + @Get(value = "/enumForm", instrumentRequestContext = true) + void enumForm(String s, ServerType type, Context ctx) { + ctx.result(s); } - @Get("/enumFormParam") - String enumFormParam(@FormParam String s, @FormParam ServerType type) { + @Get(value = "/enumFormParam", instrumentRequestContext = true) + String enumFormParam(@FormParam String s, @FormParam ServerType type) throws Exception { return type.name(); } @@ -58,7 +59,7 @@ String bytes(byte[] array) { return array.toString(); } - @Post("/strBody") + @Post(value = "/strBody", instrumentRequestContext = true) String strBody(@BodyString String body) { return body; } diff --git a/tests/test-javalin/src/main/java/org/example/myapp/web/BarInterface.java b/tests/test-javalin/src/main/java/org/example/myapp/web/BarInterface.java index 4572236ae..7aae1aba8 100644 --- a/tests/test-javalin/src/main/java/org/example/myapp/web/BarInterface.java +++ b/tests/test-javalin/src/main/java/org/example/myapp/web/BarInterface.java @@ -20,6 +20,6 @@ public interface BarInterface { List findByCode(String code); @Produces(MediaType.TEXT_PLAIN) - @Get + @Get(instrumentRequestContext = true) String barMessage(); } diff --git a/tests/test-jex/src/main/java/org/example/web/TestController.java b/tests/test-jex/src/main/java/org/example/web/TestController.java index 9d995faad..1afed2f56 100644 --- a/tests/test-jex/src/main/java/org/example/web/TestController.java +++ b/tests/test-jex/src/main/java/org/example/web/TestController.java @@ -12,7 +12,7 @@ import io.avaje.jex.Context; @Path("test/") -@Controller +@Controller(instrumentRequestContext = true) public class TestController { @Get("/paramMulti") diff --git a/tests/test-nima-jsonb/.classpath b/tests/test-nima-jsonb/.classpath index aeb867648..cb7d8e80b 100644 --- a/tests/test-nima-jsonb/.classpath +++ b/tests/test-nima-jsonb/.classpath @@ -26,17 +26,11 @@ - - - - - - diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 9b12359f5..6c8eae5a3 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -7,96 +7,114 @@ 1.36-SNAPSHOT - test-nima-jsonb + test-nima-jsonb - - 19 - 19 - 19 - UTF-8 - + + 20 + 20 + 20 + UTF-8 + - - - io.avaje - avaje-inject - ${avaje-inject.version} - - - io.avaje - avaje-http-api - ${project.version} - - - io.avaje - avaje-jsonb - 1.4 - - - io.helidon.nima.webserver - helidon-nima-webserver - 4.0.0-ALPHA5 - - - io.helidon.nima.http.media - helidon-nima-http-media-jsonb - 4.0.0-ALPHA5 - - - io.avaje - avaje-http-nima-generator - ${project.version} - test - + + + io.avaje + avaje-inject + ${avaje-inject.version} + + + io.avaje + avaje-http-api + ${project.version} + + + io.avaje + avaje-jsonb + 1.4 + + + io.avaje + avaje-http-hibernate-validator + 3.2 + + + io.helidon.nima.webserver + helidon-nima-webserver + 4.0.0-ALPHA6 + + + io.helidon.nima.http.media + helidon-nima-http-media-jsonb + 4.0.0-ALPHA6 + + + io.avaje + avaje-http-nima-generator + ${project.version} + test + io.avaje junit 1.1 test - + - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.10.1 - - 19 - - - io.avaje - avaje-http-nima-generator - ${project.version} - - - io.avaje - avaje-inject-generator - ${avaje-inject.version} - - - io.avaje - avaje-jsonb-generator - 1.4 - - - - - - io.repaint.maven - tiles-maven-plugin - 2.22 - true - - - org.avaje.tile:lib-classpath:1.1 - - - - - + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.10.1 + + 20 + + + io.avaje + avaje-http-nima-generator + ${project.version} + + + io.avaje + avaje-inject-generator + ${avaje-inject.version} + + + io.avaje + avaje-jsonb-generator + 1.4 + + + + + + io.repaint.maven + tiles-maven-plugin + 2.22 + true + + + org.avaje.tile:lib-classpath:1.1 + + + + + io.avaje + avaje-inject-maven-plugin + 1.0 + + + process-sources + + provides + + + + + + diff --git a/tests/test-nima-jsonb/src/main/java/org/example/HelloController.java b/tests/test-nima-jsonb/src/main/java/org/example/HelloController.java index 2c9738d26..5d03d262a 100644 --- a/tests/test-nima-jsonb/src/main/java/org/example/HelloController.java +++ b/tests/test-nima-jsonb/src/main/java/org/example/HelloController.java @@ -13,6 +13,7 @@ import io.avaje.http.api.Produces; import io.avaje.http.api.Put; import io.avaje.http.api.QueryParam; +import io.avaje.http.api.Valid; import io.helidon.common.http.HttpMediaType; import io.helidon.nima.webserver.http.ServerRequest; import io.helidon.nima.webserver.http.ServerResponse; @@ -129,6 +130,7 @@ String form(String name, String email, String url) { // -d "name=FormBeanJimmy&email=jim@foo&url=notaurl" @Form @Post("formBean") + @Valid String formBean(MyForm form) { return form.name + "|" + form.email + "|" + form.url; } diff --git a/tests/test-nima-jsonb/src/main/java/org/example/MyForm.java b/tests/test-nima-jsonb/src/main/java/org/example/MyForm.java index 3c3a75138..012ba61ae 100644 --- a/tests/test-nima-jsonb/src/main/java/org/example/MyForm.java +++ b/tests/test-nima-jsonb/src/main/java/org/example/MyForm.java @@ -1,5 +1,8 @@ package org.example; +import io.avaje.http.api.Valid; + +@Valid public class MyForm { public String name; diff --git a/tests/test-nima-jsonb/src/main/java/org/example/TestController.java b/tests/test-nima-jsonb/src/main/java/org/example/TestController.java index 2d26227cb..682cdf3cc 100644 --- a/tests/test-nima-jsonb/src/main/java/org/example/TestController.java +++ b/tests/test-nima-jsonb/src/main/java/org/example/TestController.java @@ -54,11 +54,12 @@ String enumQueryImplied(String s, @QueryParam ServerType type) { return type.name(); } - @Get("/inputStream") + @Get(value = "/inputStream", instrumentRequestContext = true) String stream(InputStream stream) { return stream.toString(); } + @Post("/strBody") String strBody(@BodyString String body) { return body; diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index d4715b237..f64b50ee3 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -12,8 +12,8 @@ test-nima - 19 - 19 + 20 + 20 UTF-8 @@ -32,12 +32,12 @@ io.helidon.nima.webserver helidon-nima-webserver - 4.0.0-ALPHA4 + 4.0.0-ALPHA6 io.helidon.nima.http.media helidon-nima-http-media-jsonb - 4.0.0-ALPHA4 + 4.0.0-ALPHA6 @@ -59,7 +59,7 @@ maven-compiler-plugin 3.10.1 - 19 + 20 io.avaje From ec4f84dcc05acef280d6bc6dcdc6e8151d6f5cb6 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 18 Apr 2023 21:12:22 +1200 Subject: [PATCH 0731/1323] Format only changes --- .../api/context/RequestContextResolver.java | 12 +++++----- .../avaje/http/api/context/ServerContext.java | 14 +++++++---- .../http/generator/core/MethodReader.java | 23 +++---------------- .../javalin/ControllerMethodWriter.java | 4 ---- .../generator/jex/ControllerMethodWriter.java | 1 - .../src/main/resources/public/openapi.json | 9 +------- 6 files changed, 19 insertions(+), 44 deletions(-) diff --git a/http-api/src/main/java/io/avaje/http/api/context/RequestContextResolver.java b/http-api/src/main/java/io/avaje/http/api/context/RequestContextResolver.java index a85d72bc1..2acac68eb 100644 --- a/http-api/src/main/java/io/avaje/http/api/context/RequestContextResolver.java +++ b/http-api/src/main/java/io/avaje/http/api/context/RequestContextResolver.java @@ -14,9 +14,9 @@ public interface RequestContextResolver { /** * Wraps the execution of the given callable in request context processing. * - * @param ctx The request context + * @param ctx The request context * @param callable The callable - * @param The return type of the callable + * @param The return type of the callable * @return The return value of the callable * @throws Exception if the callable throws an exception */ @@ -25,9 +25,9 @@ public interface RequestContextResolver { /** * Wraps the execution of the given supplier in request context processing. * - * @param ctx The request context + * @param ctx The request context * @param supplier The supplier - * @param The return type of the supplier + * @param The return type of the supplier * @return The return value of the supplier */ T supplyWith(ServerContext ctx, Supplier supplier); @@ -35,10 +35,10 @@ public interface RequestContextResolver { /** * Wraps the execution of the given runnable in request context processing. * - * @param ctx The request context + * @param ctx The request context * @param runnable The runnable */ - void runWith(ServerContext request, Runnable runnable); + void runWith(ServerContext ctx, Runnable runnable); /** * Retrieve the current server context. diff --git a/http-api/src/main/java/io/avaje/http/api/context/ServerContext.java b/http-api/src/main/java/io/avaje/http/api/context/ServerContext.java index c09f76f72..2d9bf98ef 100644 --- a/http-api/src/main/java/io/avaje/http/api/context/ServerContext.java +++ b/http-api/src/main/java/io/avaje/http/api/context/ServerContext.java @@ -1,14 +1,16 @@ package io.avaje.http.api.context; -/** Holder for the Server Request/Response Classes */ -public class ServerContext { +/** + * Holder for the Server Request/Response instances. + */ +public final class ServerContext { private final Object request; private final Object response; - public ServerContext(Object req, Object res) { - request = req; - response = res; + public ServerContext(Object request, Object response) { + this.request = request; + this.response = response; } /** @@ -16,6 +18,7 @@ public ServerContext(Object req, Object res) { * * @return The request */ + @SuppressWarnings("unchecked") T request() { return (T) request; } @@ -25,6 +28,7 @@ T request() { * * @return The request */ + @SuppressWarnings("unchecked") T response() { return (T) response; } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java index f1a67043f..7b3434cc8 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java @@ -70,8 +70,7 @@ public class MethodReader { initWebMethodViaAnnotation(); - this.superMethods = - superMethods(element.getEnclosingElement(), element.getSimpleName().toString()); + this.superMethods = superMethods(element.getEnclosingElement(), element.getSimpleName().toString()); superMethods.forEach(m -> methodRoles.addAll(Util.findRoles(m))); this.hasThrows = !element.getThrownTypes().isEmpty(); this.securityRequirements = readSecurityRequirements(); @@ -103,7 +102,6 @@ private boolean initResolver() { private boolean hasInstrument(Element e) { for (final var a : e.getAnnotationMirrors()) { if (HttpMethodPrism.isPresent(a.getAnnotationType().asElement())) { - return a.getElementValues().values().stream().anyMatch(v -> v.getValue().equals(true)); } } @@ -143,7 +141,6 @@ public String toString() { } private void initWebMethodViaAnnotation() { - if (findAnnotation(FormPrism::getOptionalOn).isPresent()) { this.formMarker = true; } @@ -207,7 +204,6 @@ private void readSecurityRequirements(Element element, List buildApiResponses() { - final var container = findAnnotation(OpenAPIResponsesPrism::getOptionalOn).stream() .map(OpenAPIResponsesPrism::value) @@ -226,11 +222,8 @@ private List buildApiResponses() { .flatMap(List::stream), OpenAPIResponsePrism.getAllInstancesOn(method).stream())); - final var responses = - Stream.concat(methodResponses, superMethodResponses).collect(Collectors.toList()); - + final var responses = Stream.concat(methodResponses, superMethodResponses).collect(Collectors.toList()); responses.addAll(bean.openApiResponses()); - return responses; } @@ -239,7 +232,6 @@ public Optional findAnnotation(Function> prismFunc) } public Optional findAnnotation(Function> prismFunc, ExecutableElement elem) { - return prismFunc.apply(elem).or(() -> bean.findMethodAnnotation(prismFunc, elem)); } @@ -249,9 +241,7 @@ private List addTagsToList(Element element, List list) { } TagPrism.getAllInstancesOn(element).forEach(t -> list.add(t.name())); - final var tags = TagsPrism.getInstanceOn(element); - if (tags != null) { for (final var tag : tags.value()) { list.add(tag.name()); @@ -418,21 +408,14 @@ public boolean instrumentContext() { return instrumentContext; } - public void writeContext(Append writer, String reqName,String resName) { - + public void writeContext(Append writer, String reqName, String resName) { if (isVoid) { - writer.append("resolver.runWith"); - } else if (hasThrows) { - writer.append("resolver.callWith"); - } else { - writer.append("resolver.supplyWith"); } - writer.append("(new ServerContext(%s, %s), () -> ", reqName, resName); } } diff --git a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java index 0d7852c43..14590c0fa 100644 --- a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java +++ b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java @@ -31,7 +31,6 @@ class ControllerMethodWriter { } void write(boolean requestScoped) { - final var segments = method.pathSegments(); final var fullPath = segments.fullPath(); @@ -76,12 +75,10 @@ void write(boolean requestScoped) { } if (instrumentContext) { - writer.append(")"); } writer.append(");").eol(); - if (!method.isVoid()) { writeContextReturn(); writer.eol(); @@ -133,7 +130,6 @@ private void writeContextReturn(final String resultVariableName) { if ("java.util.concurrent.CompletableFuture".equals(uType.mainType())) { uType = uType.paramRaw(); } - writer.append(" %sJsonType.toJson(%s, ctx.contentType(\"application/json\").outputStream());", uType.shortName(), resultVariableName); } else { writer.append(" ctx.json(%s);", resultVariableName); diff --git a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java index 0fddbf324..f73c42e24 100644 --- a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java +++ b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java @@ -29,7 +29,6 @@ class ControllerMethodWriter { } void write(boolean requestScoped) { - final PathSegments segments = method.pathSegments(); final String fullPath = segments.fullPath(); diff --git a/tests/test-javalin-jsonb/src/main/resources/public/openapi.json b/tests/test-javalin-jsonb/src/main/resources/public/openapi.json index 2fb2fd819..913874880 100644 --- a/tests/test-javalin-jsonb/src/main/resources/public/openapi.json +++ b/tests/test-javalin-jsonb/src/main/resources/public/openapi.json @@ -1245,14 +1245,7 @@ }, "responses" : { "200" : { - "description" : "", - "content" : { - "application/json" : { - "schema" : { - "type" : "string" - } - } - } + "description" : "No content" } } } From 243bf2250ea63881b0114a9d381e0f6e24943b8a Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 18 Apr 2023 21:19:18 +1200 Subject: [PATCH 0732/1323] Version 1.36 --- .gitignore | 1 + http-api/pom.xml | 2 +- http-client-gson-adapter/pom.xml | 4 ++-- http-client/pom.xml | 2 +- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 2 +- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-generator-nima/pom.xml | 2 +- pom.xml | 2 +- tests/pom.xml | 2 +- tests/test-client-generation/pom.xml | 2 +- tests/test-client/pom.xml | 2 +- tests/test-helidon/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- 20 files changed, 21 insertions(+), 20 deletions(-) diff --git a/.gitignore b/.gitignore index ba8980bcf..387d29edc 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,4 @@ build/ *.editorconfig *.Module dependency-reduced-pom.xml +.DS_Store diff --git a/http-api/pom.xml b/http-api/pom.xml index 9330dcb2f..fad7a0351 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.36-SNAPSHOT + 1.36 .. diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index 6bce8c6bb..247bc7910 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.36-SNAPSHOT + 1.36 avaje-http-client-gson @@ -20,7 +20,7 @@ io.avaje avaje-http-client - 1.36-SNAPSHOT + 1.36 provided diff --git a/http-client/pom.xml b/http-client/pom.xml index d205698ab..b08320af6 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.36-SNAPSHOT + 1.36 avaje-http-client diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index a5b908269..94ef678b8 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.36-SNAPSHOT + 1.36 avaje-http-client-generator diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index cc83b9349..d843aed4b 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.36-SNAPSHOT + 1.36 avaje-http-generator-core diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index 5d1155593..d386108cd 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.36-SNAPSHOT + 1.36 avaje-http-helidon-generator diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index f09c70216..e9f4d1751 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.36-SNAPSHOT + 1.36 avaje-http-javalin-generator diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index 96777a2fe..ff17da38b 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.36-SNAPSHOT + 1.36 avaje-http-jex-generator diff --git a/http-generator-nima/pom.xml b/http-generator-nima/pom.xml index 6a5d9424f..5d8ad9085 100644 --- a/http-generator-nima/pom.xml +++ b/http-generator-nima/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 1.36-SNAPSHOT + 1.36 avaje-http-nima-generator diff --git a/pom.xml b/pom.xml index 6438be347..9df02a8c9 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-parent - 1.36-SNAPSHOT + 1.36 pom diff --git a/tests/pom.xml b/tests/pom.xml index 66043d95d..c8206bd82 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 1.36-SNAPSHOT + 1.36 tests diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index c86e4bc27..c4ab49a59 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.36-SNAPSHOT + 1.36 test-client-generation diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index ab2dae722..85cf4bbfe 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 1.36-SNAPSHOT + 1.36 test-client diff --git a/tests/test-helidon/pom.xml b/tests/test-helidon/pom.xml index b3bce206f..7c6cbc7c3 100644 --- a/tests/test-helidon/pom.xml +++ b/tests/test-helidon/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.36-SNAPSHOT + 1.36 test-helidon diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index ec9933dc5..40431345e 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 1.36-SNAPSHOT + 1.36 test-javalin-jsonb diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index fc8d58d25..c3c0bd872 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.36-SNAPSHOT + 1.36 test-javalin diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 4d5fffd6f..440f5d55e 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.36-SNAPSHOT + 1.36 test-jex diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 6c8eae5a3..3898deb69 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.36-SNAPSHOT + 1.36 test-nima-jsonb diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index f64b50ee3..5892987aa 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 1.36-SNAPSHOT + 1.36 test-nima From b50db21e556e739f225543761a74ddb1585515dc Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 18 Apr 2023 21:23:11 +1200 Subject: [PATCH 0733/1323] Bump to next snapshot version --- http-api/pom.xml | 2 +- http-client-gson-adapter/pom.xml | 4 ++-- http-client/pom.xml | 2 +- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 2 +- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-generator-nima/pom.xml | 2 +- pom.xml | 2 +- tests/pom.xml | 2 +- tests/test-client-generation/pom.xml | 2 +- tests/test-client/pom.xml | 2 +- tests/test-helidon/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- 19 files changed, 20 insertions(+), 20 deletions(-) diff --git a/http-api/pom.xml b/http-api/pom.xml index fad7a0351..58fd23fe0 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.36 + 1.37-SNAPSHOT .. diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index 247bc7910..0a7ef3f39 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.36 + 1.37-SNAPSHOT avaje-http-client-gson @@ -20,7 +20,7 @@ io.avaje avaje-http-client - 1.36 + 1.37-SNAPSHOT provided diff --git a/http-client/pom.xml b/http-client/pom.xml index b08320af6..d0dd443c4 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.36 + 1.37-SNAPSHOT avaje-http-client diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index 94ef678b8..8a1efd1e3 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.36 + 1.37-SNAPSHOT avaje-http-client-generator diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index d843aed4b..84d4b1c52 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.36 + 1.37-SNAPSHOT avaje-http-generator-core diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index d386108cd..bef74946f 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.36 + 1.37-SNAPSHOT avaje-http-helidon-generator diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index e9f4d1751..7a2626848 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.36 + 1.37-SNAPSHOT avaje-http-javalin-generator diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index ff17da38b..0f62e118b 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.36 + 1.37-SNAPSHOT avaje-http-jex-generator diff --git a/http-generator-nima/pom.xml b/http-generator-nima/pom.xml index 5d8ad9085..00b347bc6 100644 --- a/http-generator-nima/pom.xml +++ b/http-generator-nima/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 1.36 + 1.37-SNAPSHOT avaje-http-nima-generator diff --git a/pom.xml b/pom.xml index 9df02a8c9..ac254b191 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-parent - 1.36 + 1.37-SNAPSHOT pom diff --git a/tests/pom.xml b/tests/pom.xml index c8206bd82..c785552a1 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 1.36 + 1.37-SNAPSHOT tests diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index c4ab49a59..3527514e7 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.36 + 1.37-SNAPSHOT test-client-generation diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index 85cf4bbfe..89b9190a8 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 1.36 + 1.37-SNAPSHOT test-client diff --git a/tests/test-helidon/pom.xml b/tests/test-helidon/pom.xml index 7c6cbc7c3..55fb1150e 100644 --- a/tests/test-helidon/pom.xml +++ b/tests/test-helidon/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.36 + 1.37-SNAPSHOT test-helidon diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 40431345e..918840eba 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 1.36 + 1.37-SNAPSHOT test-javalin-jsonb diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index c3c0bd872..d4731b3cf 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.36 + 1.37-SNAPSHOT test-javalin diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 440f5d55e..7aded753c 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.36 + 1.37-SNAPSHOT test-jex diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 3898deb69..12e4bd166 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.36 + 1.37-SNAPSHOT test-nima-jsonb diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index 5892987aa..7e59a2f7e 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 1.36 + 1.37-SNAPSHOT test-nima From 52b9eaf84f819e2826e490a9207856571f82815a Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Thu, 20 Apr 2023 18:07:49 -0400 Subject: [PATCH 0734/1323] fix beanparam import --- .../avaje/http/api/context/ServerContext.java | 4 +-- .../http/generator/core/BeanParamReader.java | 7 +++++ .../http/generator/core/ElementReader.java | 31 +++++++------------ 3 files changed, 21 insertions(+), 21 deletions(-) diff --git a/http-api/src/main/java/io/avaje/http/api/context/ServerContext.java b/http-api/src/main/java/io/avaje/http/api/context/ServerContext.java index 2d9bf98ef..f3008d0a1 100644 --- a/http-api/src/main/java/io/avaje/http/api/context/ServerContext.java +++ b/http-api/src/main/java/io/avaje/http/api/context/ServerContext.java @@ -19,7 +19,7 @@ public ServerContext(Object request, Object response) { * @return The request */ @SuppressWarnings("unchecked") - T request() { + public T request() { return (T) request; } @@ -29,7 +29,7 @@ T request() { * @return The request */ @SuppressWarnings("unchecked") - T response() { + public T response() { return (T) response; } } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/BeanParamReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/BeanParamReader.java index 17a1d309e..5c18b089d 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/BeanParamReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/BeanParamReader.java @@ -14,6 +14,7 @@ public class BeanParamReader { private final Map fieldMap = new LinkedHashMap<>(); private final List constructors = new ArrayList<>(); private final Map methodMap = new LinkedHashMap<>(); + private final Set imports = new HashSet<>(); public BeanParamReader(TypeElement beanType, String beanVarName, String beanShortType, ParamType defaultParamType) { this.beanType = beanType; @@ -23,6 +24,10 @@ public BeanParamReader(TypeElement beanType, String beanVarName, String beanShor read(); } + public Collection imports() { + return imports; + } + private void read() { for (Element enclosedElement : beanType.getEnclosedElements()) { switch (enclosedElement.getKind()) { @@ -45,6 +50,8 @@ private void readField(Element enclosedElement) { } FieldReader field = new FieldReader(enclosedElement, defaultParamType); fieldMap.put(field.varName(), field); + + imports.addAll(UType.parse(field.element.element().asType()).importTypes()); } private void readMethod(ExecutableElement enclosedElement) { diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java index 577cf3d72..cf314c6d1 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java @@ -38,6 +38,7 @@ public class ElementReader { private boolean isParamCollection; private boolean isParamMap; private final Set imports = new HashSet<>(); + private BeanParamReader formBeanReader; ElementReader(Element element, ParamType defaultType, boolean formMarker) { this(element, null, Util.typeDef(element.asType()), defaultType, formMarker); @@ -74,6 +75,10 @@ public class ElementReader { paramType = ParamType.CONTEXT; useValidation = false; } + if (ParamType.FORM == paramType || ParamType.BEANPARAM == paramType) { + this.formBeanReader = getFormBeanReader(rawType, rawType, defaultType); + this.imports.addAll(formBeanReader.imports()); + } } TypeHandler initTypeHandler() { @@ -289,21 +294,9 @@ void setValue(Append writer) { } private boolean setValue(Append writer, PathSegments segments, String shortType) { -// if (formMarker && impliedParamType && typeHandler == null) { -// if (ParamType.FORM != paramType) { -// throw new IllegalStateException("Don't get here?"); -// } -//// // @Form on method and this type is a "bean" so treat is as a form bean -//// writeForm(writer, shortType, varName, ParamType.FORMPARAM); -//// paramType = ParamType.FORM; -//// return false; -// } - if (ParamType.FORM == paramType) { - writeForm(writer, shortType, varName, ParamType.FORMPARAM); - return false; - } - if (ParamType.BEANPARAM == paramType) { - writeForm(writer, shortType, varName, ParamType.QUERYPARAM); + + if ((ParamType.FORM == paramType) || (ParamType.BEANPARAM == paramType)) { + formBeanReader.write(writer); return false; } if (impliedParamType) { @@ -366,10 +359,10 @@ private boolean setValue(Append writer, PathSegments segments, String shortType) return true; } - private void writeForm(Append writer, String shortType, String varName, ParamType defaultParamType) { - TypeElement formBeanType = typeElement(rawType); - BeanParamReader form = new BeanParamReader(formBeanType, varName, shortType, defaultParamType); - form.write(writer); + private BeanParamReader getFormBeanReader( + String shortType, String varName, ParamType defaultParamType) { + final TypeElement formBeanType = typeElement(rawType); + return new BeanParamReader(formBeanType, varName, shortType, defaultParamType); } public ParamType paramType() { From b3eac31c5f6382b39c8d1ef0ee92a78c05bcbada Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Thu, 20 Apr 2023 18:16:36 -0400 Subject: [PATCH 0735/1323] Update ElementReader.java --- .../main/java/io/avaje/http/generator/core/ElementReader.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java index cf314c6d1..620bd03af 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java @@ -76,7 +76,7 @@ public class ElementReader { useValidation = false; } if (ParamType.FORM == paramType || ParamType.BEANPARAM == paramType) { - this.formBeanReader = getFormBeanReader(rawType, rawType, defaultType); + this.formBeanReader = getFormBeanReader(rawType, rawType, paramType); this.imports.addAll(formBeanReader.imports()); } } From 2875ce62eb11947eaa3d286488e9451210f28e34 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Thu, 20 Apr 2023 19:49:06 -0400 Subject: [PATCH 0736/1323] Update ElementReader.java --- .../http/generator/core/ElementReader.java | 31 +++++++++++++------ 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java index 620bd03af..395a85842 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java @@ -38,7 +38,6 @@ public class ElementReader { private boolean isParamCollection; private boolean isParamMap; private final Set imports = new HashSet<>(); - private BeanParamReader formBeanReader; ElementReader(Element element, ParamType defaultType, boolean formMarker) { this(element, null, Util.typeDef(element.asType()), defaultType, formMarker); @@ -76,8 +75,8 @@ public class ElementReader { useValidation = false; } if (ParamType.FORM == paramType || ParamType.BEANPARAM == paramType) { - this.formBeanReader = getFormBeanReader(rawType, rawType, paramType); - this.imports.addAll(formBeanReader.imports()); + this.imports.addAll( + new BeanParamReader(typeElement(rawType), varName, shortType, paramType).imports()); } } @@ -294,9 +293,21 @@ void setValue(Append writer) { } private boolean setValue(Append writer, PathSegments segments, String shortType) { - - if ((ParamType.FORM == paramType) || (ParamType.BEANPARAM == paramType)) { - formBeanReader.write(writer); +// if (formMarker && impliedParamType && typeHandler == null) { +// if (ParamType.FORM != paramType) { +// throw new IllegalStateException("Don't get here?"); +// } +//// // @Form on method and this type is a "bean" so treat is as a form bean +//// writeForm(writer, shortType, varName, ParamType.FORMPARAM); +//// paramType = ParamType.FORM; +//// return false; +// } + if (ParamType.FORM == paramType) { + writeForm(writer, shortType, varName, ParamType.FORMPARAM); + return false; + } + if (ParamType.BEANPARAM == paramType) { + writeForm(writer, shortType, varName, ParamType.QUERYPARAM); return false; } if (impliedParamType) { @@ -359,10 +370,10 @@ private boolean setValue(Append writer, PathSegments segments, String shortType) return true; } - private BeanParamReader getFormBeanReader( - String shortType, String varName, ParamType defaultParamType) { - final TypeElement formBeanType = typeElement(rawType); - return new BeanParamReader(formBeanType, varName, shortType, defaultParamType); + private void writeForm(Append writer, String shortType, String varName, ParamType defaultParamType) { + TypeElement formBeanType = typeElement(rawType); + BeanParamReader form = new BeanParamReader(formBeanType, varName, shortType, defaultParamType); + form.write(writer); } public ParamType paramType() { From e56e0503c55591eba7be6a682f9f433467034f04 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Thu, 20 Apr 2023 19:57:58 -0400 Subject: [PATCH 0737/1323] Update ElementReader.java --- .../io/avaje/http/generator/core/ElementReader.java | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java index 395a85842..0a64911d6 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java @@ -75,11 +75,20 @@ public class ElementReader { useValidation = false; } if (ParamType.FORM == paramType || ParamType.BEANPARAM == paramType) { - this.imports.addAll( - new BeanParamReader(typeElement(rawType), varName, shortType, paramType).imports()); + beanParamImports(rawType); } } + private void beanParamImports(String rawType) { + typeElement(rawType).getEnclosedElements().stream() + .filter(e -> e.getKind() == ElementKind.FIELD) + .filter(f -> !IgnorePrism.isPresent(f)) + .map(Element::asType) + .map(UType::parse) + .flatMap(u -> u.importTypes().stream()) + .forEach(imports::add); + } + TypeHandler initTypeHandler() { if (specialParam) { From d344b98214a5f2a9de44aad53605f0eac23e213b Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Fri, 21 Apr 2023 16:59:58 +1200 Subject: [PATCH 0738/1323] Version 1.37 --- http-api/pom.xml | 2 +- http-client-gson-adapter/pom.xml | 4 ++-- http-client/pom.xml | 2 +- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 2 +- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-generator-nima/pom.xml | 2 +- pom.xml | 2 +- tests/pom.xml | 2 +- tests/test-client-generation/pom.xml | 2 +- tests/test-client/pom.xml | 2 +- tests/test-helidon/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 4 +++- tests/test-nima/pom.xml | 4 +++- 19 files changed, 24 insertions(+), 20 deletions(-) diff --git a/http-api/pom.xml b/http-api/pom.xml index 58fd23fe0..3f7080cb8 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.37-SNAPSHOT + 1.37 .. diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index 0a7ef3f39..7cebe5e44 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.37-SNAPSHOT + 1.37 avaje-http-client-gson @@ -20,7 +20,7 @@ io.avaje avaje-http-client - 1.37-SNAPSHOT + 1.37 provided diff --git a/http-client/pom.xml b/http-client/pom.xml index d0dd443c4..262e34d66 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.37-SNAPSHOT + 1.37 avaje-http-client diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index 8a1efd1e3..ee0ee2392 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.37-SNAPSHOT + 1.37 avaje-http-client-generator diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 84d4b1c52..d15f69390 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.37-SNAPSHOT + 1.37 avaje-http-generator-core diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index bef74946f..48712c934 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.37-SNAPSHOT + 1.37 avaje-http-helidon-generator diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index 7a2626848..4923f9aef 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.37-SNAPSHOT + 1.37 avaje-http-javalin-generator diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index 0f62e118b..8ed240fb8 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.37-SNAPSHOT + 1.37 avaje-http-jex-generator diff --git a/http-generator-nima/pom.xml b/http-generator-nima/pom.xml index 00b347bc6..7bdbf8eef 100644 --- a/http-generator-nima/pom.xml +++ b/http-generator-nima/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 1.37-SNAPSHOT + 1.37 avaje-http-nima-generator diff --git a/pom.xml b/pom.xml index ac254b191..8df173e6d 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-parent - 1.37-SNAPSHOT + 1.37 pom diff --git a/tests/pom.xml b/tests/pom.xml index c785552a1..d1986627a 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 1.37-SNAPSHOT + 1.37 tests diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index 3527514e7..1274308c0 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.37-SNAPSHOT + 1.37 test-client-generation diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index 89b9190a8..ef6fe6ac0 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 1.37-SNAPSHOT + 1.37 test-client diff --git a/tests/test-helidon/pom.xml b/tests/test-helidon/pom.xml index 55fb1150e..7b9daa930 100644 --- a/tests/test-helidon/pom.xml +++ b/tests/test-helidon/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.37-SNAPSHOT + 1.37 test-helidon diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 918840eba..5e22e04a9 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 1.37-SNAPSHOT + 1.37 test-javalin-jsonb diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index d4731b3cf..66eb5b45e 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.37-SNAPSHOT + 1.37 test-javalin diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 7aded753c..37a15a304 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.37-SNAPSHOT + 1.37 test-jex diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 12e4bd166..5e6a5e9f8 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.37-SNAPSHOT + 1.37 test-nima-jsonb @@ -87,6 +87,8 @@ 1.4 + 19 + 19 diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index 7e59a2f7e..525eb7eb5 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 1.37-SNAPSHOT + 1.37 test-nima @@ -72,6 +72,8 @@ ${avaje-inject.version} + 19 + 19 From a59d850f3bdcfd70e7eb2a443ff7be57067ccdee Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Fri, 21 Apr 2023 17:00:37 +1200 Subject: [PATCH 0739/1323] Bump to next snapshot version --- http-api/pom.xml | 2 +- http-client-gson-adapter/pom.xml | 4 ++-- http-client/pom.xml | 2 +- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 2 +- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-generator-nima/pom.xml | 2 +- pom.xml | 2 +- tests/pom.xml | 2 +- tests/test-client-generation/pom.xml | 2 +- tests/test-client/pom.xml | 2 +- tests/test-helidon/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- 19 files changed, 20 insertions(+), 20 deletions(-) diff --git a/http-api/pom.xml b/http-api/pom.xml index 3f7080cb8..27da449f8 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.37 + 1.38-SNAPSHOT .. diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index 7cebe5e44..0e5cc85bc 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.37 + 1.38-SNAPSHOT avaje-http-client-gson @@ -20,7 +20,7 @@ io.avaje avaje-http-client - 1.37 + 1.38-SNAPSHOT provided diff --git a/http-client/pom.xml b/http-client/pom.xml index 262e34d66..1fc2a6523 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.37 + 1.38-SNAPSHOT avaje-http-client diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index ee0ee2392..ad3160e39 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.37 + 1.38-SNAPSHOT avaje-http-client-generator diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index d15f69390..50e9b379b 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.37 + 1.38-SNAPSHOT avaje-http-generator-core diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index 48712c934..6f3ed5671 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.37 + 1.38-SNAPSHOT avaje-http-helidon-generator diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index 4923f9aef..8dd346d50 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.37 + 1.38-SNAPSHOT avaje-http-javalin-generator diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index 8ed240fb8..3223cd943 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.37 + 1.38-SNAPSHOT avaje-http-jex-generator diff --git a/http-generator-nima/pom.xml b/http-generator-nima/pom.xml index 7bdbf8eef..cdba73479 100644 --- a/http-generator-nima/pom.xml +++ b/http-generator-nima/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 1.37 + 1.38-SNAPSHOT avaje-http-nima-generator diff --git a/pom.xml b/pom.xml index 8df173e6d..e461f0ab9 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-parent - 1.37 + 1.38-SNAPSHOT pom diff --git a/tests/pom.xml b/tests/pom.xml index d1986627a..2045ad5da 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 1.37 + 1.38-SNAPSHOT tests diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index 1274308c0..e2f436ee9 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.37 + 1.38-SNAPSHOT test-client-generation diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index ef6fe6ac0..9c20d07c6 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 1.37 + 1.38-SNAPSHOT test-client diff --git a/tests/test-helidon/pom.xml b/tests/test-helidon/pom.xml index 7b9daa930..9b0d461e3 100644 --- a/tests/test-helidon/pom.xml +++ b/tests/test-helidon/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.37 + 1.38-SNAPSHOT test-helidon diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 5e22e04a9..17093ecb1 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 1.37 + 1.38-SNAPSHOT test-javalin-jsonb diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 66eb5b45e..cc2e1b0a9 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.37 + 1.38-SNAPSHOT test-javalin diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 37a15a304..e5e6c0c30 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.37 + 1.38-SNAPSHOT test-jex diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 5e6a5e9f8..8119ed1d4 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.37 + 1.38-SNAPSHOT test-nima-jsonb diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index 525eb7eb5..d4cc06bbc 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 1.37 + 1.38-SNAPSHOT test-nima From 6bb1dc636a9ff78fb433ce11d62f4399eb9a2530 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Fri, 28 Apr 2023 02:51:44 -0400 Subject: [PATCH 0740/1323] Fix Hard Inject Dependency (use cyclical plugin module) (#212) * plugin * dir * Delete io.avaje.inject.spi.Plugin * working --- http-api/pom.xml | 6 +-- http-api/src/main/java/module-info.java | 5 -- .../services/io.avaje.inject.spi.Plugin | 1 - http-inject-plugin/pom.xml | 47 +++++++++++++++++++ .../http/inject}/DefaultResolverProvider.java | 2 +- .../src/main/java/module-info.java | 8 ++++ .../services/io.avaje.inject.spi.Plugin | 1 + pom.xml | 1 + 8 files changed, 60 insertions(+), 11 deletions(-) delete mode 100644 http-api/src/main/resources/META-INF/services/io.avaje.inject.spi.Plugin create mode 100644 http-inject-plugin/pom.xml rename {http-api/src/main/java/io/avaje/http/api/spi => http-inject-plugin/src/main/java/io/avaje/http/inject}/DefaultResolverProvider.java (95%) create mode 100644 http-inject-plugin/src/main/java/module-info.java create mode 100644 http-inject-plugin/src/main/resources/META-INF/services/io.avaje.inject.spi.Plugin diff --git a/http-api/pom.xml b/http-api/pom.xml index 27da449f8..62bd5aca5 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -18,10 +18,8 @@ io.avaje - avaje-inject - 9.0 - provided - true + avaje-http-inject-plugin + ${project.version} diff --git a/http-api/src/main/java/module-info.java b/http-api/src/main/java/module-info.java index 30ae62a71..71c803543 100644 --- a/http-api/src/main/java/module-info.java +++ b/http-api/src/main/java/module-info.java @@ -2,9 +2,4 @@ exports io.avaje.http.api; exports io.avaje.http.api.context; - exports io.avaje.http.api.spi; - requires static io.avaje.inject; - - provides io.avaje.inject.spi.Plugin with io.avaje.http.api.spi.DefaultResolverProvider; - } diff --git a/http-api/src/main/resources/META-INF/services/io.avaje.inject.spi.Plugin b/http-api/src/main/resources/META-INF/services/io.avaje.inject.spi.Plugin deleted file mode 100644 index 4d6993ea6..000000000 --- a/http-api/src/main/resources/META-INF/services/io.avaje.inject.spi.Plugin +++ /dev/null @@ -1 +0,0 @@ -io.avaje.http.api.spi.DefaultResolverProvider diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml new file mode 100644 index 000000000..3f348d241 --- /dev/null +++ b/http-inject-plugin/pom.xml @@ -0,0 +1,47 @@ + + + 4.0.0 + + io.avaje + avaje-http-parent + 1.38-SNAPSHOT + .. + + + avaje-http-inject-plugin + + + scm:git:git@github.com:avaje/avaje-http.git + avaje-http-parent-1.19 + + + + + io.avaje + avaje-inject + 9.0 + provided + true + + + io.avaje + avaje-http-api + 1.37 + true + provided + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 3.0.0 + + 0 + + + + + diff --git a/http-api/src/main/java/io/avaje/http/api/spi/DefaultResolverProvider.java b/http-inject-plugin/src/main/java/io/avaje/http/inject/DefaultResolverProvider.java similarity index 95% rename from http-api/src/main/java/io/avaje/http/api/spi/DefaultResolverProvider.java rename to http-inject-plugin/src/main/java/io/avaje/http/inject/DefaultResolverProvider.java index e2c49ffb3..56b5ad2f2 100644 --- a/http-api/src/main/java/io/avaje/http/api/spi/DefaultResolverProvider.java +++ b/http-inject-plugin/src/main/java/io/avaje/http/inject/DefaultResolverProvider.java @@ -1,4 +1,4 @@ -package io.avaje.http.api.spi; +package io.avaje.http.inject; import io.avaje.http.api.context.RequestContextResolver; import io.avaje.http.api.context.ThreadLocalRequestContextResolver; diff --git a/http-inject-plugin/src/main/java/module-info.java b/http-inject-plugin/src/main/java/module-info.java new file mode 100644 index 000000000..c8149f2fe --- /dev/null +++ b/http-inject-plugin/src/main/java/module-info.java @@ -0,0 +1,8 @@ +module io.avaje.http.plugin { + + requires io.avaje.http.api; + requires io.avaje.inject; + + provides io.avaje.inject.spi.Plugin with io.avaje.http.inject.DefaultResolverProvider; + +} diff --git a/http-inject-plugin/src/main/resources/META-INF/services/io.avaje.inject.spi.Plugin b/http-inject-plugin/src/main/resources/META-INF/services/io.avaje.inject.spi.Plugin new file mode 100644 index 000000000..d996e4e0c --- /dev/null +++ b/http-inject-plugin/src/main/resources/META-INF/services/io.avaje.inject.spi.Plugin @@ -0,0 +1 @@ +io.avaje.http.inject.DefaultResolverProvider diff --git a/pom.xml b/pom.xml index e461f0ab9..6366559f9 100644 --- a/pom.xml +++ b/pom.xml @@ -38,6 +38,7 @@ http-api http-client http-client-gson-adapter + http-inject-plugin http-generator-core http-generator-javalin http-generator-jex From f3b0d62f23794811d0aa2f0475ecd00441157813 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Fri, 28 Apr 2023 19:01:05 +1200 Subject: [PATCH 0741/1323] Version 1.38 --- http-api/pom.xml | 2 +- http-client-gson-adapter/pom.xml | 4 ++-- http-client/pom.xml | 2 +- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 2 +- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-generator-nima/pom.xml | 2 +- http-inject-plugin/pom.xml | 2 +- pom.xml | 2 +- tests/pom.xml | 2 +- tests/test-client-generation/pom.xml | 2 +- tests/test-client/pom.xml | 2 +- tests/test-helidon/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- 20 files changed, 21 insertions(+), 21 deletions(-) diff --git a/http-api/pom.xml b/http-api/pom.xml index 62bd5aca5..267a59781 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.38-SNAPSHOT + 1.38 .. diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index 0e5cc85bc..baf1b4282 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.38-SNAPSHOT + 1.38 avaje-http-client-gson @@ -20,7 +20,7 @@ io.avaje avaje-http-client - 1.38-SNAPSHOT + 1.38 provided diff --git a/http-client/pom.xml b/http-client/pom.xml index 1fc2a6523..57bc7b03c 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.38-SNAPSHOT + 1.38 avaje-http-client diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index ad3160e39..6d1c9da68 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.38-SNAPSHOT + 1.38 avaje-http-client-generator diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 50e9b379b..178988527 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.38-SNAPSHOT + 1.38 avaje-http-generator-core diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index 6f3ed5671..92849f6c1 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.38-SNAPSHOT + 1.38 avaje-http-helidon-generator diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index 8dd346d50..40ef83821 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.38-SNAPSHOT + 1.38 avaje-http-javalin-generator diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index 3223cd943..42dd47ad5 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.38-SNAPSHOT + 1.38 avaje-http-jex-generator diff --git a/http-generator-nima/pom.xml b/http-generator-nima/pom.xml index cdba73479..488a0a1f4 100644 --- a/http-generator-nima/pom.xml +++ b/http-generator-nima/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 1.38-SNAPSHOT + 1.38 avaje-http-nima-generator diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index 3f348d241..8a21a5a50 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.38-SNAPSHOT + 1.38 .. diff --git a/pom.xml b/pom.xml index 6366559f9..289c3fbef 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-parent - 1.38-SNAPSHOT + 1.38 pom diff --git a/tests/pom.xml b/tests/pom.xml index 2045ad5da..2dde7d3d2 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 1.38-SNAPSHOT + 1.38 tests diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index e2f436ee9..5d04c2765 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.38-SNAPSHOT + 1.38 test-client-generation diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index 9c20d07c6..9d99e0bfd 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 1.38-SNAPSHOT + 1.38 test-client diff --git a/tests/test-helidon/pom.xml b/tests/test-helidon/pom.xml index 9b0d461e3..6ba7c1d1b 100644 --- a/tests/test-helidon/pom.xml +++ b/tests/test-helidon/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.38-SNAPSHOT + 1.38 test-helidon diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 17093ecb1..714a9479f 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 1.38-SNAPSHOT + 1.38 test-javalin-jsonb diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index cc2e1b0a9..8563d7131 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.38-SNAPSHOT + 1.38 test-javalin diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index e5e6c0c30..6669b6cd2 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.38-SNAPSHOT + 1.38 test-jex diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 8119ed1d4..685f6a60d 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.38-SNAPSHOT + 1.38 test-nima-jsonb diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index d4cc06bbc..118d58aa2 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 1.38-SNAPSHOT + 1.38 test-nima From 1496846fde26f390c2ccbe4d8f351e81eff7e549 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Fri, 28 Apr 2023 19:01:51 +1200 Subject: [PATCH 0742/1323] Bump to next snapshot version --- http-api/pom.xml | 2 +- http-client-gson-adapter/pom.xml | 4 ++-- http-client/pom.xml | 2 +- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 2 +- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-generator-nima/pom.xml | 2 +- http-inject-plugin/pom.xml | 2 +- pom.xml | 2 +- tests/pom.xml | 2 +- tests/test-client-generation/pom.xml | 2 +- tests/test-client/pom.xml | 2 +- tests/test-helidon/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- 20 files changed, 21 insertions(+), 21 deletions(-) diff --git a/http-api/pom.xml b/http-api/pom.xml index 267a59781..e30c6f5e0 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.38 + 1.39-SNAPSHOT .. diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index baf1b4282..b796238e0 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.38 + 1.39-SNAPSHOT avaje-http-client-gson @@ -20,7 +20,7 @@ io.avaje avaje-http-client - 1.38 + 1.39-SNAPSHOT provided diff --git a/http-client/pom.xml b/http-client/pom.xml index 57bc7b03c..20912ed4a 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.38 + 1.39-SNAPSHOT avaje-http-client diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index 6d1c9da68..d76828d70 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.38 + 1.39-SNAPSHOT avaje-http-client-generator diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 178988527..5fef171ed 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.38 + 1.39-SNAPSHOT avaje-http-generator-core diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index 92849f6c1..de207e2f0 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.38 + 1.39-SNAPSHOT avaje-http-helidon-generator diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index 40ef83821..6db22ad1d 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.38 + 1.39-SNAPSHOT avaje-http-javalin-generator diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index 42dd47ad5..91782b79c 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.38 + 1.39-SNAPSHOT avaje-http-jex-generator diff --git a/http-generator-nima/pom.xml b/http-generator-nima/pom.xml index 488a0a1f4..b75898c05 100644 --- a/http-generator-nima/pom.xml +++ b/http-generator-nima/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 1.38 + 1.39-SNAPSHOT avaje-http-nima-generator diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index 8a21a5a50..7194a8a5c 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.38 + 1.39-SNAPSHOT .. diff --git a/pom.xml b/pom.xml index 289c3fbef..da30cd127 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-parent - 1.38 + 1.39-SNAPSHOT pom diff --git a/tests/pom.xml b/tests/pom.xml index 2dde7d3d2..57d942d05 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 1.38 + 1.39-SNAPSHOT tests diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index 5d04c2765..c844b56c7 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.38 + 1.39-SNAPSHOT test-client-generation diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index 9d99e0bfd..050d079ef 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 1.38 + 1.39-SNAPSHOT test-client diff --git a/tests/test-helidon/pom.xml b/tests/test-helidon/pom.xml index 6ba7c1d1b..1c6c184fc 100644 --- a/tests/test-helidon/pom.xml +++ b/tests/test-helidon/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.38 + 1.39-SNAPSHOT test-helidon diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 714a9479f..4fa35a87e 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 1.38 + 1.39-SNAPSHOT test-javalin-jsonb diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 8563d7131..90c2c3245 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.38 + 1.39-SNAPSHOT test-javalin diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 6669b6cd2..36e74b750 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.38 + 1.39-SNAPSHOT test-jex diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 685f6a60d..f0b14960c 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.38 + 1.39-SNAPSHOT test-nima-jsonb diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index 118d58aa2..6162a85a3 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 1.38 + 1.39-SNAPSHOT test-nima From 13e42b8e22496cbd2241babb17c95ba82cfa690e Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sun, 30 Apr 2023 01:00:58 -0400 Subject: [PATCH 0743/1323] InstrumentServerContext annotation (#214) --- .../java/io/avaje/http/api/Controller.java | 7 ++- .../main/java/io/avaje/http/api/Delete.java | 22 ++++---- .../src/main/java/io/avaje/http/api/Get.java | 52 ++++++++++--------- .../http/api/InstrumentServerContext.java | 29 +++++++++++ .../main/java/io/avaje/http/api/Patch.java | 7 ++- .../src/main/java/io/avaje/http/api/Post.java | 12 +++-- .../src/main/java/io/avaje/http/api/Put.java | 13 +++-- .../http/generator/core/ControllerReader.java | 31 +++++++---- .../http/generator/core/MethodReader.java | 31 ++++++----- .../http/generator/core/package-info.java | 1 + .../src/main/resources/public/openapi.json | 6 +-- .../main/java/org/example/TestController.java | 4 +- 12 files changed, 144 insertions(+), 71 deletions(-) create mode 100644 http-api/src/main/java/io/avaje/http/api/InstrumentServerContext.java diff --git a/http-api/src/main/java/io/avaje/http/api/Controller.java b/http-api/src/main/java/io/avaje/http/api/Controller.java index 575eeb643..14e112205 100644 --- a/http-api/src/main/java/io/avaje/http/api/Controller.java +++ b/http-api/src/main/java/io/avaje/http/api/Controller.java @@ -24,6 +24,11 @@ /** Specify the path mapping request to the controller. */ String value() default ""; - /** Specify if the http request context should be instrumented via RequestContextResolver */ + /** + * Specify if the http request context should be instrumented via RequestContextResolver + * + * @deprecated use InstrumentServerContext annotation instead + */ + @Deprecated boolean instrumentRequestContext() default false; } diff --git a/http-api/src/main/java/io/avaje/http/api/Delete.java b/http-api/src/main/java/io/avaje/http/api/Delete.java index ab82fc551..3c06a7564 100644 --- a/http-api/src/main/java/io/avaje/http/api/Delete.java +++ b/http-api/src/main/java/io/avaje/http/api/Delete.java @@ -1,21 +1,20 @@ package io.avaje.http.api; -import java.lang.annotation.Retention; -import java.lang.annotation.Target; - import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.RetentionPolicy.RUNTIME; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + /** * Marks a method that handles HTTP DELETE requests. * *
{@code
+ * @Delete("{id}")
+ * void delete(long id) {
  *
- *   @Delete("{id}")
- *   void delete(long id) {
- *
- *     ...
- *   }
+ *   ...
+ * }
  *
  * }
*/ @@ -26,6 +25,11 @@ /** Specify the path. */ String value() default ""; - + /** + * Specify if the http request context should be instrumented via RequestContextResolver + * + * @deprecated use InstrumentServerContext annotation instead + */ + @Deprecated boolean instrumentRequestContext() default false; } diff --git a/http-api/src/main/java/io/avaje/http/api/Get.java b/http-api/src/main/java/io/avaje/http/api/Get.java index 7238b90cc..c51769d98 100644 --- a/http-api/src/main/java/io/avaje/http/api/Get.java +++ b/http-api/src/main/java/io/avaje/http/api/Get.java @@ -1,51 +1,47 @@ package io.avaje.http.api; -import java.lang.annotation.Retention; -import java.lang.annotation.Target; - import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.RetentionPolicy.RUNTIME; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + /** * Marks a method that handles HTTP GET requests. * *
{@code
+ * @Get("{id}")
+ * Customer get(long id) {
  *
- *   @Get("{id}")
- *   Customer get(long id) {
- *
- *     ...
- *   }
+ *   ...
+ * }
  *
  * }
* *

Example

- *

- * Path parameters are matched by name - "status" in the example below. - *

- *

- * Method parameters that do not match a path parameter default to being - * a query parameter - "since" is a query parameter in the example below. - *

* - *
{@code
+ * 

Path parameters are matched by name - "status" in the example below. + * + *

Method parameters that do not match a path parameter default to being a query parameter - + * "since" is a query parameter in the example below. * - * @Get("/status/{status}") - * List getByStatus(String status, LocalDate since) { + *

{@code
+ * @Get("/status/{status}")
+ * List getByStatus(String status, LocalDate since) {
  *
- *     ...
- *   }
+ *   ...
+ * }
  *
  * }
* *

Example - Multiple path parameters

- *
{@code
  *
- *   @Get("/status/{status}/{parentId}")
- *   List getByStatus(String status, long parentId, LocalDate since) {
+ * 
{@code
+ * @Get("/status/{status}/{parentId}")
+ * List getByStatus(String status, long parentId, LocalDate since) {
  *
- *     ...
- *   }
+ *   ...
+ * }
  *
  * }
*/ @@ -57,5 +53,11 @@ /** Specify the path. */ String value() default ""; + /** + * Specify if the http request context should be instrumented via RequestContextResolver + * + * @deprecated use InstrumentServerContext annotation instead + */ + @Deprecated boolean instrumentRequestContext() default false; } diff --git a/http-api/src/main/java/io/avaje/http/api/InstrumentServerContext.java b/http-api/src/main/java/io/avaje/http/api/InstrumentServerContext.java new file mode 100644 index 000000000..16024506c --- /dev/null +++ b/http-api/src/main/java/io/avaje/http/api/InstrumentServerContext.java @@ -0,0 +1,29 @@ +package io.avaje.http.api; + +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.SOURCE; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +/** + * Marks a controller method to be instrumented with RequestContextResolver. + * + *

When instrumented,resolver.currentRequest() can be used to retrieve the current request during a handler method execution + * + *

{@code
+ * RequestContextResolver resolver = ...
+ *
+ * @Get
+ * @InstrumentServerContext
+ * void helloWorld(long id) {
+ *  Server resolver.currentRequest()
+ *   ...
+ * }
+ *
+ * }
+ */ +@Retention(SOURCE) +@Target({TYPE, METHOD}) +public @interface InstrumentServerContext {} diff --git a/http-api/src/main/java/io/avaje/http/api/Patch.java b/http-api/src/main/java/io/avaje/http/api/Patch.java index afed8854b..3b9491ef7 100644 --- a/http-api/src/main/java/io/avaje/http/api/Patch.java +++ b/http-api/src/main/java/io/avaje/http/api/Patch.java @@ -14,6 +14,11 @@ /** Specify the path. */ String value() default ""; - + /** + * Specify if the http request context should be instrumented via RequestContextResolver + * + * @deprecated use InstrumentServerContext annotation instead + */ + @Deprecated boolean instrumentRequestContext() default false; } diff --git a/http-api/src/main/java/io/avaje/http/api/Post.java b/http-api/src/main/java/io/avaje/http/api/Post.java index 158461f39..244854c33 100644 --- a/http-api/src/main/java/io/avaje/http/api/Post.java +++ b/http-api/src/main/java/io/avaje/http/api/Post.java @@ -1,11 +1,11 @@ package io.avaje.http.api; -import java.lang.annotation.Retention; -import java.lang.annotation.Target; - import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.RetentionPolicy.RUNTIME; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + /** * Marks a method that handles HTTP POST requests. * @@ -24,5 +24,11 @@ /** Specify the path. */ String value() default ""; + /** + * Specify if the http request context should be instrumented via RequestContextResolver + * + * @deprecated use InstrumentServerContext annotation instead + */ + @Deprecated boolean instrumentRequestContext() default false; } diff --git a/http-api/src/main/java/io/avaje/http/api/Put.java b/http-api/src/main/java/io/avaje/http/api/Put.java index e3b23c8a1..65ab54fd4 100644 --- a/http-api/src/main/java/io/avaje/http/api/Put.java +++ b/http-api/src/main/java/io/avaje/http/api/Put.java @@ -1,11 +1,11 @@ package io.avaje.http.api; -import java.lang.annotation.Retention; -import java.lang.annotation.Target; - import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.RetentionPolicy.RUNTIME; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + /** * Marks a method that handles HTTP PUT requests. */ @@ -16,6 +16,11 @@ /** Specify the path. */ String value() default ""; - + /** + * Specify if the http request context should be instrumented via RequestContextResolver + * + * @deprecated use InstrumentServerContext annotation instead + */ + @Deprecated boolean instrumentRequestContext() default false; } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java index 1b71404ca..933e22e42 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java @@ -1,6 +1,12 @@ package io.avaje.http.generator.core; -import static io.avaje.http.generator.core.ProcessingContext.*; +import static io.avaje.http.generator.core.ProcessingContext.asElement; +import static io.avaje.http.generator.core.ProcessingContext.asMemberOf; +import static io.avaje.http.generator.core.ProcessingContext.instrumentAllWebMethods; +import static io.avaje.http.generator.core.ProcessingContext.isOpenApiAvailable; +import static io.avaje.http.generator.core.ProcessingContext.platform; +import static io.avaje.http.generator.core.ProcessingContext.useComponent; +import static io.avaje.http.generator.core.ProcessingContext.useJavax; import static java.util.function.Predicate.not; import java.util.ArrayList; @@ -61,6 +67,9 @@ public ControllerReader(TypeElement beanType) { instrumentAllWebMethods() || findAnnotation(ControllerPrism::getOptionalOn) .map(ControllerPrism::instrumentRequestContext) + .or( + () -> + findAnnotation(InstrumentServerContextPrism::getOptionalOn).map(x -> true)) .orElse(false); } @@ -107,8 +116,8 @@ void addImports(boolean withSingleton) { } private List initInterfaces() { - List interfaces = new ArrayList<>(); - for (TypeMirror anInterface : beanType.getInterfaces()) { + final List interfaces = new ArrayList<>(); + for (final TypeMirror anInterface : beanType.getInterfaces()) { final Element ifaceElement = asElement(anInterface); final var controller = ControllerPrism.getInstanceOn(ifaceElement); if (controller != null && !controller.value().isBlank() @@ -120,8 +129,8 @@ private List initInterfaces() { } private List initInterfaceMethods() { - List ifaceMethods = new ArrayList<>(); - for (Element anInterface : interfaces) { + final List ifaceMethods = new ArrayList<>(); + for (final Element anInterface : interfaces) { ifaceMethods.addAll(ElementFilter.methodsIn(anInterface.getEnclosedElements())); } return ifaceMethods; @@ -204,7 +213,7 @@ public void read(boolean withSingleton) { if (!roles.isEmpty()) { platform().controllerRoles(roles, this); } - for (Element element : beanType.getEnclosedElements()) { + for (final Element element : beanType.getEnclosedElements()) { if (element.getKind() == ElementKind.METHOD) { readMethod((ExecutableElement) element); } else if (element.getKind() == ElementKind.FIELD) { @@ -221,7 +230,7 @@ private void deriveIncludeValidation() { } private boolean methodHasValid() { - for (MethodReader method : methods) { + for (final MethodReader method : methods) { if (method.hasValid()) { return true; } @@ -240,12 +249,12 @@ private void readField(Element element) { * Read methods from superclasses taking into account generics. */ private void readSuper(TypeElement beanType) { - TypeMirror superclass = beanType.getSuperclass(); + final TypeMirror superclass = beanType.getSuperclass(); if (superclass.getKind() != TypeKind.NONE) { - DeclaredType declaredType = (DeclaredType) superclass; + final DeclaredType declaredType = (DeclaredType) superclass; final Element superElement = asElement(superclass); if (!"java.lang.Object".equals(superElement.toString())) { - for (Element element : superElement.getEnclosedElements()) { + for (final Element element : superElement.getEnclosedElements()) { if (element.getKind() == ElementKind.METHOD) { readMethod((ExecutableElement) element, declaredType); } else if (element.getKind() == ElementKind.FIELD) { @@ -269,7 +278,7 @@ private void readMethod(ExecutableElement method, DeclaredType declaredType) { // actual taking into account generics actualExecutable = (ExecutableType) asMemberOf(declaredType, method); } - MethodReader methodReader = new MethodReader(this, method, actualExecutable); + final MethodReader methodReader = new MethodReader(this, method, actualExecutable); if (methodReader.isWebMethod()) { methodReader.read(); methods.add(methodReader); diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java index 7b3434cc8..c3bad7897 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java @@ -100,6 +100,11 @@ private boolean initResolver() { } private boolean hasInstrument(Element e) { + + if (InstrumentServerContextPrism.getOptionalOn(e).isPresent()) { + return true; + } + for (final var a : e.getAnnotationMirrors()) { if (HttpMethodPrism.isPresent(a.getAnnotationType().asElement())) { return a.getElementValues().values().stream().anyMatch(v -> v.getValue().equals(true)); @@ -170,16 +175,16 @@ public Javadoc javadoc() { } private List readSecurityRequirements() { - var list = new ArrayList(); + final var list = new ArrayList(); readSecurityRequirements(element, list); - for (ExecutableElement superMethod : superMethods) { + for (final ExecutableElement superMethod : superMethods) { readSecurityRequirements(superMethod, list); } readSecurityRequirements(bean.beanType(), list); - var map = new HashMap(); - for (SecurityRequirementPrism p : list) { + final var map = new HashMap(); + for (final SecurityRequirementPrism p : list) { if (!map.containsKey(p.name())) { map.put(p.name(), p); } @@ -188,7 +193,7 @@ private List readSecurityRequirements() { } private void readSecurityRequirements(Element element, List list) { - Consumer f = e -> { + final Consumer f = e -> { Optional.ofNullable(SecurityRequirementsPrism.getInstanceOn(e)) .map(SecurityRequirementsPrism::value) .ifPresent(list::addAll); @@ -197,7 +202,7 @@ private void readSecurityRequirements(Element element, List parameters = element.getParameters(); for (int i = 0; i < parameters.size(); i++) { - VariableElement p = parameters.get(i); + final VariableElement p = parameters.get(i); TypeMirror typeMirror; if (actualParams != null) { typeMirror = actualParams.get(i); } else { typeMirror = p.asType(); } - String rawType = Util.typeDef(typeMirror); - UType type = Util.parse(typeMirror.toString()); - MethodParam param = new MethodParam(p, type, rawType, defaultParamType, formMarker); + final String rawType = Util.typeDef(typeMirror); + final UType type = Util.parse(typeMirror.toString()); + final MethodParam param = new MethodParam(p, type, rawType, defaultParamType, formMarker); params.add(param); param.addImports(bean); } @@ -293,7 +298,7 @@ public void buildApiDocumentation() { } public List roles() { - var roles = new ArrayList<>(methodRoles); + final var roles = new ArrayList<>(methodRoles); roles.addAll(bean.roles()); return roles; } @@ -374,7 +379,7 @@ public String simpleName() { } public boolean isFormBody() { - for (MethodParam param : params) { + for (final MethodParam param : params) { if (param.isForm()) { return true; } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/package-info.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/package-info.java index c41bf74f7..f5a9a1b0c 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/package-info.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/package-info.java @@ -20,6 +20,7 @@ @GeneratePrism(value = io.avaje.http.api.Produces.class, publicAccess = true) @GeneratePrism(value = io.avaje.http.api.Consumes.class, publicAccess = true) @GeneratePrism(value = io.avaje.http.api.Put.class, publicAccess = true) +@GeneratePrism(value = io.avaje.http.api.InstrumentServerContext.class) @GeneratePrism(value = io.swagger.v3.oas.annotations.OpenAPIDefinition.class, publicAccess = true) @GeneratePrism(value = io.swagger.v3.oas.annotations.tags.Tag.class, publicAccess = true) @GeneratePrism(value = io.swagger.v3.oas.annotations.tags.Tags.class, publicAccess = true) diff --git a/tests/test-javalin-jsonb/src/main/resources/public/openapi.json b/tests/test-javalin-jsonb/src/main/resources/public/openapi.json index 913874880..1dd758c73 100644 --- a/tests/test-javalin-jsonb/src/main/resources/public/openapi.json +++ b/tests/test-javalin-jsonb/src/main/resources/public/openapi.json @@ -1,18 +1,18 @@ { "openapi" : "3.0.1", "info" : { - "title" : "Example service showing off the Path extension method of controller", + "title" : "Example service", "description" : "Example Javalin controllers with Java and Maven", "version" : "" }, "tags" : [ { "name" : "tag1", - "description" : "this is added to openapi tags" + "description" : "it's somethin" }, { "name" : "tag1", - "description" : "it's somethin" + "description" : "this is added to openapi tags" } ], "paths" : { diff --git a/tests/test-nima-jsonb/src/main/java/org/example/TestController.java b/tests/test-nima-jsonb/src/main/java/org/example/TestController.java index 682cdf3cc..ae476c608 100644 --- a/tests/test-nima-jsonb/src/main/java/org/example/TestController.java +++ b/tests/test-nima-jsonb/src/main/java/org/example/TestController.java @@ -10,6 +10,7 @@ import io.avaje.http.api.Form; import io.avaje.http.api.FormParam; import io.avaje.http.api.Get; +import io.avaje.http.api.InstrumentServerContext; import io.avaje.http.api.Path; import io.avaje.http.api.Post; import io.avaje.http.api.QueryParam; @@ -54,7 +55,8 @@ String enumQueryImplied(String s, @QueryParam ServerType type) { return type.name(); } - @Get(value = "/inputStream", instrumentRequestContext = true) + @InstrumentServerContext + @Get(value = "/inputStream") String stream(InputStream stream) { return stream.toString(); } From d0c74c86f6f72eb98f7440b830bf3ddb2845786f Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sun, 30 Apr 2023 01:01:46 -0400 Subject: [PATCH 0744/1323] Update ControllerMethodWriter.java (#211) --- .../http/generator/javalin/ControllerMethodWriter.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java index 14590c0fa..b034edbaa 100644 --- a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java +++ b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java @@ -100,6 +100,13 @@ void write(boolean requestScoped) { } private void writeContextReturn() { + + if (instrumentContext) { + writer + .append(" if (ctx.resultInputStream() != null || ctx.res().isCommitted()) return;") + .eol(); + } + // Support for CompletableFuture's. final UType type = UType.parse(method.returnType()); if ("java.util.concurrent.CompletableFuture".equals(type.mainType())) { From fca319d047ae18d3ee6c9e0c6ae16718c6dfeda4 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sun, 30 Apr 2023 16:33:04 -0400 Subject: [PATCH 0745/1323] [http-client] Copy Annotations to Generated Clients (#216) * Copy Annotations * handle compound annotations * Update AnnotationUtil.java * Update AnnotationUtil.java * Delete .factorypath * Update AnnotationUtil.java * Update AnnotationUtil.java --- .../http/generator/client/AnnotationUtil.java | 88 +++++++++++++++++++ .../generator/client/ClientMethodWriter.java | 1 + .../http/generator/client/ClientWriter.java | 1 + .../http/generator/core/MethodReader.java | 4 + tests/test-nima-jsonb/.factorypath | 16 ---- 5 files changed, 94 insertions(+), 16 deletions(-) create mode 100644 http-generator-client/src/main/java/io/avaje/http/generator/client/AnnotationUtil.java delete mode 100644 tests/test-nima-jsonb/.factorypath diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/AnnotationUtil.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/AnnotationUtil.java new file mode 100644 index 000000000..1f3769381 --- /dev/null +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/AnnotationUtil.java @@ -0,0 +1,88 @@ +package io.avaje.http.generator.client; + +import java.util.List; + +import javax.lang.model.element.AnnotationMirror; +import javax.lang.model.element.AnnotationValue; +import javax.lang.model.element.Element; +import javax.lang.model.element.VariableElement; + +import io.avaje.http.generator.core.Append; +import io.avaje.http.generator.core.UType; + +final class AnnotationUtil { + private AnnotationUtil() {} + + public static void writeAnnotations(Append writer, Element element) { + for (final AnnotationMirror annotationMirror : element.getAnnotationMirrors()) { + final var type = UType.parse(annotationMirror.getAnnotationType().asElement().asType()); + if (type.mainType().startsWith("io.avaje.http") || type.mainType().startsWith("io.swagger")) { + continue; + } + final String annotationName = annotationMirror.getAnnotationType().toString(); + final StringBuilder sb = new StringBuilder("@").append(annotationName).append("("); + boolean first = true; + + for (final var entry : annotationMirror.getElementValues().entrySet()) { + if (!first) { + sb.append(", "); + } + sb.append(entry.getKey().getSimpleName()).append("="); + writeVal(sb, entry.getValue()); + first = false; + } + + sb.append(")"); + final String annotationString = sb.toString(); + writer.append(annotationString).eol(); + } + } + + private static void writeVal(final StringBuilder sb, final AnnotationValue annotationValue) { + final var value = annotationValue.getValue(); + // handle array values + if (value instanceof List) { + sb.append("{"); + boolean first = true; + + for (final AnnotationValue listValue : (List) value) { + + if (!first) { + sb.append(", "); + } + + writeVal(sb, listValue); + first = false; + } + sb.append("}"); + // Handle enum values + } else if (value instanceof VariableElement) { + + final var element = (VariableElement) value; + + final var type = UType.parse(element.asType()); + sb.append(type.full() + "." + element.toString()); + // handle annotation values + } else if (value instanceof AnnotationMirror) { + + final var mirror = (AnnotationMirror) value; + + final String annotationName = mirror.getAnnotationType().toString(); + sb.append("@").append(annotationName).append("("); + boolean first = true; + + for (final var entry : mirror.getElementValues().entrySet()) { + if (!first) { + sb.append(", "); + } + sb.append(entry.getKey().getSimpleName()).append("="); + writeVal(sb, entry.getValue()); + first = false; + } + + sb.append(")"); + } else { + sb.append(annotationValue.toString()); + } + } +} diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java index 01963feed..0729ca45d 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java @@ -49,6 +49,7 @@ private void methodStart(Append writer) { } writer.append(" // %s %s", webMethod, method.webMethodPath()).eol(); writer.append(" @Override").eol(); + AnnotationUtil.writeAnnotations(writer, method.element()); writer.append(" public %s%s %s(", methodGenericParams, returnType.shortType(), method.simpleName()); int count = 0; for (MethodParam param : method.params()) { diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientWriter.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientWriter.java index d2d313795..fcc098ccf 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientWriter.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientWriter.java @@ -79,6 +79,7 @@ private void writeMethods() { private void writeClassStart() { writer.append(AT_GENERATED).eol(); + AnnotationUtil.writeAnnotations(writer, reader.beanType()); writer.append("public class %s%s implements %s {", shortName, SUFFIX, shortName).eol().eol(); writer.append(" private final HttpClient client;").eol().eol(); diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java index c3bad7897..dd7879347 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java @@ -423,4 +423,8 @@ public void writeContext(Append writer, String reqName, String resName) { } writer.append("(new ServerContext(%s, %s), () -> ", reqName, resName); } + + public ExecutableElement element() { + return element; + } } diff --git a/tests/test-nima-jsonb/.factorypath b/tests/test-nima-jsonb/.factorypath deleted file mode 100644 index 7506fe785..000000000 --- a/tests/test-nima-jsonb/.factorypath +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - - - - - From 1256673a27116390fa44822f62f3ed07a45be343 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Mon, 1 May 2023 10:37:11 +1200 Subject: [PATCH 0746/1323] Version 1.39 --- http-api/pom.xml | 2 +- http-client-gson-adapter/pom.xml | 4 ++-- http-client/pom.xml | 2 +- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 2 +- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-generator-nima/pom.xml | 2 +- http-inject-plugin/pom.xml | 2 +- pom.xml | 2 +- tests/pom.xml | 2 +- tests/test-client-generation/pom.xml | 2 +- tests/test-client/pom.xml | 2 +- tests/test-helidon/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- .../src/main/resources/public/openapi.json | 6 +++--- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- 21 files changed, 24 insertions(+), 24 deletions(-) diff --git a/http-api/pom.xml b/http-api/pom.xml index e30c6f5e0..264c1bd14 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.39-SNAPSHOT + 1.39 .. diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index b796238e0..b2e5ceed6 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.39-SNAPSHOT + 1.39 avaje-http-client-gson @@ -20,7 +20,7 @@ io.avaje avaje-http-client - 1.39-SNAPSHOT + 1.39 provided diff --git a/http-client/pom.xml b/http-client/pom.xml index 20912ed4a..93ccecae2 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.39-SNAPSHOT + 1.39 avaje-http-client diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index d76828d70..9d81b8cd1 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.39-SNAPSHOT + 1.39 avaje-http-client-generator diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 5fef171ed..6a4f9487c 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.39-SNAPSHOT + 1.39 avaje-http-generator-core diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index de207e2f0..8dcd907cc 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.39-SNAPSHOT + 1.39 avaje-http-helidon-generator diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index 6db22ad1d..51ca3a98f 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.39-SNAPSHOT + 1.39 avaje-http-javalin-generator diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index 91782b79c..f7c76f8d0 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.39-SNAPSHOT + 1.39 avaje-http-jex-generator diff --git a/http-generator-nima/pom.xml b/http-generator-nima/pom.xml index b75898c05..101029eb2 100644 --- a/http-generator-nima/pom.xml +++ b/http-generator-nima/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 1.39-SNAPSHOT + 1.39 avaje-http-nima-generator diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index 7194a8a5c..15072a4a6 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.39-SNAPSHOT + 1.39 .. diff --git a/pom.xml b/pom.xml index da30cd127..a93410d60 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-parent - 1.39-SNAPSHOT + 1.39 pom diff --git a/tests/pom.xml b/tests/pom.xml index 57d942d05..9178fd930 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 1.39-SNAPSHOT + 1.39 tests diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index c844b56c7..33c8147c6 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.39-SNAPSHOT + 1.39 test-client-generation diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index 050d079ef..b4e7f07ba 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 1.39-SNAPSHOT + 1.39 test-client diff --git a/tests/test-helidon/pom.xml b/tests/test-helidon/pom.xml index 1c6c184fc..24f96f647 100644 --- a/tests/test-helidon/pom.xml +++ b/tests/test-helidon/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.39-SNAPSHOT + 1.39 test-helidon diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 4fa35a87e..8e7c106dc 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 1.39-SNAPSHOT + 1.39 test-javalin-jsonb diff --git a/tests/test-javalin-jsonb/src/main/resources/public/openapi.json b/tests/test-javalin-jsonb/src/main/resources/public/openapi.json index 1dd758c73..913874880 100644 --- a/tests/test-javalin-jsonb/src/main/resources/public/openapi.json +++ b/tests/test-javalin-jsonb/src/main/resources/public/openapi.json @@ -1,18 +1,18 @@ { "openapi" : "3.0.1", "info" : { - "title" : "Example service", + "title" : "Example service showing off the Path extension method of controller", "description" : "Example Javalin controllers with Java and Maven", "version" : "" }, "tags" : [ { "name" : "tag1", - "description" : "it's somethin" + "description" : "this is added to openapi tags" }, { "name" : "tag1", - "description" : "this is added to openapi tags" + "description" : "it's somethin" } ], "paths" : { diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 90c2c3245..27945ecbb 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.39-SNAPSHOT + 1.39 test-javalin diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 36e74b750..0354cb268 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.39-SNAPSHOT + 1.39 test-jex diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index f0b14960c..0528431c2 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.39-SNAPSHOT + 1.39 test-nima-jsonb diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index 6162a85a3..910f43edb 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 1.39-SNAPSHOT + 1.39 test-nima From 71d27019d146f21c17d1f0dfc31e0e9c300bef7c Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Mon, 1 May 2023 10:37:58 +1200 Subject: [PATCH 0747/1323] Bump to next snapshot version --- http-api/pom.xml | 2 +- http-client-gson-adapter/pom.xml | 4 ++-- http-client/pom.xml | 2 +- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 2 +- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-generator-nima/pom.xml | 2 +- http-inject-plugin/pom.xml | 2 +- pom.xml | 2 +- tests/pom.xml | 2 +- tests/test-client-generation/pom.xml | 2 +- tests/test-client/pom.xml | 2 +- tests/test-helidon/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- 20 files changed, 21 insertions(+), 21 deletions(-) diff --git a/http-api/pom.xml b/http-api/pom.xml index 264c1bd14..a5558ec09 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.39 + 1.40-SNAPSHOT .. diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index b2e5ceed6..60614f2ef 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.39 + 1.40-SNAPSHOT avaje-http-client-gson @@ -20,7 +20,7 @@ io.avaje avaje-http-client - 1.39 + 1.40-SNAPSHOT provided diff --git a/http-client/pom.xml b/http-client/pom.xml index 93ccecae2..f2c49b530 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.39 + 1.40-SNAPSHOT avaje-http-client diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index 9d81b8cd1..072e85847 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.39 + 1.40-SNAPSHOT avaje-http-client-generator diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 6a4f9487c..13d416bb2 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.39 + 1.40-SNAPSHOT avaje-http-generator-core diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index 8dcd907cc..ad22b1eba 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.39 + 1.40-SNAPSHOT avaje-http-helidon-generator diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index 51ca3a98f..b595c3944 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.39 + 1.40-SNAPSHOT avaje-http-javalin-generator diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index f7c76f8d0..af48b1939 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.39 + 1.40-SNAPSHOT avaje-http-jex-generator diff --git a/http-generator-nima/pom.xml b/http-generator-nima/pom.xml index 101029eb2..b88dec1f4 100644 --- a/http-generator-nima/pom.xml +++ b/http-generator-nima/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 1.39 + 1.40-SNAPSHOT avaje-http-nima-generator diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index 15072a4a6..cd4bf2e70 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.39 + 1.40-SNAPSHOT .. diff --git a/pom.xml b/pom.xml index a93410d60..e8586008b 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-parent - 1.39 + 1.40-SNAPSHOT pom diff --git a/tests/pom.xml b/tests/pom.xml index 9178fd930..b50896881 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 1.39 + 1.40-SNAPSHOT tests diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index 33c8147c6..9a56c9334 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.39 + 1.40-SNAPSHOT test-client-generation diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index b4e7f07ba..e5ce120c9 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 1.39 + 1.40-SNAPSHOT test-client diff --git a/tests/test-helidon/pom.xml b/tests/test-helidon/pom.xml index 24f96f647..9cfaf7b61 100644 --- a/tests/test-helidon/pom.xml +++ b/tests/test-helidon/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.39 + 1.40-SNAPSHOT test-helidon diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 8e7c106dc..98ef3aa5c 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 1.39 + 1.40-SNAPSHOT test-javalin-jsonb diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 27945ecbb..c845cc807 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.39 + 1.40-SNAPSHOT test-javalin diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 0354cb268..70bcebcab 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.39 + 1.40-SNAPSHOT test-jex diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 0528431c2..402ada06f 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.39 + 1.40-SNAPSHOT test-nima-jsonb diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index 910f43edb..2748bb5d0 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 1.39 + 1.40-SNAPSHOT test-nima From 2ce27b470ba7d5ca204f54eac757e2445528d285 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Mon, 29 May 2023 09:51:09 -0400 Subject: [PATCH 0748/1323] working --- .../http/api/InstrumentServerContext.java | 2 +- .../java/io/avaje/http/client/DHttpApi.java | 16 ++- .../avaje/http/client/DHttpClientContext.java | 44 ++++--- .../io/avaje/http/client/HttpApiProvider.java | 16 +-- .../java/io/avaje/http/client/HttpClient.java | 17 ++- http-client/src/main/java/module-info.java | 1 + http-generator-client/pom.xml | 21 +++ .../generator/client/ClientProcessor.java | 42 +++--- .../http/generator/client/ClientWriter.java | 20 +-- .../client/SimpleComponentWriter.java | 124 ++++++++++++++++++ .../http/generator/client/TopPackage.java | 48 +++++++ .../generator/client/ClientProcessorTest.java | 68 ++++++++++ .../generator/client/clients/ApiClient.java | 12 ++ .../generator/core/ProcessingContext.java | 8 ++ pom.xml | 2 +- 15 files changed, 363 insertions(+), 78 deletions(-) create mode 100644 http-generator-client/src/main/java/io/avaje/http/generator/client/SimpleComponentWriter.java create mode 100644 http-generator-client/src/main/java/io/avaje/http/generator/client/TopPackage.java create mode 100644 http-generator-client/src/test/java/io/avaje/http/generator/client/ClientProcessorTest.java create mode 100644 http-generator-client/src/test/java/io/avaje/http/generator/client/clients/ApiClient.java diff --git a/http-api/src/main/java/io/avaje/http/api/InstrumentServerContext.java b/http-api/src/main/java/io/avaje/http/api/InstrumentServerContext.java index 16024506c..ff455a6f6 100644 --- a/http-api/src/main/java/io/avaje/http/api/InstrumentServerContext.java +++ b/http-api/src/main/java/io/avaje/http/api/InstrumentServerContext.java @@ -18,7 +18,7 @@ * @Get * @InstrumentServerContext * void helloWorld(long id) { - * Server resolver.currentRequest() + * Context = resolver.currentRequest() * ... * } * diff --git a/http-client/src/main/java/io/avaje/http/client/DHttpApi.java b/http-client/src/main/java/io/avaje/http/client/DHttpApi.java index 74c72f2e1..0f03dafba 100644 --- a/http-client/src/main/java/io/avaje/http/client/DHttpApi.java +++ b/http-client/src/main/java/io/avaje/http/client/DHttpApi.java @@ -1,6 +1,7 @@ package io.avaje.http.client; import io.avaje.applog.AppLog; +import io.avaje.http.client.HttpClient.GeneratedComponent; import java.util.HashMap; import java.util.Map; @@ -19,20 +20,21 @@ final class DHttpApi { private final Map, HttpApiProvider> providerMap = new HashMap<>(); - DHttpApi() { + private DHttpApi() { init(); } @SuppressWarnings("rawtypes") void init() { - for (HttpApiProvider apiProvider : ServiceLoader.load(HttpApiProvider.class)) { - addProvider(apiProvider); + for (final HttpApiProvider apiProvider : ServiceLoader.load(HttpApiProvider.class)) { + providerMap.put(apiProvider.type(), apiProvider); } - log.log(DEBUG, "providers for {0}", providerMap.keySet()); - } - void addProvider(HttpApiProvider apiProvider) { - providerMap.put(apiProvider.type(), apiProvider); + for (final GeneratedComponent apiProvider : ServiceLoader.load(GeneratedComponent.class)) { + apiProvider.register(providerMap); + } + + log.log(DEBUG, "providers for {0}", providerMap.keySet()); } @SuppressWarnings("unchecked") diff --git a/http-client/src/main/java/io/avaje/http/client/DHttpClientContext.java b/http-client/src/main/java/io/avaje/http/client/DHttpClientContext.java index 7eb7b0979..fb149f2b2 100644 --- a/http-client/src/main/java/io/avaje/http/client/DHttpClientContext.java +++ b/http-client/src/main/java/io/avaje/http/client/DHttpClientContext.java @@ -58,16 +58,27 @@ public T create(Class clientInterface) { if (!clientInterface.isInterface()) { throw new IllegalArgumentException("API declarations must be interfaces."); } - HttpApiProvider apiProvider = DHttpApi.get(clientInterface); + final HttpApiProvider apiProvider = DHttpApi.get(clientInterface); if (apiProvider != null) { return apiProvider.provide(this); } try { - Class implementationClass = implementationClass(clientInterface); - Constructor constructor = implementationClass.getConstructor(HttpClientContext.class); + final Class implementationClass = implementationClass(clientInterface); + final Constructor constructor = implementationClass.getConstructor(HttpClient.class); return (T) constructor.newInstance(this); - } catch (Exception e) { - String cn = implementationClassName(clientInterface, "HttpClient"); + } catch (final Exception e) { + return constructReflectively(clientInterface); + } + } + + @SuppressWarnings("unchecked") + private T constructReflectively(Class clientInterface) { + try { + final Class implementationClass = implementationClass(clientInterface); + final Constructor constructor = implementationClass.getConstructor(HttpClientContext.class); + return (T) constructor.newInstance(this); + } catch (final Exception e) { + final String cn = implementationClassName(clientInterface, "HttpClient"); throw new IllegalStateException("Failed to create http client service " + cn, e); } } @@ -75,15 +86,15 @@ public T create(Class clientInterface) { private Class implementationClass(Class clientInterface) throws ClassNotFoundException { try { return Class.forName(implementationClassName(clientInterface, "HttpClient")); - } catch (ClassNotFoundException e) { + } catch (final ClassNotFoundException e) { // try the older generated client suffix return Class.forName(implementationClassName(clientInterface, "$HttpClient")); } } private String implementationClassName(Class clientInterface, String suffix) { - String packageName = clientInterface.getPackageName(); - String simpleName = clientInterface.getSimpleName(); + final String packageName = clientInterface.getPackageName(); + final String simpleName = clientInterface.getSimpleName(); return packageName + ".httpclient." + simpleName + suffix; } @@ -202,7 +213,7 @@ public BodyContent readErrorContent(boolean responseAsBytes, HttpResponse htt if (body instanceof String) { return new BodyContent(contentType, ((String) body).getBytes(StandardCharsets.UTF_8)); } - String type = (body == null) ? "null" : body.getClass().toString(); + final String type = (body == null) ? "null" : body.getClass().toString(); throw new IllegalStateException("Unable to translate response body to bytes? Maybe use HttpResponse directly instead? Response body type: " + type); } @@ -212,7 +223,7 @@ public BodyContent readContent(HttpResponse httpResponse) { if (body != null && body.length > 0) { metricResBytes.add(body.length); } - byte[] bodyBytes = decodeContent(httpResponse); + final byte[] bodyBytes = decodeContent(httpResponse); final String contentType = getContentType(httpResponse); return new BodyContent(contentType, bodyBytes); } @@ -227,21 +238,22 @@ String getContentEncoding(HttpResponse httpResponse) { @Override public byte[] decodeContent(String encoding, byte[] body) { - if (encoding.equals("gzip")) { + if ("gzip".equals(encoding)) { return GzipUtil.gzipDecode(body); } // todo: register decoders with context and use them return body; } - public byte[] decodeContent(HttpResponse httpResponse) { - String encoding = getContentEncoding(httpResponse); + @Override +public byte[] decodeContent(HttpResponse httpResponse) { + final String encoding = getContentEncoding(httpResponse); return encoding == null ? httpResponse.body() : decodeContent(encoding, httpResponse.body()); } String firstHeader(HttpHeaders headers, String... names) { final Map> map = headers.map(); - for (String key : names) { + for (final String key : names) { final List values = map.get(key); if (values != null && !values.isEmpty()) { return values.get(0); @@ -253,9 +265,9 @@ String firstHeader(HttpHeaders headers, String... names) { HttpResponse send(HttpRequest.Builder requestBuilder, HttpResponse.BodyHandler bodyHandler) { try { return httpClient.send(requestBuilder.build(), bodyHandler); - } catch (IOException e) { + } catch (final IOException e) { throw new HttpException(499, e); - } catch (InterruptedException e) { + } catch (final InterruptedException e) { Thread.currentThread().interrupt(); throw new HttpException(499, e); } diff --git a/http-client/src/main/java/io/avaje/http/client/HttpApiProvider.java b/http-client/src/main/java/io/avaje/http/client/HttpApiProvider.java index 9936f1749..e4ed08d8a 100644 --- a/http-client/src/main/java/io/avaje/http/client/HttpApiProvider.java +++ b/http-client/src/main/java/io/avaje/http/client/HttpApiProvider.java @@ -1,20 +1,20 @@ package io.avaje.http.client; +import java.util.Map; + /** * Provides http client implementations for an interface. * * @param The interface type */ +@FunctionalInterface public interface HttpApiProvider { - /** - * Return the interface type this API implements. - */ - Class type(); + /** Return the interface type this API implements. */ + default Class type() { + throw new UnsupportedOperationException(); + } - /** - * Return the provided implementation of the API. - */ + /** Return the provided implementation of the API. */ T provide(HttpClient client); - } diff --git a/http-client/src/main/java/io/avaje/http/client/HttpClient.java b/http-client/src/main/java/io/avaje/http/client/HttpClient.java index b4722c1c6..b293eb69f 100644 --- a/http-client/src/main/java/io/avaje/http/client/HttpClient.java +++ b/http-client/src/main/java/io/avaje/http/client/HttpClient.java @@ -1,15 +1,17 @@ package io.avaje.http.client; -import io.avaje.inject.BeanScope; - -import javax.net.ssl.SSLContext; -import javax.net.ssl.SSLParameters; import java.net.Authenticator; import java.net.CookieHandler; import java.net.ProxySelector; import java.time.Duration; +import java.util.Map; import java.util.concurrent.Executor; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLParameters; + +import io.avaje.inject.BeanScope; + /** * The HTTP client context that we use to build and process requests. * @@ -356,4 +358,11 @@ interface State { interface Metrics extends HttpClientContext.Metrics { } + + /** Components register Generated Client interface Providers */ + @FunctionalInterface + interface GeneratedComponent { + + void register(Map, HttpApiProvider> providerMap); + } } diff --git a/http-client/src/main/java/module-info.java b/http-client/src/main/java/module-info.java index 56ad106f8..d5d23f60f 100644 --- a/http-client/src/main/java/module-info.java +++ b/http-client/src/main/java/module-info.java @@ -1,6 +1,7 @@ module io.avaje.http.client { uses io.avaje.http.client.HttpApiProvider; + uses io.avaje.http.client.HttpClient.GeneratedComponent; requires transitive java.net.http; requires transitive io.avaje.applog; diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index 072e85847..c6923d654 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -21,6 +21,19 @@ ${project.version} + + io.avaje + avaje-http-client + test + ${project.version} + + + io.avaje + avaje-http-api + test + ${project.version} + + @@ -36,6 +49,14 @@ -proc:none + + org.apache.maven.plugins + maven-surefire-plugin + ${maven-surefire-plugin.version} + + false + + diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java index 18ad8bcb2..dc214a7b7 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java @@ -1,8 +1,11 @@ package io.avaje.http.generator.client; import static io.avaje.http.generator.core.ProcessingContext.*; +import static io.avaje.http.generator.core.ProcessingContext.platform; +import static io.avaje.http.generator.core.ProcessingContext.setPlatform; +import static io.avaje.http.generator.core.ProcessingContext.typeElement; + import java.io.IOException; -import java.io.Writer; import java.util.LinkedHashSet; import java.util.Objects; import java.util.Set; @@ -14,7 +17,6 @@ import javax.lang.model.SourceVersion; import javax.lang.model.element.Element; import javax.lang.model.element.TypeElement; -import javax.tools.FileObject; import io.avaje.http.generator.core.ClientPrism; import io.avaje.http.generator.core.ControllerReader; @@ -25,8 +27,6 @@ @SupportedAnnotationTypes({ClientPrism.PRISM_TYPE, ImportPrism.PRISM_TYPE}) public class ClientProcessor extends AbstractProcessor { - private static final String METAINF_SERVICES_PROVIDER = "META-INF/services/io.avaje.http.client.HttpApiProvider"; - private final Set generatedClients = new LinkedHashSet<>(); private final boolean useJsonB; @@ -61,29 +61,16 @@ public boolean process(Set annotations, RoundEnvironment for (final Element controller : round.getElementsAnnotatedWith(typeElement(ClientPrism.PRISM_TYPE))) { writeClient(controller); } - for (final Element importedElement : round.getElementsAnnotatedWith(typeElement(ImportPrism.PRISM_TYPE))) { + for (final var importedElement : round.getElementsAnnotatedWith(typeElement(ImportPrism.PRISM_TYPE))) { writeForImported(importedElement); } - if (round.processingOver()) { - writeServicesFile(); - } + + writeComponent(round.processingOver()); + setPlatform(platform); return false; } - private void writeServicesFile() { - try { - final FileObject metaInfWriter = createMetaInfWriter(METAINF_SERVICES_PROVIDER); - final Writer writer = metaInfWriter.openWriter(); - for (String generatedClient : generatedClients) { - writer.append(generatedClient).append("$Provider\n"); - } - writer.close(); - } catch (IOException e) { - logError(null, "Error writing services file " + e, e); - } - } - private void writeForImported(Element importedElement) { ImportPrism.getInstanceOn(importedElement).types().stream() .map(ProcessingContext::asElement) @@ -93,11 +80,11 @@ private void writeForImported(Element importedElement) { private void writeClient(Element controller) { if (controller instanceof TypeElement) { - ControllerReader reader = new ControllerReader((TypeElement) controller); + final ControllerReader reader = new ControllerReader((TypeElement) controller); reader.read(false); try { generatedClients.add(writeClientAdapter(reader)); - } catch (Throwable e) { + } catch (final Throwable e) { e.printStackTrace(); logError(reader.beanType(), "Failed to write client class " + e); } @@ -108,4 +95,13 @@ protected String writeClientAdapter(ControllerReader reader) throws IOException return new ClientWriter(reader, useJsonB).write(); } + private void writeComponent(boolean processingOver) { + if (processingOver) { + try { + new SimpleComponentWriter(generatedClients).write(); + } catch (final IOException e) { + logError("Error writing component", e); + } + } + } } diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientWriter.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientWriter.java index fcc098ccf..8fba4298b 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientWriter.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientWriter.java @@ -15,7 +15,6 @@ class ClientWriter extends BaseControllerWriter { private static final String HTTP_CLIENT = "io.avaje.http.client.HttpClient"; - private static final String HTTP_API_PROVIDER = "io.avaje.http.client.HttpApiProvider"; private static final String AT_GENERATED = "@Generated(\"avaje-http-client-generator\")"; private static final String SUFFIX = "HttpClient"; @@ -26,7 +25,6 @@ class ClientWriter extends BaseControllerWriter { ClientWriter(ControllerReader reader, boolean useJsonB) throws IOException { super(reader, SUFFIX); reader.addImportType(HTTP_CLIENT); - reader.addImportType(HTTP_API_PROVIDER); this.useJsonb = useJsonB; readMethods(); if (useJsonB) reader.addImportType("io.avaje.jsonb.Types"); @@ -39,7 +37,7 @@ protected String initPackageName(String originName) { } private void readMethods() { - for (MethodReader method : reader.methods()) { + for (final MethodReader method : reader.methods()) { if (method.isWebMethod()) { final var methodWriter = new ClientMethodWriter(method, writer, useJsonb); methodWriter.addImportTypes(reader); @@ -53,26 +51,12 @@ String write() { writeImports(); writeClassStart(); writeMethods(); - writeProvider(); writeClassEnd(); return fullName; } - private void writeProvider() { - writer.append(" public static class Provider implements HttpApiProvider<%s> {", shortName).eol(); - writer.append(" @Override").eol(); - writer.append(" public Class<%s> type() {", shortName).eol(); - writer.append(" return %s.class;", shortName).eol(); - writer.append(" }").eol(); - writer.append(" @Override").eol(); - writer.append(" public %s provide(HttpClient client) {", shortName).eol(); - writer.append(" return new %s%s(client);", shortName, SUFFIX).eol(); - writer.append(" }").eol(); - writer.append(" }").eol(); - } - private void writeMethods() { - for (ClientMethodWriter methodWriter : methodList) { + for (final ClientMethodWriter methodWriter : methodList) { methodWriter.write(); } } diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/SimpleComponentWriter.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/SimpleComponentWriter.java new file mode 100644 index 000000000..ded2f85f4 --- /dev/null +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/SimpleComponentWriter.java @@ -0,0 +1,124 @@ +package io.avaje.http.generator.client; + +import static io.avaje.http.generator.core.ProcessingContext.createMetaInfWriter; +import static io.avaje.http.generator.core.ProcessingContext.createWriter; + +import java.io.IOException; +import java.io.Writer; +import java.util.Set; +import java.util.TreeSet; + +import javax.tools.FileObject; +import javax.tools.JavaFileObject; + +import io.avaje.http.generator.core.Append; +import io.avaje.http.generator.core.Util; + +final class SimpleComponentWriter { + + private static final String AT_GENERATED = "@Generated(\"avaje-client-generator\")"; + + private final Set generatedClients; + private final Set importTypes = new TreeSet<>(); + private Append writer; + private final JavaFileObject fileObject; + private final String fullName; + + SimpleComponentWriter(Set generatedClients) throws IOException { + this.generatedClients = generatedClients; + this.fullName = fullName(); + fileObject = createWriter(fullName()); + } + + String fullName() { + String topPackage = TopPackage.of(generatedClients); + if (!topPackage.endsWith(".httpclient")) { + topPackage += ".httpclient"; + } + return topPackage + ".GeneratedHttpComponent"; + } + + void write() throws IOException { + writer = new Append(fileObject.openWriter()); + writePackage(); + writeImports(); + writeClassStart(); + writeRegister(); + writeClassEnd(); + writer.close(); + writeMetaInf(); + } + + void writeMetaInf() throws IOException { + final FileObject fileObject = + createMetaInfWriter("META-INF/services/io.avaje.http.client.HttpClient$GeneratedComponent"); + if (fileObject != null) { + try (var fileWriter = fileObject.openWriter()) { + fileWriter.write(fullName); + } + } + } + + private void writeRegister() { + writer.append(" @Override").eol(); + writer.append(" public void register(Map, HttpApiProvider> providerMap) {").eol(); + + for (final String clientFullName : generatedClients) { + + final String clientShortName = Util.shortName(clientFullName); + final var clientInterface = removeLast(clientShortName, "HttpClient"); + writer + .append(" providerMap.put(%s.class, %s::new);", clientInterface, clientShortName) + .eol(); + } + writer.append(" }").eol().eol(); + } + + private void writeClassEnd() { + writer.append("}").eol(); + } + + private void writeClassStart() { + final String shortName = Util.shortName(fullName); + writer.append(AT_GENERATED).eol(); + writer + .append("public class %s implements HttpClient.GeneratedComponent {", shortName) + .eol() + .eol(); + } + + private void writeImports() { + importTypes.add("io.avaje.http.client.HttpClient"); + importTypes.add("io.avaje.http.client.HttpApiProvider"); + importTypes.add("java.util.Map"); + importTypes.add("io.avaje.http.api.Generated"); + + importTypes.addAll(generatedClients); + generatedClients.stream() + .map(s -> removeLast(removeLast(s, ".httpclient"), "HttpClient")) + .forEach(importTypes::add); + + for (final String importType : importTypes) { + writer.append("import %s;", importType).eol(); + writer.append("import %s;", importType).eol(); + } + writer.eol(); + } + + public static String removeLast(String s, String search) { + final int pos = s.lastIndexOf(search); + + if (pos > -1) { + return s.substring(0, pos) + s.substring(pos + search.length()); + } + + return s; + } + + private void writePackage() { + final String packageName = TopPackage.packageOf(fullName); + if (packageName != null && !packageName.isEmpty()) { + writer.append("package %s;", packageName).eol().eol(); + } + } +} diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/TopPackage.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/TopPackage.java new file mode 100644 index 000000000..a0df52b1e --- /dev/null +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/TopPackage.java @@ -0,0 +1,48 @@ +package io.avaje.http.generator.client; + +import java.util.Collection; + +final class TopPackage { + + private String topPackage; + + static String of(Collection values) { + return new TopPackage(values).value(); + } + + private String value() { + return topPackage; + } + + private TopPackage(Collection values) { + for (final String pkg : values) { + topPackage = commonParent(topPackage, pkg); + } + } + + /** Return the common parent package. */ + static String commonParent(String currentTop, String aPackage) { + if (aPackage == null) return currentTop; + if (currentTop == null) return packageOf(aPackage); + if (aPackage.startsWith(currentTop)) { + return currentTop; + } + int next; + do { + next = currentTop.lastIndexOf('.'); + if (next > -1) { + currentTop = currentTop.substring(0, next); + if (aPackage.startsWith(currentTop)) { + return currentTop; + } + } + } while (next > -1); + + return currentTop; + } + + static String packageOf(String cls) { + final int pos = cls.lastIndexOf('.'); + return (pos == -1) ? "" : cls.substring(0, pos); + } +} diff --git a/http-generator-client/src/test/java/io/avaje/http/generator/client/ClientProcessorTest.java b/http-generator-client/src/test/java/io/avaje/http/generator/client/ClientProcessorTest.java new file mode 100644 index 000000000..645198b29 --- /dev/null +++ b/http-generator-client/src/test/java/io/avaje/http/generator/client/ClientProcessorTest.java @@ -0,0 +1,68 @@ +package io.avaje.http.generator.client; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.io.File; +import java.io.IOException; +import java.io.PrintWriter; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +import java.util.Set; + +import javax.tools.JavaCompiler; +import javax.tools.JavaCompiler.CompilationTask; +import javax.tools.JavaFileObject; +import javax.tools.JavaFileObject.Kind; +import javax.tools.StandardJavaFileManager; +import javax.tools.StandardLocation; +import javax.tools.ToolProvider; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; + +class ClientProcessorTest { + + @AfterEach + void deleteGeneratedFiles() throws IOException { + try { + Paths.get("io.avaje.http.client.HttpClient$GeneratedComponent") + .toAbsolutePath() + .toFile() + .delete(); + Files.walk(Paths.get("io").toAbsolutePath()) + .sorted(Comparator.reverseOrder()) + .map(Path::toFile) + .forEach(File::delete); + } catch (final Exception e) { + } + } + + @Test + void testGeneration() throws Exception { + final Iterable files = getSourceFiles("src/test/java/"); + + final JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); + + final CompilationTask task = + compiler.getTask( + new PrintWriter(System.out), null, null, Arrays.asList("--release=11"), null, files); + task.setProcessors(Arrays.asList(new ClientProcessor())); + + assertThat(task.call()).isTrue(); + } + + private Iterable getSourceFiles(String source) throws Exception { + final var compiler = ToolProvider.getSystemJavaCompiler(); + final var files = compiler.getStandardFileManager(null, null, null); + + files.setLocation(StandardLocation.SOURCE_PATH, List.of(new File(source))); + + final Set fileKinds = Collections.singleton(Kind.SOURCE); + return files.list(StandardLocation.SOURCE_PATH, "", fileKinds, true); + } +} diff --git a/http-generator-client/src/test/java/io/avaje/http/generator/client/clients/ApiClient.java b/http-generator-client/src/test/java/io/avaje/http/generator/client/clients/ApiClient.java new file mode 100644 index 000000000..37c22d1a8 --- /dev/null +++ b/http-generator-client/src/test/java/io/avaje/http/generator/client/clients/ApiClient.java @@ -0,0 +1,12 @@ +package io.avaje.http.generator.client.clients; + +import io.avaje.http.api.Client; +import io.avaje.http.api.Get; +import io.avaje.http.api.Header; + +@Client +public interface ApiClient { + + @Get("/inputstream") + String apiCall(@Header("Accept") String accept); +} diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java index e778d0cff..1f2e333f6 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java @@ -108,6 +108,10 @@ public static boolean useComponent() { return CTX.get().useComponent; } + public static void logError(String msg, Object... args) { + CTX.get().messager.printMessage(Diagnostic.Kind.ERROR, String.format(msg, args)); + } + public static void logError(Element e, String msg, Object... args) { CTX.get().messager.printMessage(Diagnostic.Kind.ERROR, String.format(msg, args), e); } @@ -122,6 +126,10 @@ public static FileObject createMetaInfWriter(String target) throws IOException { return CTX.get().filer.createResource(StandardLocation.CLASS_OUTPUT, "", target); } + public static JavaFileObject createWriter(String cls) throws IOException { + return CTX.get().filer.createSourceFile(cls); + } + public static String docComment(Element param) { return CTX.get().elementUtils.getDocComment(param); } diff --git a/pom.xml b/pom.xml index e8586008b..8f69f11b1 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ org.avaje java11-oss - 3.9 + 3.10 io.avaje From 454aae7d18496077fe8de827966bc0cf385463b8 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Mon, 29 May 2023 09:56:07 -0400 Subject: [PATCH 0749/1323] Update GithubTest.java --- .../src/test/java/example/github/GithubTest.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/test-client/src/test/java/example/github/GithubTest.java b/tests/test-client/src/test/java/example/github/GithubTest.java index 5bfdfa284..36e501f15 100644 --- a/tests/test-client/src/test/java/example/github/GithubTest.java +++ b/tests/test-client/src/test/java/example/github/GithubTest.java @@ -14,6 +14,14 @@ class GithubTest { + @Test + void test_create() { + final HttpClient client = HttpClient.builder().baseUrl("https://api.github.com").build(); + + final Simple simple = client.create(Simple.class); + assertThat(simple).isNotNull(); + } + @Disabled @Test void test_with_jackson() { From 920a8a1e40b694670ff529a9f09258420e60a635 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Mon, 29 May 2023 09:58:11 -0400 Subject: [PATCH 0750/1323] Update DHttpApi.java --- http-client/src/main/java/io/avaje/http/client/DHttpApi.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/http-client/src/main/java/io/avaje/http/client/DHttpApi.java b/http-client/src/main/java/io/avaje/http/client/DHttpApi.java index 0f03dafba..73de1df33 100644 --- a/http-client/src/main/java/io/avaje/http/client/DHttpApi.java +++ b/http-client/src/main/java/io/avaje/http/client/DHttpApi.java @@ -20,7 +20,7 @@ final class DHttpApi { private final Map, HttpApiProvider> providerMap = new HashMap<>(); - private DHttpApi() { + DHttpApi() { init(); } From 7e3643196f380376cd0b9a73d58358c457d441a0 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Mon, 29 May 2023 10:06:02 -0400 Subject: [PATCH 0751/1323] Update DHttpApi.java --- .../src/main/java/io/avaje/http/client/DHttpApi.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/http-client/src/main/java/io/avaje/http/client/DHttpApi.java b/http-client/src/main/java/io/avaje/http/client/DHttpApi.java index 73de1df33..880371c52 100644 --- a/http-client/src/main/java/io/avaje/http/client/DHttpApi.java +++ b/http-client/src/main/java/io/avaje/http/client/DHttpApi.java @@ -27,7 +27,7 @@ final class DHttpApi { @SuppressWarnings("rawtypes") void init() { for (final HttpApiProvider apiProvider : ServiceLoader.load(HttpApiProvider.class)) { - providerMap.put(apiProvider.type(), apiProvider); + addProvider(apiProvider); } for (final GeneratedComponent apiProvider : ServiceLoader.load(GeneratedComponent.class)) { @@ -37,6 +37,10 @@ void init() { log.log(DEBUG, "providers for {0}", providerMap.keySet()); } + void addProvider(HttpApiProvider apiProvider) { + providerMap.put(apiProvider.type(), apiProvider); + } + @SuppressWarnings("unchecked") private HttpApiProvider lookup(Class type) { return (HttpApiProvider) providerMap.get(type); From c18e798907546d270cb6a15cb35526bfa48fdbe5 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Mon, 29 May 2023 10:14:47 -0400 Subject: [PATCH 0752/1323] Update DHttpClientContext.java --- .../src/main/java/io/avaje/http/client/DHttpClientContext.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/http-client/src/main/java/io/avaje/http/client/DHttpClientContext.java b/http-client/src/main/java/io/avaje/http/client/DHttpClientContext.java index fb149f2b2..e1a386d01 100644 --- a/http-client/src/main/java/io/avaje/http/client/DHttpClientContext.java +++ b/http-client/src/main/java/io/avaje/http/client/DHttpClientContext.java @@ -246,7 +246,7 @@ public byte[] decodeContent(String encoding, byte[] body) { } @Override -public byte[] decodeContent(HttpResponse httpResponse) { + public byte[] decodeContent(HttpResponse httpResponse) { final String encoding = getContentEncoding(httpResponse); return encoding == null ? httpResponse.body() : decodeContent(encoding, httpResponse.body()); } From 4e77fddda68678f64bbcf45b44eae65c43385f41 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Mon, 29 May 2023 23:58:48 -0400 Subject: [PATCH 0753/1323] partial compile stuff --- .../java/io/avaje/http/api/spi/MetaData.java | 18 ++++ http-api/src/main/java/module-info.java | 1 + http-generator-client/pom.xml | 25 +++-- .../generator/client/ClientProcessor.java | 41 +++++++-- .../generator/client/ComponentMetaData.java | 71 +++++++++++++++ .../generator/client/ComponentReader.java | 91 +++++++++++++++++++ .../client/SimpleComponentWriter.java | 54 ++++++----- .../src/main/java/module-info.java | 4 +- http-generator-core/pom.xml | 2 +- .../avaje/http/generator/core/Constants.java | 2 + .../generator/core/ProcessingContext.java | 11 +++ pom.xml | 1 + 12 files changed, 282 insertions(+), 39 deletions(-) create mode 100644 http-api/src/main/java/io/avaje/http/api/spi/MetaData.java create mode 100644 http-generator-client/src/main/java/io/avaje/http/generator/client/ComponentMetaData.java create mode 100644 http-generator-client/src/main/java/io/avaje/http/generator/client/ComponentReader.java diff --git a/http-api/src/main/java/io/avaje/http/api/spi/MetaData.java b/http-api/src/main/java/io/avaje/http/api/spi/MetaData.java new file mode 100644 index 000000000..0addc046d --- /dev/null +++ b/http-api/src/main/java/io/avaje/http/api/spi/MetaData.java @@ -0,0 +1,18 @@ +package io.avaje.http.api.spi; + +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.CLASS; + +import java.lang.annotation.*; + +/** + * For internal use, holds metadata on generated client interfaces for use by code generation (Java + * annotation processing). + */ +@Target(TYPE) +@Retention(CLASS) +public @interface MetaData { + + /** The generated HttpClient interfaces. */ + Class[] value(); +} diff --git a/http-api/src/main/java/module-info.java b/http-api/src/main/java/module-info.java index 71c803543..5fe2e429f 100644 --- a/http-api/src/main/java/module-info.java +++ b/http-api/src/main/java/module-info.java @@ -2,4 +2,5 @@ exports io.avaje.http.api; exports io.avaje.http.api.context; + exports io.avaje.http.api.spi; } diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index c6923d654..73c5158ed 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -11,10 +11,16 @@ 11 + 1.9 - - + + io.avaje + avaje-prisms + ${avaje.prisms.version} + true + provided + io.avaje avaje-http-generator-core @@ -30,8 +36,9 @@ io.avaje avaje-http-api - test ${project.version} + true + provided @@ -41,12 +48,14 @@ org.apache.maven.plugins maven-compiler-plugin - 3.10.1 - 11 - 11 - - -proc:none + + + io.avaje + avaje-prisms + ${avaje.prisms.version} + + diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java index dc214a7b7..e93e53b55 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java @@ -1,12 +1,11 @@ package io.avaje.http.generator.client; -import static io.avaje.http.generator.core.ProcessingContext.*; +import static io.avaje.http.generator.core.ProcessingContext.logError; import static io.avaje.http.generator.core.ProcessingContext.platform; import static io.avaje.http.generator.core.ProcessingContext.setPlatform; import static io.avaje.http.generator.core.ProcessingContext.typeElement; import java.io.IOException; -import java.util.LinkedHashSet; import java.util.Objects; import java.util.Set; @@ -27,10 +26,14 @@ @SupportedAnnotationTypes({ClientPrism.PRISM_TYPE, ImportPrism.PRISM_TYPE}) public class ClientProcessor extends AbstractProcessor { - private final Set generatedClients = new LinkedHashSet<>(); + private final ComponentMetaData metaData = new ComponentMetaData(); private final boolean useJsonB; + private SimpleComponentWriter componentWriter; + + private boolean readModuleInfo; + public ClientProcessor() { useJsonB = JsonBUtil.detectJsonb(); } @@ -49,6 +52,8 @@ public synchronized void init(ProcessingEnvironment processingEnv) { super.init(processingEnv); this.processingEnv = processingEnv; ProcessingContext.init(processingEnv, new ClientPlatformAdapter(), false); + + this.componentWriter = new SimpleComponentWriter(metaData); } @Override @@ -57,11 +62,13 @@ public boolean process(Set annotations, RoundEnvironment if (!(platform instanceof ClientPlatformAdapter)) { setPlatform(new ClientPlatformAdapter()); } - - for (final Element controller : round.getElementsAnnotatedWith(typeElement(ClientPrism.PRISM_TYPE))) { + readModule(); + for (final Element controller : + round.getElementsAnnotatedWith(typeElement(ClientPrism.PRISM_TYPE))) { writeClient(controller); } - for (final var importedElement : round.getElementsAnnotatedWith(typeElement(ImportPrism.PRISM_TYPE))) { + for (final var importedElement : + round.getElementsAnnotatedWith(typeElement(ImportPrism.PRISM_TYPE))) { writeForImported(importedElement); } @@ -70,6 +77,14 @@ public boolean process(Set annotations, RoundEnvironment setPlatform(platform); return false; } + /** Read the existing metadata from the generated component (if exists). */ + private void readModule() { + if (readModuleInfo) { + return; + } + readModuleInfo = true; + new ComponentReader(metaData).read(); + } private void writeForImported(Element importedElement) { ImportPrism.getInstanceOn(importedElement).types().stream() @@ -83,7 +98,7 @@ private void writeClient(Element controller) { final ControllerReader reader = new ControllerReader((TypeElement) controller); reader.read(false); try { - generatedClients.add(writeClientAdapter(reader)); + metaData.add(writeClientAdapter(reader)); } catch (final Throwable e) { e.printStackTrace(); logError(reader.beanType(), "Failed to write client class " + e); @@ -95,10 +110,20 @@ protected String writeClientAdapter(ControllerReader reader) throws IOException return new ClientWriter(reader, useJsonB).write(); } + private void initialiseComponent() { + metaData.initialiseFullName(); + try { + componentWriter.init(); + } catch (final IOException e) { + logError("Error creating writer for JsonbComponent", e); + } + } + private void writeComponent(boolean processingOver) { + initialiseComponent(); if (processingOver) { try { - new SimpleComponentWriter(generatedClients).write(); + componentWriter.write(); } catch (final IOException e) { logError("Error writing component", e); } diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ComponentMetaData.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ComponentMetaData.java new file mode 100644 index 000000000..946b1efbc --- /dev/null +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ComponentMetaData.java @@ -0,0 +1,71 @@ +package io.avaje.http.generator.client; + +import java.util.*; + +final class ComponentMetaData { + + private final List generatedClients = new ArrayList<>(); + private String fullName; + + @Override + public String toString() { + return generatedClients.toString(); + } + + /** Ensure the component name has been initialised. */ + void initialiseFullName() { + fullName(); + } + + boolean contains(String type) { + return generatedClients.contains(type); + } + + void add(String type) { + generatedClients.add(type); + } + + void setFullName(String fullName) { + this.fullName = fullName; + } + + String fullName() { + if (fullName == null) { + + String topPackage = TopPackage.of(generatedClients); + if (!topPackage.endsWith(".httpclient")) { + topPackage += ".httpclient"; + } + fullName = topPackage + ".GeneratedHttpComponent"; + } + return fullName; + } + + String packageName() { + return TopPackage.packageOf(fullName()); + } + + List all() { + return generatedClients; + } + + /** Return the package imports for the JsonAdapters and related types. */ + Collection allImports() { + final Set packageImports = new TreeSet<>(generatedClients); + generatedClients.stream() + .map(s -> removeLast(removeLast(s, ".httpclient"), "HttpClient")) + .forEach(packageImports::add); + + return packageImports; + } + + public static String removeLast(String s, String search) { + final int pos = s.lastIndexOf(search); + + if (pos > -1) { + return s.substring(0, pos) + s.substring(pos + search.length()); + } + + return s; + } +} diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ComponentReader.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ComponentReader.java new file mode 100644 index 000000000..88084c99e --- /dev/null +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ComponentReader.java @@ -0,0 +1,91 @@ +package io.avaje.http.generator.client; +import static io.avaje.http.generator.core.ProcessingContext.filer; +import static io.avaje.http.generator.core.ProcessingContext.logDebug; +import static io.avaje.http.generator.core.ProcessingContext.logWarn; +import static io.avaje.http.generator.core.ProcessingContext.typeElement; + +import java.io.FileNotFoundException; +import java.io.LineNumberReader; +import java.io.Reader; +import java.nio.file.NoSuchFileException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import javax.annotation.processing.FilerException; +import javax.lang.model.element.AnnotationMirror; +import javax.lang.model.element.TypeElement; +import javax.lang.model.type.TypeMirror; +import javax.tools.FileObject; +import javax.tools.StandardLocation; + +import io.avaje.http.generator.core.Constants; +import io.avaje.prism.GeneratePrism; + +@GeneratePrism(io.avaje.http.api.spi.MetaData.class) +final class ComponentReader { + + private final ComponentMetaData componentMetaData; + + ComponentReader(ComponentMetaData metaData) { + this.componentMetaData = metaData; + } + + void read() { + final String componentFullName = loadMetaInfServices(); + if (componentFullName != null) { + final TypeElement moduleType = typeElement(componentFullName); + if (moduleType != null) { + componentMetaData.setFullName(componentFullName); + readMetaData(moduleType); + } + } + } + + /** Read the existing JsonAdapters from the MetaData annotation of the generated component. */ + private void readMetaData(TypeElement moduleType) { + for (final AnnotationMirror annotationMirror : moduleType.getAnnotationMirrors()) { + MetaDataPrism.getOptional(annotationMirror).map(MetaDataPrism::value).stream() + .flatMap(List::stream) + .map(TypeMirror::toString) + .forEach(componentMetaData::add); + } + } + + private String loadMetaInfServices() { + final List lines = loadMetaInf(); + return lines.isEmpty() ? null : lines.get(0); + } + + private List loadMetaInf() { + try { + final FileObject fileObject = filer() + .getResource(StandardLocation.CLASS_OUTPUT, "", Constants.META_INF_COMPONENT); + + if (fileObject != null) { + final List lines = new ArrayList<>(); + final Reader reader = fileObject.openReader(true); + final LineNumberReader lineReader = new LineNumberReader(reader); + String line; + while ((line = lineReader.readLine()) != null) { + line = line.trim(); + if (!line.isEmpty()) { + lines.add(line); + } + } + return lines; + } + + } catch (FileNotFoundException | NoSuchFileException e) { + // logDebug("no services file yet"); + + } catch (final FilerException e) { + logDebug("FilerException reading services file"); + + } catch (final Exception e) { + e.printStackTrace(); + logWarn("Error reading services file: " + e.getMessage()); + } + return Collections.emptyList(); + } +} diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/SimpleComponentWriter.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/SimpleComponentWriter.java index ded2f85f4..e363174ff 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/SimpleComponentWriter.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/SimpleComponentWriter.java @@ -4,7 +4,7 @@ import static io.avaje.http.generator.core.ProcessingContext.createWriter; import java.io.IOException; -import java.io.Writer; +import java.util.List; import java.util.Set; import java.util.TreeSet; @@ -12,30 +12,32 @@ import javax.tools.JavaFileObject; import io.avaje.http.generator.core.Append; +import io.avaje.http.generator.core.Constants; import io.avaje.http.generator.core.Util; final class SimpleComponentWriter { private static final String AT_GENERATED = "@Generated(\"avaje-client-generator\")"; - private final Set generatedClients; + private final ComponentMetaData metaData; private final Set importTypes = new TreeSet<>(); private Append writer; - private final JavaFileObject fileObject; - private final String fullName; + private JavaFileObject fileObject; + private String fullName; - SimpleComponentWriter(Set generatedClients) throws IOException { - this.generatedClients = generatedClients; - this.fullName = fullName(); - fileObject = createWriter(fullName()); + SimpleComponentWriter(ComponentMetaData metaData) { + this.metaData = metaData; } - String fullName() { - String topPackage = TopPackage.of(generatedClients); - if (!topPackage.endsWith(".httpclient")) { - topPackage += ".httpclient"; + void init() throws IOException { + + if (fullName == null) { + this.fullName = metaData.fullName(); + } + + if (fileObject == null) { + fileObject = createWriter(metaData.fullName()); } - return topPackage + ".GeneratedHttpComponent"; } void write() throws IOException { @@ -50,8 +52,7 @@ void write() throws IOException { } void writeMetaInf() throws IOException { - final FileObject fileObject = - createMetaInfWriter("META-INF/services/io.avaje.http.client.HttpClient$GeneratedComponent"); + final FileObject fileObject = createMetaInfWriter(Constants.META_INF_COMPONENT); if (fileObject != null) { try (var fileWriter = fileObject.openWriter()) { fileWriter.write(fullName); @@ -63,7 +64,7 @@ private void writeRegister() { writer.append(" @Override").eol(); writer.append(" public void register(Map, HttpApiProvider> providerMap) {").eol(); - for (final String clientFullName : generatedClients) { + for (final String clientFullName : metaData.all()) { final String clientShortName = Util.shortName(clientFullName); final var clientInterface = removeLast(clientShortName, "HttpClient"); @@ -81,22 +82,33 @@ private void writeClassEnd() { private void writeClassStart() { final String shortName = Util.shortName(fullName); writer.append(AT_GENERATED).eol(); + + writer.append("@MetaData({"); + final List all = metaData.all(); + writeMetaDataEntry(all); + writer.append("})").eol(); writer .append("public class %s implements HttpClient.GeneratedComponent {", shortName) .eol() .eol(); } + private void writeMetaDataEntry(List entries) { + for (int i = 0, size = entries.size(); i < size; i++) { + if (i > 0) { + writer.append(", "); + } + writer.append("%s.class", Util.shortName(entries.get(i))); + } + } + private void writeImports() { importTypes.add("io.avaje.http.client.HttpClient"); importTypes.add("io.avaje.http.client.HttpApiProvider"); importTypes.add("java.util.Map"); importTypes.add("io.avaje.http.api.Generated"); - - importTypes.addAll(generatedClients); - generatedClients.stream() - .map(s -> removeLast(removeLast(s, ".httpclient"), "HttpClient")) - .forEach(importTypes::add); + importTypes.add("io.avaje.http.api.spi.MetaData"); + importTypes.addAll(metaData.allImports()); for (final String importType : importTypes) { writer.append("import %s;", importType).eol(); diff --git a/http-generator-client/src/main/java/module-info.java b/http-generator-client/src/main/java/module-info.java index 09c6b3e21..ea6d43cc0 100644 --- a/http-generator-client/src/main/java/module-info.java +++ b/http-generator-client/src/main/java/module-info.java @@ -6,6 +6,8 @@ requires java.sql; // SHADED: All content after this line will be removed at package time - requires transitive io.avaje.http.generator.core; + requires io.avaje.http.generator.core; + requires static io.avaje.http.api; + requires static io.avaje.prism; } diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 13d416bb2..460dbe44c 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -10,7 +10,7 @@ avaje-http-generator-core - 1.8 + 1.9 diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/Constants.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/Constants.java index ebe5d7ec2..75d58dd2e 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/Constants.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/Constants.java @@ -18,5 +18,7 @@ public class Constants { static final String IMPORT_HTTP_API = "io.avaje.http.api.*"; static final String VALIDATOR = "io.avaje.http.api.Validator"; + public static final String META_INF_COMPONENT = "META-INF/services/io.avaje.http.client.HttpClient$GeneratedComponent"; + } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java index 1f2e333f6..ba60509ec 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java @@ -116,6 +116,13 @@ public static void logError(Element e, String msg, Object... args) { CTX.get().messager.printMessage(Diagnostic.Kind.ERROR, String.format(msg, args), e); } + public static void logWarn(String msg, Object... args) { + CTX.get().messager.printMessage(Diagnostic.Kind.WARNING, String.format(msg, args)); + } + + public static void logDebug(String msg, Object... args) { + CTX.get().messager.printMessage(Diagnostic.Kind.NOTE, String.format(msg, args)); + } /** Create a file writer for the given class name. */ public static JavaFileObject createWriter(String cls, Element origin) throws IOException { return CTX.get().filer.createSourceFile(cls, origin); @@ -176,4 +183,8 @@ public static String diAnnotation() { public static boolean instrumentAllWebMethods() { return CTX.get().instrumentAllMethods; } + + public static Filer filer() { + return CTX.get().filer; + } } diff --git a/pom.xml b/pom.xml index 8f69f11b1..8581aa5a9 100644 --- a/pom.xml +++ b/pom.xml @@ -21,6 +21,7 @@ true 2.2.8 2.14.2 + 1.9 ${project.build.directory}${file.separator}module-info.shade From 5daeb387c22539117e0ed124b13576620bf6a079 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 30 May 2023 21:31:45 +1200 Subject: [PATCH 0754/1323] Format, javadoc, remove duplicate code --- .../java/io/avaje/http/client/DHttpApi.java | 2 -- .../java/io/avaje/http/client/HttpClient.java | 3 +++ .../generator/client/ClientProcessor.java | 4 +-- .../generator/client/ComponentMetaData.java | 11 +++----- .../client/SimpleComponentWriter.java | 27 +++---------------- 5 files changed, 12 insertions(+), 35 deletions(-) diff --git a/http-client/src/main/java/io/avaje/http/client/DHttpApi.java b/http-client/src/main/java/io/avaje/http/client/DHttpApi.java index 880371c52..9f4ceec1b 100644 --- a/http-client/src/main/java/io/avaje/http/client/DHttpApi.java +++ b/http-client/src/main/java/io/avaje/http/client/DHttpApi.java @@ -29,11 +29,9 @@ void init() { for (final HttpApiProvider apiProvider : ServiceLoader.load(HttpApiProvider.class)) { addProvider(apiProvider); } - for (final GeneratedComponent apiProvider : ServiceLoader.load(GeneratedComponent.class)) { apiProvider.register(providerMap); } - log.log(DEBUG, "providers for {0}", providerMap.keySet()); } diff --git a/http-client/src/main/java/io/avaje/http/client/HttpClient.java b/http-client/src/main/java/io/avaje/http/client/HttpClient.java index b293eb69f..cb7665ca0 100644 --- a/http-client/src/main/java/io/avaje/http/client/HttpClient.java +++ b/http-client/src/main/java/io/avaje/http/client/HttpClient.java @@ -363,6 +363,9 @@ interface Metrics extends HttpClientContext.Metrics { @FunctionalInterface interface GeneratedComponent { + /** + * Register the HttpApiProviders to the given providerMap. + */ void register(Map, HttpApiProvider> providerMap); } } diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java index e93e53b55..4a3a61fbf 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java @@ -67,13 +67,11 @@ public boolean process(Set annotations, RoundEnvironment round.getElementsAnnotatedWith(typeElement(ClientPrism.PRISM_TYPE))) { writeClient(controller); } - for (final var importedElement : - round.getElementsAnnotatedWith(typeElement(ImportPrism.PRISM_TYPE))) { + for (final var importedElement : round.getElementsAnnotatedWith(typeElement(ImportPrism.PRISM_TYPE))) { writeForImported(importedElement); } writeComponent(round.processingOver()); - setPlatform(platform); return false; } diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ComponentMetaData.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ComponentMetaData.java index 946b1efbc..2b30927c7 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ComponentMetaData.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ComponentMetaData.java @@ -31,7 +31,6 @@ void setFullName(String fullName) { String fullName() { if (fullName == null) { - String topPackage = TopPackage.of(generatedClients); if (!topPackage.endsWith(".httpclient")) { topPackage += ".httpclient"; @@ -59,13 +58,11 @@ Collection allImports() { return packageImports; } - public static String removeLast(String s, String search) { - final int pos = s.lastIndexOf(search); - + public static String removeLast(String className, String search) { + final int pos = className.lastIndexOf(search); if (pos > -1) { - return s.substring(0, pos) + s.substring(pos + search.length()); + return className.substring(0, pos) + className.substring(pos + search.length()); } - - return s; + return className; } } diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/SimpleComponentWriter.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/SimpleComponentWriter.java index e363174ff..ad6ec6cd2 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/SimpleComponentWriter.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/SimpleComponentWriter.java @@ -30,11 +30,9 @@ final class SimpleComponentWriter { } void init() throws IOException { - if (fullName == null) { this.fullName = metaData.fullName(); } - if (fileObject == null) { fileObject = createWriter(metaData.fullName()); } @@ -65,12 +63,9 @@ private void writeRegister() { writer.append(" public void register(Map, HttpApiProvider> providerMap) {").eol(); for (final String clientFullName : metaData.all()) { - final String clientShortName = Util.shortName(clientFullName); - final var clientInterface = removeLast(clientShortName, "HttpClient"); - writer - .append(" providerMap.put(%s.class, %s::new);", clientInterface, clientShortName) - .eol(); + final var clientInterface = ComponentMetaData.removeLast(clientShortName, "HttpClient"); + writer.append(" providerMap.put(%s.class, %s::new);", clientInterface, clientShortName).eol(); } writer.append(" }").eol().eol(); } @@ -82,15 +77,11 @@ private void writeClassEnd() { private void writeClassStart() { final String shortName = Util.shortName(fullName); writer.append(AT_GENERATED).eol(); - writer.append("@MetaData({"); final List all = metaData.all(); writeMetaDataEntry(all); writer.append("})").eol(); - writer - .append("public class %s implements HttpClient.GeneratedComponent {", shortName) - .eol() - .eol(); + writer.append("public class %s implements HttpClient.GeneratedComponent {", shortName).eol().eol(); } private void writeMetaDataEntry(List entries) { @@ -117,19 +108,9 @@ private void writeImports() { writer.eol(); } - public static String removeLast(String s, String search) { - final int pos = s.lastIndexOf(search); - - if (pos > -1) { - return s.substring(0, pos) + s.substring(pos + search.length()); - } - - return s; - } - private void writePackage() { final String packageName = TopPackage.packageOf(fullName); - if (packageName != null && !packageName.isEmpty()) { + if (!packageName.isEmpty()) { writer.append("package %s;", packageName).eol().eol(); } } From 3c21c072e10c09dbc2fd79c383d432a2a3732a43 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Wed, 31 May 2023 14:05:31 +1200 Subject: [PATCH 0755/1323] Bump to Java version 20 for Nima generator (#220) --- .github/workflows/build.yml | 2 +- http-generator-nima/pom.xml | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f6d717324..1c8e40d52 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -33,7 +33,7 @@ jobs: env: JAVA_VERSION: ${{ matrix.java_version }} run: | - if (( JAVA_VERSION < 19 )); + if (( JAVA_VERSION < 20 )); then mvn clean package -pl "!:avaje-http-nima-generator" else diff --git a/http-generator-nima/pom.xml b/http-generator-nima/pom.xml index b88dec1f4..1816e6cdf 100644 --- a/http-generator-nima/pom.xml +++ b/http-generator-nima/pom.xml @@ -10,9 +10,9 @@ avaje-http-nima-generator - 19 - 19 - 19 + 20 + 20 + 20 UTF-8 From e2ff2da9a1d70c8d278e3f560b6ee09d896b1315 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Thu, 1 Jun 2023 22:31:40 +1200 Subject: [PATCH 0756/1323] Version 1.40 --- http-api/pom.xml | 2 +- http-client-gson-adapter/pom.xml | 4 ++-- http-client/pom.xml | 2 +- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 2 +- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-generator-nima/pom.xml | 2 +- http-inject-plugin/pom.xml | 2 +- pom.xml | 2 +- tests/pom.xml | 2 +- tests/test-client-generation/pom.xml | 2 +- tests/test-client/pom.xml | 2 +- tests/test-helidon/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- 20 files changed, 21 insertions(+), 21 deletions(-) diff --git a/http-api/pom.xml b/http-api/pom.xml index a5558ec09..dcdb5ccd9 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.40-SNAPSHOT + 1.40 .. diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index 60614f2ef..ec5781a21 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.40-SNAPSHOT + 1.40 avaje-http-client-gson @@ -20,7 +20,7 @@ io.avaje avaje-http-client - 1.40-SNAPSHOT + 1.40 provided diff --git a/http-client/pom.xml b/http-client/pom.xml index f2c49b530..15a9726b7 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.40-SNAPSHOT + 1.40 avaje-http-client diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index 73c5158ed..8112a8ef6 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.40-SNAPSHOT + 1.40 avaje-http-client-generator diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 460dbe44c..14c2ab599 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.40-SNAPSHOT + 1.40 avaje-http-generator-core diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index ad22b1eba..07ddf9834 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.40-SNAPSHOT + 1.40 avaje-http-helidon-generator diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index b595c3944..2a3885071 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.40-SNAPSHOT + 1.40 avaje-http-javalin-generator diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index af48b1939..00bf0edca 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.40-SNAPSHOT + 1.40 avaje-http-jex-generator diff --git a/http-generator-nima/pom.xml b/http-generator-nima/pom.xml index 1816e6cdf..543fc9f17 100644 --- a/http-generator-nima/pom.xml +++ b/http-generator-nima/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 1.40-SNAPSHOT + 1.40 avaje-http-nima-generator diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index cd4bf2e70..926955608 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.40-SNAPSHOT + 1.40 .. diff --git a/pom.xml b/pom.xml index 8581aa5a9..b96ccd54d 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-parent - 1.40-SNAPSHOT + 1.40 pom diff --git a/tests/pom.xml b/tests/pom.xml index b50896881..80677047f 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 1.40-SNAPSHOT + 1.40 tests diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index 9a56c9334..f4b65b0b4 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.40-SNAPSHOT + 1.40 test-client-generation diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index e5ce120c9..6c6a1658f 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 1.40-SNAPSHOT + 1.40 test-client diff --git a/tests/test-helidon/pom.xml b/tests/test-helidon/pom.xml index 9cfaf7b61..f5d1c267e 100644 --- a/tests/test-helidon/pom.xml +++ b/tests/test-helidon/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.40-SNAPSHOT + 1.40 test-helidon diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 98ef3aa5c..5f61cbfce 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 1.40-SNAPSHOT + 1.40 test-javalin-jsonb diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index c845cc807..fc6dd5721 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.40-SNAPSHOT + 1.40 test-javalin diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 70bcebcab..9961b68a5 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.40-SNAPSHOT + 1.40 test-jex diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 402ada06f..e65fd55ab 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.40-SNAPSHOT + 1.40 test-nima-jsonb diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index 2748bb5d0..fc71799b7 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 1.40-SNAPSHOT + 1.40 test-nima From d7a9678bef6ced2313f16db870edd6cf9de76bef Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Thu, 1 Jun 2023 22:32:27 +1200 Subject: [PATCH 0757/1323] Bump to next snapshot version --- http-api/pom.xml | 2 +- http-client-gson-adapter/pom.xml | 4 ++-- http-client/pom.xml | 2 +- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 2 +- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-generator-nima/pom.xml | 2 +- http-inject-plugin/pom.xml | 2 +- pom.xml | 2 +- tests/pom.xml | 2 +- tests/test-client-generation/pom.xml | 2 +- tests/test-client/pom.xml | 2 +- tests/test-helidon/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- 20 files changed, 21 insertions(+), 21 deletions(-) diff --git a/http-api/pom.xml b/http-api/pom.xml index dcdb5ccd9..a05b666b3 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.40 + 1.41-SNAPSHOT .. diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index ec5781a21..36b8219db 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.40 + 1.41-SNAPSHOT avaje-http-client-gson @@ -20,7 +20,7 @@ io.avaje avaje-http-client - 1.40 + 1.41-SNAPSHOT provided diff --git a/http-client/pom.xml b/http-client/pom.xml index 15a9726b7..5ca2054f6 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.40 + 1.41-SNAPSHOT avaje-http-client diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index 8112a8ef6..56c455acf 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.40 + 1.41-SNAPSHOT avaje-http-client-generator diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 14c2ab599..c100a3147 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.40 + 1.41-SNAPSHOT avaje-http-generator-core diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index 07ddf9834..8c8adaffb 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.40 + 1.41-SNAPSHOT avaje-http-helidon-generator diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index 2a3885071..398241477 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.40 + 1.41-SNAPSHOT avaje-http-javalin-generator diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index 00bf0edca..f52b80c64 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.40 + 1.41-SNAPSHOT avaje-http-jex-generator diff --git a/http-generator-nima/pom.xml b/http-generator-nima/pom.xml index 543fc9f17..0f989ab5f 100644 --- a/http-generator-nima/pom.xml +++ b/http-generator-nima/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 1.40 + 1.41-SNAPSHOT avaje-http-nima-generator diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index 926955608..e0a0b5fb1 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.40 + 1.41-SNAPSHOT .. diff --git a/pom.xml b/pom.xml index b96ccd54d..b8b562076 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-parent - 1.40 + 1.41-SNAPSHOT pom diff --git a/tests/pom.xml b/tests/pom.xml index 80677047f..2b7307742 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 1.40 + 1.41-SNAPSHOT tests diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index f4b65b0b4..d3db40d58 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.40 + 1.41-SNAPSHOT test-client-generation diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index 6c6a1658f..b86a884cd 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 1.40 + 1.41-SNAPSHOT test-client diff --git a/tests/test-helidon/pom.xml b/tests/test-helidon/pom.xml index f5d1c267e..08ebbd133 100644 --- a/tests/test-helidon/pom.xml +++ b/tests/test-helidon/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.40 + 1.41-SNAPSHOT test-helidon diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 5f61cbfce..81f131e4c 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 1.40 + 1.41-SNAPSHOT test-javalin-jsonb diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index fc6dd5721..40eb27bfe 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.40 + 1.41-SNAPSHOT test-javalin diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 9961b68a5..8fd0087e8 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.40 + 1.41-SNAPSHOT test-jex diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index e65fd55ab..06bd15fe4 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.40 + 1.41-SNAPSHOT test-nima-jsonb diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index fc71799b7..ecea13734 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 1.40 + 1.41-SNAPSHOT test-nima From fc6a12f4a54f839b87f6b6024d7bfe9885779d43 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Fri, 2 Jun 2023 12:23:55 -0400 Subject: [PATCH 0758/1323] fix enum path --- .../src/main/java/io/avaje/http/generator/core/TypeMap.java | 2 +- .../java/org/example/myapp/web/test/TestController2.java | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/TypeMap.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/TypeMap.java index 632e9ece8..3fa25372f 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/TypeMap.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/TypeMap.java @@ -315,7 +315,7 @@ public String toMethod() { @Override public String asMethod() { - return "java.util.Objects.toString("; + return "asEnum(" + type.shortType() + ".class,"; } } diff --git a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController2.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController2.java index e24bed13f..b3a829be8 100644 --- a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController2.java +++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController2.java @@ -43,6 +43,11 @@ String enumQueryImplied(String s, @QueryParam ServerType type) { return type.name(); } + @Post("/enumPath/{type}") + String enumQueryImplied(ServerType type) { + return type.name(); + } + @Get("/mapTest") String mapTest(Map> strings) { return strings.toString(); From 986729ea1d24bdd26ec291d5a862759b0e2fa31a Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Fri, 2 Jun 2023 12:38:34 -0400 Subject: [PATCH 0759/1323] test name --- .../src/main/java/io/avaje/http/generator/core/TypeMap.java | 4 ++-- .../main/java/org/example/myapp/web/test/TestController2.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/TypeMap.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/TypeMap.java index 3fa25372f..0b88dac69 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/TypeMap.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/TypeMap.java @@ -310,12 +310,12 @@ static class EnumHandler extends ObjectHandler { @Override public String toMethod() { - return "(" + type.shortType() + ") asEnum(" + type.shortType() + ".class,"; + return "(" + type.shortType() + ") asEnum(" + type.shortType() + ".class, "; } @Override public String asMethod() { - return "asEnum(" + type.shortType() + ".class,"; + return "asEnum(" + type.shortType() + ".class, "; } } diff --git a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController2.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController2.java index b3a829be8..13d5190a5 100644 --- a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController2.java +++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController2.java @@ -44,7 +44,7 @@ String enumQueryImplied(String s, @QueryParam ServerType type) { } @Post("/enumPath/{type}") - String enumQueryImplied(ServerType type) { + String enumPath(ServerType type) { return type.name(); } From 100c85ab20f114759d88f95d54e27f444dcc252f Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Fri, 2 Jun 2023 12:40:02 -0400 Subject: [PATCH 0760/1323] Update TypeMap.java --- .../src/main/java/io/avaje/http/generator/core/TypeMap.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/TypeMap.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/TypeMap.java index 0b88dac69..c092c37fa 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/TypeMap.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/TypeMap.java @@ -315,7 +315,7 @@ public String toMethod() { @Override public String asMethod() { - return "asEnum(" + type.shortType() + ".class, "; + return "(" + type.shortType() + ") asEnum(" + type.shortType() + ".class, "; } } From 6deb8a370ef231691c436b967a36a279463ffef4 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Sat, 3 Jun 2023 08:53:21 +1200 Subject: [PATCH 0761/1323] Version 1.41 --- http-api/pom.xml | 2 +- http-client-gson-adapter/pom.xml | 4 +-- http-client/pom.xml | 2 +- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 2 +- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-generator-nima/pom.xml | 2 +- http-inject-plugin/pom.xml | 2 +- pom.xml | 2 +- tests/pom.xml | 2 +- tests/test-client-generation/pom.xml | 2 +- tests/test-client/pom.xml | 2 +- tests/test-helidon/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- .../src/main/resources/public/openapi.json | 36 +++++++++++++++++++ tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- 21 files changed, 57 insertions(+), 21 deletions(-) diff --git a/http-api/pom.xml b/http-api/pom.xml index a05b666b3..3117d7b28 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.41-SNAPSHOT + 1.41 .. diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index 36b8219db..957d5ba2b 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.41-SNAPSHOT + 1.41 avaje-http-client-gson @@ -20,7 +20,7 @@ io.avaje avaje-http-client - 1.41-SNAPSHOT + 1.41 provided diff --git a/http-client/pom.xml b/http-client/pom.xml index 5ca2054f6..f7406ba1c 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.41-SNAPSHOT + 1.41 avaje-http-client diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index 56c455acf..0a6af3542 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.41-SNAPSHOT + 1.41 avaje-http-client-generator diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index c100a3147..abd0d8766 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.41-SNAPSHOT + 1.41 avaje-http-generator-core diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index 8c8adaffb..3f4fcde14 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.41-SNAPSHOT + 1.41 avaje-http-helidon-generator diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index 398241477..77a34a7eb 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.41-SNAPSHOT + 1.41 avaje-http-javalin-generator diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index f52b80c64..23322118d 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.41-SNAPSHOT + 1.41 avaje-http-jex-generator diff --git a/http-generator-nima/pom.xml b/http-generator-nima/pom.xml index 0f989ab5f..33e63cb70 100644 --- a/http-generator-nima/pom.xml +++ b/http-generator-nima/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 1.41-SNAPSHOT + 1.41 avaje-http-nima-generator diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index e0a0b5fb1..ee11f54d8 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.41-SNAPSHOT + 1.41 .. diff --git a/pom.xml b/pom.xml index b8b562076..91061ce4a 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-parent - 1.41-SNAPSHOT + 1.41 pom diff --git a/tests/pom.xml b/tests/pom.xml index 2b7307742..da8698872 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 1.41-SNAPSHOT + 1.41 tests diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index d3db40d58..f4b35f7c2 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.41-SNAPSHOT + 1.41 test-client-generation diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index b86a884cd..3ee349ee9 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 1.41-SNAPSHOT + 1.41 test-client diff --git a/tests/test-helidon/pom.xml b/tests/test-helidon/pom.xml index 08ebbd133..02e24f3a0 100644 --- a/tests/test-helidon/pom.xml +++ b/tests/test-helidon/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.41-SNAPSHOT + 1.41 test-helidon diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 81f131e4c..6132acd32 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 1.41-SNAPSHOT + 1.41 test-javalin-jsonb diff --git a/tests/test-javalin-jsonb/src/main/resources/public/openapi.json b/tests/test-javalin-jsonb/src/main/resources/public/openapi.json index 913874880..fb5692c1a 100644 --- a/tests/test-javalin-jsonb/src/main/resources/public/openapi.json +++ b/tests/test-javalin-jsonb/src/main/resources/public/openapi.json @@ -1294,6 +1294,42 @@ } } }, + "/test/enumPath/{type}" : { + "post" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "parameters" : [ + { + "name" : "type", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string", + "enum" : [ + "PROXY", + "HIDE_N_SEEK", + "FFA" + ] + } + } + ], + "responses" : { + "201" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, "/test/enumQuery" : { "get" : { "tags" : [ diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 40eb27bfe..97a28669a 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.41-SNAPSHOT + 1.41 test-javalin diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 8fd0087e8..a48fab821 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.41-SNAPSHOT + 1.41 test-jex diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 06bd15fe4..7974658d2 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.41-SNAPSHOT + 1.41 test-nima-jsonb diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index ecea13734..28e27b5ba 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 1.41-SNAPSHOT + 1.41 test-nima From 6870b33ea6881368c234d39abbde56467c152596 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Sat, 3 Jun 2023 08:54:05 +1200 Subject: [PATCH 0762/1323] Bump to next snapshot version --- http-api/pom.xml | 2 +- http-client-gson-adapter/pom.xml | 4 ++-- http-client/pom.xml | 2 +- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 2 +- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-generator-nima/pom.xml | 2 +- http-inject-plugin/pom.xml | 2 +- pom.xml | 2 +- tests/pom.xml | 2 +- tests/test-client-generation/pom.xml | 2 +- tests/test-client/pom.xml | 2 +- tests/test-helidon/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- 20 files changed, 21 insertions(+), 21 deletions(-) diff --git a/http-api/pom.xml b/http-api/pom.xml index 3117d7b28..ab78397b2 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.41 + 1.42-SNAPSHOT .. diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index 957d5ba2b..51a93a33e 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.41 + 1.42-SNAPSHOT avaje-http-client-gson @@ -20,7 +20,7 @@ io.avaje avaje-http-client - 1.41 + 1.42-SNAPSHOT provided diff --git a/http-client/pom.xml b/http-client/pom.xml index f7406ba1c..a4712fe2b 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.41 + 1.42-SNAPSHOT avaje-http-client diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index 0a6af3542..afe631da6 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.41 + 1.42-SNAPSHOT avaje-http-client-generator diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index abd0d8766..15a30dcd9 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.41 + 1.42-SNAPSHOT avaje-http-generator-core diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index 3f4fcde14..54e256acf 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.41 + 1.42-SNAPSHOT avaje-http-helidon-generator diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index 77a34a7eb..027fb50e3 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.41 + 1.42-SNAPSHOT avaje-http-javalin-generator diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index 23322118d..1f4706126 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.41 + 1.42-SNAPSHOT avaje-http-jex-generator diff --git a/http-generator-nima/pom.xml b/http-generator-nima/pom.xml index 33e63cb70..ac6e7b25c 100644 --- a/http-generator-nima/pom.xml +++ b/http-generator-nima/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 1.41 + 1.42-SNAPSHOT avaje-http-nima-generator diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index ee11f54d8..a2a8024b6 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.41 + 1.42-SNAPSHOT .. diff --git a/pom.xml b/pom.xml index 91061ce4a..cef13f3b9 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-parent - 1.41 + 1.42-SNAPSHOT pom diff --git a/tests/pom.xml b/tests/pom.xml index da8698872..de2ec01bf 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 1.41 + 1.42-SNAPSHOT tests diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index f4b35f7c2..596043397 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.41 + 1.42-SNAPSHOT test-client-generation diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index 3ee349ee9..33ca59584 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 1.41 + 1.42-SNAPSHOT test-client diff --git a/tests/test-helidon/pom.xml b/tests/test-helidon/pom.xml index 02e24f3a0..3be72dc7e 100644 --- a/tests/test-helidon/pom.xml +++ b/tests/test-helidon/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.41 + 1.42-SNAPSHOT test-helidon diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 6132acd32..48c1bcedd 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 1.41 + 1.42-SNAPSHOT test-javalin-jsonb diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 97a28669a..56a6fbfce 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.41 + 1.42-SNAPSHOT test-javalin diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index a48fab821..eac038ea6 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.41 + 1.42-SNAPSHOT test-jex diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 7974658d2..d4a526160 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.41 + 1.42-SNAPSHOT test-nima-jsonb diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index 28e27b5ba..f3ed587b5 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 1.41 + 1.42-SNAPSHOT test-nima From d31af6abfc0d0327a39543b3fe78760c19b1fac8 Mon Sep 17 00:00:00 2001 From: "robin.bygrave" Date: Thu, 15 Jun 2023 08:59:45 +1200 Subject: [PATCH 0763/1323] Update the tests to use HttpClient (from HttpClientContext) --- .../java/io/avaje/http/client/AsyncTest.java | 4 +-- .../io/avaje/http/client/AuthTokenTest.java | 2 +- .../io/avaje/http/client/BaseWebTest.java | 6 ++-- .../http/client/BasicAuthInterceptTest.java | 2 +- .../io/avaje/http/client/DHttpApiTest.java | 4 +-- .../avaje/http/client/HelloBasicAuthTest.java | 6 ++-- .../http/client/HelloControllerTest.java | 28 +++++++++---------- .../http/client/RequestListenerTest.java | 8 +++--- .../java/io/avaje/http/client/RetryTest.java | 10 +++---- .../java/io/avaje/http/client/VerbTest.java | 13 ++++----- .../example/dinject/ConfigureWithDITest.java | 6 ++-- .../java/org/example/github/GithubTest.java | 4 +-- .../test/java/org/example/CommonApiTest.java | 4 +-- 13 files changed, 47 insertions(+), 50 deletions(-) diff --git a/http-client/src/test/java/io/avaje/http/client/AsyncTest.java b/http-client/src/test/java/io/avaje/http/client/AsyncTest.java index 2bc5a44bf..7991c020d 100644 --- a/http-client/src/test/java/io/avaje/http/client/AsyncTest.java +++ b/http-client/src/test/java/io/avaje/http/client/AsyncTest.java @@ -13,10 +13,10 @@ class AsyncTest extends BaseWebTest { - final HttpClientContext clientContext = client(); + final HttpClient clientContext = client(); @Test - void waitForAsync() { + void waitForAsync() { final CompletableFuture>> future = clientContext.request() .path("hello").path("stream") .GET() diff --git a/http-client/src/test/java/io/avaje/http/client/AuthTokenTest.java b/http-client/src/test/java/io/avaje/http/client/AuthTokenTest.java index 7a567861b..530ad9cc4 100644 --- a/http-client/src/test/java/io/avaje/http/client/AuthTokenTest.java +++ b/http-client/src/test/java/io/avaje/http/client/AuthTokenTest.java @@ -45,7 +45,7 @@ public AuthToken obtainToken(HttpClientRequest tokenRequest) { @Test void sendEmail() { - HttpClientContext ctx = HttpClientContext.builder() + var ctx = HttpClient.builder() .baseUrl("https://foo") .bodyAdapter(new JacksonBodyAdapter(objectMapper)) .authTokenProvider(new MyAuthTokenProvider()) diff --git a/http-client/src/test/java/io/avaje/http/client/BaseWebTest.java b/http-client/src/test/java/io/avaje/http/client/BaseWebTest.java index d71186b38..cc3f4ebde 100644 --- a/http-client/src/test/java/io/avaje/http/client/BaseWebTest.java +++ b/http-client/src/test/java/io/avaje/http/client/BaseWebTest.java @@ -1,8 +1,8 @@ package io.avaje.http.client; import com.fasterxml.jackson.databind.ObjectMapper; -import org.example.webserver.App; import io.javalin.Javalin; +import org.example.webserver.App; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; @@ -25,8 +25,8 @@ public static void shutdown() { webServer.stop(); } - public static HttpClientContext client() { - return HttpClientContext.builder() + public static HttpClient client() { + return HttpClient.builder() .baseUrl(baseUrl) .connectionTimeout(Duration.ofSeconds(1)) .requestTimeout(Duration.ofSeconds(1)) diff --git a/http-client/src/test/java/io/avaje/http/client/BasicAuthInterceptTest.java b/http-client/src/test/java/io/avaje/http/client/BasicAuthInterceptTest.java index fb89c1d9a..74d7755be 100644 --- a/http-client/src/test/java/io/avaje/http/client/BasicAuthInterceptTest.java +++ b/http-client/src/test/java/io/avaje/http/client/BasicAuthInterceptTest.java @@ -18,7 +18,7 @@ void encode() { void beforeRequest() { // setup final BasicAuthIntercept intercept = new BasicAuthIntercept("Aladdin", "open sesame"); - final HttpClientContext ctx = HttpClientContext.builder().baseUrl("junk").build(); + final var ctx = HttpClient.builder().baseUrl("junk").build(); // act final HttpClientRequest request = ctx.request(); diff --git a/http-client/src/test/java/io/avaje/http/client/DHttpApiTest.java b/http-client/src/test/java/io/avaje/http/client/DHttpApiTest.java index 763fb5b86..7d4511103 100644 --- a/http-client/src/test/java/io/avaje/http/client/DHttpApiTest.java +++ b/http-client/src/test/java/io/avaje/http/client/DHttpApiTest.java @@ -2,9 +2,9 @@ import io.avaje.jsonb.Jsonb; import org.example.github.Repo; +import org.example.github.RepoJsonAdapter; import org.example.github.Simple; import org.example.github.httpclient.Simple$HttpClient; -import org.example.github.RepoJsonAdapter; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; @@ -18,7 +18,7 @@ class DHttpApiTest { @Test void test_github_listRepos() { - final HttpClientContext clientContext = HttpClientContext.builder() + final var clientContext = HttpClient.builder() .baseUrl("https://api.github.com") .bodyAdapter(new JacksonBodyAdapter()) .build(); diff --git a/http-client/src/test/java/io/avaje/http/client/HelloBasicAuthTest.java b/http-client/src/test/java/io/avaje/http/client/HelloBasicAuthTest.java index 810a1c9b8..2f5508954 100644 --- a/http-client/src/test/java/io/avaje/http/client/HelloBasicAuthTest.java +++ b/http-client/src/test/java/io/avaje/http/client/HelloBasicAuthTest.java @@ -9,10 +9,10 @@ class HelloBasicAuthTest extends BaseWebTest { - final HttpClientContext clientContext = client(); + final HttpClient clientContext = client(); - public static HttpClientContext client() { - return HttpClientContext.builder() + public static HttpClient client() { + return HttpClient.builder() .baseUrl(baseUrl) .bodyAdapter(new JacksonBodyAdapter(new ObjectMapper())) .requestIntercept(new BasicAuthIntercept("rob", "bot")) diff --git a/http-client/src/test/java/io/avaje/http/client/HelloControllerTest.java b/http-client/src/test/java/io/avaje/http/client/HelloControllerTest.java index cff0b3018..f33a2185b 100644 --- a/http-client/src/test/java/io/avaje/http/client/HelloControllerTest.java +++ b/http-client/src/test/java/io/avaje/http/client/HelloControllerTest.java @@ -30,7 +30,7 @@ class HelloControllerTest extends BaseWebTest { private static final ObjectMapper objectMapper = new ObjectMapper(); - final HttpClientContext clientContext = client(); + final HttpClient clientContext = client(); @Test void newClientTest() { @@ -77,7 +77,7 @@ void queryParamMap() { assertThat(hres.statusCode()).isEqualTo(200); assertThat(hres.uri().toString()).isEqualTo("http://localhost:8889/hello/message?A=a&B=b"); - HttpClientContext.Metrics metrics = clientContext.metrics(); + HttpClient.Metrics metrics = clientContext.metrics(); assertThat(metrics.totalCount()).isEqualTo(1); assertThat(metrics.errorCount()).isEqualTo(0); assertThat(metrics.responseBytes()).isGreaterThan(0); @@ -116,7 +116,7 @@ void asLines_async() throws ExecutionException, InterruptedException { assertThat(lines).hasSize(4); assertThat(lines.get(0)).contains("{\"id\":1, \"name\":\"one\"}"); - HttpClientContext.Metrics metrics = clientContext.metrics(); + HttpClient.Metrics metrics = clientContext.metrics(); assertThat(metrics.totalCount()).isEqualTo(1); assertThat(metrics.errorCount()).isEqualTo(0); assertThat(metrics.responseBytes()).isEqualTo(0); @@ -281,7 +281,7 @@ void get_stream_NotFoundException() { assertThat(httpException.statusCode()).isEqualTo(404); assertThat(httpException.httpResponse().statusCode()).isEqualTo(404); - HttpClientContext.Metrics metrics = clientContext.metrics(true); + HttpClient.Metrics metrics = clientContext.metrics(true); assertThat(metrics.totalCount()).isEqualTo(1); assertThat(metrics.errorCount()).isEqualTo(1); assertThat(metrics.responseBytes()).isEqualTo(0); @@ -475,7 +475,7 @@ void get_notFound() { assertThat(hres.statusCode()).isEqualTo(404); assertThat(hres.body()).contains("Not Found"); - HttpClientContext.Metrics metrics = clientContext.metrics(true); + HttpClient.Metrics metrics = clientContext.metrics(true); assertThat(metrics.totalCount()).isEqualTo(1); assertThat(metrics.errorCount()).isEqualTo(1); assertThat(metrics.responseBytes()).isGreaterThan(0); @@ -506,11 +506,11 @@ void asPlainString_200() { void asPlainString_throwingHttpException() { final HttpException httpException = assertThrows(HttpException.class, () -> clientContext.request() - .path("hello/saveform3") - .formParam("name", "Bax") - .formParam("email", "notValidEmail") - .POST() - .asPlainString()); + .path("hello/saveform3") + .formParam("name", "Bax") + .formParam("email", "notValidEmail") + .POST() + .asPlainString()); assertThat(httpException.statusCode()).isEqualTo(422); @@ -532,7 +532,7 @@ void asString_readInvalidResponse() { assertThat(hres.statusCode()).isEqualTo(422); // convert json error response body to a bean - final ErrorResponse errorResponse = clientContext.converters() + final ErrorResponse errorResponse = clientContext.bodyAdapter() .beanReader(ErrorResponse.class).readBody(hres.body()); final Map errorMap = errorResponse.getErrors(); @@ -936,7 +936,7 @@ void async_whenComplete_throwingHttpException() { } catch (CompletionException e) { assertThat(e.getCause()).isSameAs(causeRef.get()); } - HttpClientContext.Metrics metrics = clientContext.metrics(true); + HttpClient.Metrics metrics = clientContext.metrics(true); assertThat(metrics.totalCount()).isEqualTo(1); assertThat(metrics.errorCount()).isEqualTo(1); assertThat(metrics.responseBytes()).isGreaterThan(0); @@ -981,8 +981,8 @@ void post_bean_returningBean_usingExplicitConverters() { HelloDto dto = new HelloDto(12, "rob", "other"); - final BodyWriter from = clientContext.converters().beanWriter(HelloDto.class); - final BodyReader toDto = clientContext.converters().beanReader(HelloDto.class); + final BodyWriter from = clientContext.bodyAdapter().beanWriter(HelloDto.class); + final BodyReader toDto = clientContext.bodyAdapter().beanReader(HelloDto.class); final HelloDto bean = clientContext.request() .path("hello") diff --git a/http-client/src/test/java/io/avaje/http/client/RequestListenerTest.java b/http-client/src/test/java/io/avaje/http/client/RequestListenerTest.java index cb8115338..7382d0f3f 100644 --- a/http-client/src/test/java/io/avaje/http/client/RequestListenerTest.java +++ b/http-client/src/test/java/io/avaje/http/client/RequestListenerTest.java @@ -32,8 +32,8 @@ public void response(Event event) { } } - private HttpClientContext createClient(TDRequestListener tdRequestListener) { - return HttpClientContext.builder() + private HttpClient createClient(TDRequestListener tdRequestListener) { + return HttpClient.builder() .baseUrl(baseUrl) .requestLogging(false) .requestListener(new RequestLogger()) @@ -45,7 +45,7 @@ private HttpClientContext createClient(TDRequestListener tdRequestListener) { @Test void get_no_request_body() { final TDRequestListener tdRequestListener = new TDRequestListener(false); - final HttpClientContext client = createClient(tdRequestListener); + final HttpClient client = createClient(tdRequestListener); final HttpResponse hres = client.request() .path("hello").path("message") @@ -58,7 +58,7 @@ void get_no_request_body() { @Test void post() { final TDRequestListener tdRequestListener = new TDRequestListener(true); - final HttpClientContext client = createClient(tdRequestListener); + final HttpClient client = createClient(tdRequestListener); final HttpResponse hres = client.request() .path("post") diff --git a/http-client/src/test/java/io/avaje/http/client/RetryTest.java b/http-client/src/test/java/io/avaje/http/client/RetryTest.java index 41f76a0f0..b63c74f8f 100644 --- a/http-client/src/test/java/io/avaje/http/client/RetryTest.java +++ b/http-client/src/test/java/io/avaje/http/client/RetryTest.java @@ -9,8 +9,8 @@ class RetryTest extends BaseWebTest { - HttpClientContext initClientWithRetry(MyIntercept myIntercept, RetryHandler retryHandler) { - return HttpClientContext.builder() + HttpClient initClientWithRetry(MyIntercept myIntercept, RetryHandler retryHandler) { + return HttpClient.builder() .baseUrl("http://localhost:8889") .bodyAdapter(new JacksonBodyAdapter()) .retryHandler(retryHandler) @@ -21,18 +21,18 @@ HttpClientContext initClientWithRetry(MyIntercept myIntercept, RetryHandler retr @Test void retryTest() { final MyIntercept myIntercept = new MyIntercept(); - final HttpClientContext clientContext = initClientWithRetry(myIntercept, new SimpleRetryHandler(4, 1)); + final HttpClient clientContext = initClientWithRetry(myIntercept, new SimpleRetryHandler(4, 1)); performGetRequestAndAssert(myIntercept, clientContext); } @Test void retryWithGitterTest() { final MyIntercept myIntercept = new MyIntercept(); - final HttpClientContext clientContext = initClientWithRetry(myIntercept, new SimpleRetryHandler(4, 10, 20)); + final HttpClient clientContext = initClientWithRetry(myIntercept, new SimpleRetryHandler(4, 10, 20)); performGetRequestAndAssert(myIntercept, clientContext); } - private void performGetRequestAndAssert(MyIntercept myIntercept, HttpClientContext clientContext) { + private void performGetRequestAndAssert(MyIntercept myIntercept, HttpClient clientContext) { HttpResponse res = clientContext.request() .label("http_client_hello_retry") .path("hello/retry") diff --git a/http-client/src/test/java/io/avaje/http/client/VerbTest.java b/http-client/src/test/java/io/avaje/http/client/VerbTest.java index fa100a669..e1c006b5e 100644 --- a/http-client/src/test/java/io/avaje/http/client/VerbTest.java +++ b/http-client/src/test/java/io/avaje/http/client/VerbTest.java @@ -3,7 +3,6 @@ import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; -import java.io.InputStream; import java.net.URI; import java.net.URISyntaxException; import java.net.URL; @@ -11,15 +10,13 @@ import java.net.http.HttpResponse; import java.nio.charset.StandardCharsets; import java.nio.file.Path; -import java.util.function.Supplier; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.fail; public class VerbTest extends BaseWebTest { - private final HttpClientContext clientContext = client(); + private final HttpClient clientContext = client(); @Test void post() { @@ -148,9 +145,9 @@ void delete_with_body_Path_NotFound_expects_IllegalArgumentException() { @Test void delete_with_body_InputStream() { HttpResponse res = clientContext.request() - .path("delete") - .body(() -> getClass().getResourceAsStream("/dummy.txt")) - .DELETE().asString(); + .path("delete") + .body(() -> getClass().getResourceAsStream("/dummy.txt")) + .DELETE().asString(); assertThat(res.body()).isEqualTo("delete body[dummyFileContent]"); } @@ -183,7 +180,7 @@ void get_BodyHandler_null_expect() { HttpResponse res = clientContext.request() .path("post") - .body((HttpRequest.BodyPublisher)null) + .body((HttpRequest.BodyPublisher) null) .POST().asString(); assertThat(res.body()).isEqualTo("post"); diff --git a/http-client/src/test/java/org/example/dinject/ConfigureWithDITest.java b/http-client/src/test/java/org/example/dinject/ConfigureWithDITest.java index 74f1496f2..a92d016ea 100644 --- a/http-client/src/test/java/org/example/dinject/ConfigureWithDITest.java +++ b/http-client/src/test/java/org/example/dinject/ConfigureWithDITest.java @@ -1,7 +1,7 @@ package org.example.dinject; import io.avaje.http.client.BodyAdapter; -import io.avaje.http.client.HttpClientContext; +import io.avaje.http.client.HttpClient; import io.avaje.http.client.JsonbBodyAdapter; import io.avaje.inject.BeanScope; import org.junit.jupiter.api.Test; @@ -18,8 +18,8 @@ void configureWith() { assertThat(beanScope.contains("io.avaje.jsonb.Jsonb")).isTrue(); - HttpClientContext.Builder builder = HttpClientContext.builder(); - HttpClientContext.Builder.State state = builder.state(); + HttpClient.Builder builder = HttpClient.builder(); + HttpClient.Builder.State state = builder.state(); assertThat(state.baseUrl()).isNull(); assertThat(state.bodyAdapter()).isNull(); assertThat(state.client()).isNull(); diff --git a/http-client/src/test/java/org/example/github/GithubTest.java b/http-client/src/test/java/org/example/github/GithubTest.java index 3a4c6c13c..473df7c99 100644 --- a/http-client/src/test/java/org/example/github/GithubTest.java +++ b/http-client/src/test/java/org/example/github/GithubTest.java @@ -1,6 +1,6 @@ package org.example.github; -import io.avaje.http.client.HttpClientContext; +import io.avaje.http.client.HttpClient; import io.avaje.http.client.JacksonBodyAdapter; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; @@ -15,7 +15,7 @@ public class GithubTest { @Disabled void test() { - final HttpClientContext clientContext = HttpClientContext.builder() + final HttpClient clientContext = HttpClient.builder() .baseUrl("https://api.github.com") .bodyAdapter(new JacksonBodyAdapter()) .requestLogging(false) diff --git a/tests/test-client-generation/src/test/java/org/example/CommonApiTest.java b/tests/test-client-generation/src/test/java/org/example/CommonApiTest.java index 84fa0a3b8..86783388b 100644 --- a/tests/test-client-generation/src/test/java/org/example/CommonApiTest.java +++ b/tests/test-client-generation/src/test/java/org/example/CommonApiTest.java @@ -1,6 +1,6 @@ package org.example; -import io.avaje.http.client.HttpClientContext; +import io.avaje.http.client.HttpClient; import io.avaje.http.client.JacksonBodyAdapter; import org.example.server.Main; import org.junit.jupiter.api.BeforeAll; @@ -21,7 +21,7 @@ static void start() { final int port = new Random().nextInt(1000) + 10_000; Main.start(port); - final HttpClientContext clientContext = HttpClientContext.builder() + final HttpClient clientContext = HttpClient.builder() .baseUrl("http://localhost:" + port) .bodyAdapter(new JacksonBodyAdapter()) .build(); From be78c8c864b439bafbd21b621cf95fd8a687ef35 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Wed, 14 Jun 2023 17:08:43 -0400 Subject: [PATCH 0764/1323] remove inject from quickstart inject isn't actually needed there --- README.md | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/README.md b/README.md index 0e2486c0f..4ed06c76f 100644 --- a/README.md +++ b/README.md @@ -17,11 +17,6 @@ to generate adapter code for Javalin and Helidon SE/Nima. ## Add dependencies ```xml - - io.avaje - avaje-inject - ${avaje-inject.version} - io.avaje avaje-http-api @@ -32,12 +27,6 @@ to generate adapter code for Javalin and Helidon SE/Nima. ```xml - - io.avaje - avaje-inject-generator - ${avaje-inject.version} - provided - io.avaje avaje-http-javalin-generator From 731309665ead19e6d791312cb96bffa7d64c0b1b Mon Sep 17 00:00:00 2001 From: "robin.bygrave" Date: Thu, 15 Jun 2023 09:09:02 +1200 Subject: [PATCH 0765/1323] [HttpClient] Remove deprecated method withHandler() migrate to handler() Migrate from withHandler(HttpResponse.BodyHandler bodyHandler) to handler(HttpResponse.BodyHandler bodyHandler) --- .../http/client/gson/GsonBodyAdapter.java | 2 +- .../avaje/http/client/HttpAsyncResponse.java | 8 ---- .../avaje/http/client/HttpCallResponse.java | 8 ---- .../java/io/avaje/http/client/HttpClient.java | 44 +++++++++++++------ .../avaje/http/client/HttpClientResponse.java | 8 ---- 5 files changed, 31 insertions(+), 39 deletions(-) diff --git a/http-client-gson-adapter/src/main/java/io/avaje/http/client/gson/GsonBodyAdapter.java b/http-client-gson-adapter/src/main/java/io/avaje/http/client/gson/GsonBodyAdapter.java index c45fc4aea..405d7852b 100644 --- a/http-client-gson-adapter/src/main/java/io/avaje/http/client/gson/GsonBodyAdapter.java +++ b/http-client-gson-adapter/src/main/java/io/avaje/http/client/gson/GsonBodyAdapter.java @@ -21,7 +21,7 @@ * *
{@code
  *
- *   HttpClientContext.builder()
+ *   HttpClient.builder()
  *       .baseUrl(baseUrl)
  *       .requestListener(new RequestLogger())
  *       //.bodyAdapter(new JacksonBodyAdapter(new ObjectMapper()))
diff --git a/http-client/src/main/java/io/avaje/http/client/HttpAsyncResponse.java b/http-client/src/main/java/io/avaje/http/client/HttpAsyncResponse.java
index ca39b400b..f56b44811 100644
--- a/http-client/src/main/java/io/avaje/http/client/HttpAsyncResponse.java
+++ b/http-client/src/main/java/io/avaje/http/client/HttpAsyncResponse.java
@@ -224,14 +224,6 @@ public interface HttpAsyncResponse {
    */
    CompletableFuture> handler(HttpResponse.BodyHandler bodyHandler);
 
-  /**
-   * Deprecated - migrate to handler().
-   */
-  @Deprecated
-  default  CompletableFuture> withHandler(HttpResponse.BodyHandler bodyHandler) {
-    return handler(bodyHandler);
-  }
-
   /**
    * Process converting the response body to the given type.
    * 

diff --git a/http-client/src/main/java/io/avaje/http/client/HttpCallResponse.java b/http-client/src/main/java/io/avaje/http/client/HttpCallResponse.java index 51040422d..d056c2e5b 100644 --- a/http-client/src/main/java/io/avaje/http/client/HttpCallResponse.java +++ b/http-client/src/main/java/io/avaje/http/client/HttpCallResponse.java @@ -118,14 +118,6 @@ public interface HttpCallResponse { */ HttpCall> handler(HttpResponse.BodyHandler bodyHandler); - /** - * Deprecated - migrate to handler(). - */ - @Deprecated - default HttpCall> withHandler(HttpResponse.BodyHandler bodyHandler) { - return handler(bodyHandler); - } - /** * A bean response to execute async or sync. *

diff --git a/http-client/src/main/java/io/avaje/http/client/HttpClient.java b/http-client/src/main/java/io/avaje/http/client/HttpClient.java index cb7665ca0..7e0b3cce7 100644 --- a/http-client/src/main/java/io/avaje/http/client/HttpClient.java +++ b/http-client/src/main/java/io/avaje/http/client/HttpClient.java @@ -72,19 +72,6 @@ static Builder builder() { */ UrlBuilder url(); - /** - * Deprecated - migrate to {@link #bodyAdapter()}. - *

- * Return the body adapter used by the client context. - *

- * This is the body adapter used to convert request and response - * bodies to java types. For example using Jackson with JSON payloads. - */ - @Deprecated - default BodyAdapter converters() { - return bodyAdapter(); - } - /** * Return the BodyAdapter that this client is using. */ @@ -355,8 +342,37 @@ interface State { /** * Statistic metrics collected to provide an overview of activity of this client. */ - interface Metrics extends HttpClientContext.Metrics { + interface Metrics { + + /** + * Return the total number of responses. + */ + long totalCount(); + + /** + * Return the total number of error responses (status code >= 300). + */ + long errorCount(); + /** + * Return the total response bytes (excludes streaming responses). + */ + long responseBytes(); + + /** + * Return the total response time in microseconds. + */ + long totalMicros(); + + /** + * Return the max response time in microseconds (since the last reset). + */ + long maxMicros(); + + /** + * Return the average response time in microseconds. + */ + long avgMicros(); } /** Components register Generated Client interface Providers */ diff --git a/http-client/src/main/java/io/avaje/http/client/HttpClientResponse.java b/http-client/src/main/java/io/avaje/http/client/HttpClientResponse.java index 299e0bb98..cddf068b4 100644 --- a/http-client/src/main/java/io/avaje/http/client/HttpClientResponse.java +++ b/http-client/src/main/java/io/avaje/http/client/HttpClientResponse.java @@ -307,12 +307,4 @@ public interface HttpClientResponse { */ HttpResponse handler(HttpResponse.BodyHandler responseHandler); - /** - * Deprecated - migrate to handler(). - */ - @Deprecated - default HttpResponse withHandler(HttpResponse.BodyHandler responseHandler) { - return handler(responseHandler); - } - } From f75b45a63362af1b4dc4ccc49d805cebd79c1497 Mon Sep 17 00:00:00 2001 From: "robin.bygrave" Date: Thu, 15 Jun 2023 16:08:42 +1200 Subject: [PATCH 0766/1323] [HttpClient] Remove deprecated HttpClientContext, migrate to HttpClient --- .../avaje/http/client/DHttpClientContext.java | 4 +- .../client/DHttpClientContextBuilder.java | 47 ++- .../avaje/http/client/HttpClientContext.java | 323 ------------------ .../BasicClientInterface$HttpClient.java | 4 +- 4 files changed, 27 insertions(+), 351 deletions(-) delete mode 100644 http-client/src/main/java/io/avaje/http/client/HttpClientContext.java diff --git a/http-client/src/main/java/io/avaje/http/client/DHttpClientContext.java b/http-client/src/main/java/io/avaje/http/client/DHttpClientContext.java index e1a386d01..936de98bc 100644 --- a/http-client/src/main/java/io/avaje/http/client/DHttpClientContext.java +++ b/http-client/src/main/java/io/avaje/http/client/DHttpClientContext.java @@ -15,7 +15,7 @@ import java.util.concurrent.atomic.LongAccumulator; import java.util.concurrent.atomic.LongAdder; -final class DHttpClientContext implements HttpClientContext, SpiHttpClient { +final class DHttpClientContext implements HttpClient, SpiHttpClient { /** * HTTP Authorization header. @@ -75,7 +75,7 @@ public T create(Class clientInterface) { private T constructReflectively(Class clientInterface) { try { final Class implementationClass = implementationClass(clientInterface); - final Constructor constructor = implementationClass.getConstructor(HttpClientContext.class); + final Constructor constructor = implementationClass.getConstructor(HttpClient.class); return (T) constructor.newInstance(this); } catch (final Exception e) { final String cn = implementationClassName(clientInterface, "HttpClient"); diff --git a/http-client/src/main/java/io/avaje/http/client/DHttpClientContextBuilder.java b/http-client/src/main/java/io/avaje/http/client/DHttpClientContextBuilder.java index d6dd785bd..7af837210 100644 --- a/http-client/src/main/java/io/avaje/http/client/DHttpClientContextBuilder.java +++ b/http-client/src/main/java/io/avaje/http/client/DHttpClientContextBuilder.java @@ -3,7 +3,6 @@ import java.net.Authenticator; import java.net.CookieHandler; import java.net.ProxySelector; -import java.net.http.HttpClient; import java.time.Duration; import java.util.Collections; import java.util.concurrent.Executor; @@ -13,121 +12,121 @@ import io.avaje.inject.BeanScope; -final class DHttpClientContextBuilder extends DBaseBuilder implements HttpClientContext.Builder, HttpClientContext.Builder.State { +final class DHttpClientContextBuilder extends DBaseBuilder implements HttpClient.Builder, HttpClient.Builder.State { DHttpClientContextBuilder() { } @Override - public HttpClientContext.Builder client(HttpClient client) { + public HttpClient.Builder client(java.net.http.HttpClient client) { this.client = client; return this; } @Override - public HttpClientContext.Builder baseUrl(String baseUrl) { + public HttpClient.Builder baseUrl(String baseUrl) { this.baseUrl = baseUrl; return this; } @Override - public HttpClientContext.Builder connectionTimeout(Duration connectionTimeout) { + public HttpClient.Builder connectionTimeout(Duration connectionTimeout) { this.connectionTimeout = connectionTimeout; return this; } @Override - public HttpClientContext.Builder requestTimeout(Duration requestTimeout) { + public HttpClient.Builder requestTimeout(Duration requestTimeout) { this.requestTimeout = requestTimeout; return this; } @Override - public HttpClientContext.Builder bodyAdapter(BodyAdapter adapter) { + public HttpClient.Builder bodyAdapter(BodyAdapter adapter) { this.bodyAdapter = adapter; return this; } @Override - public HttpClientContext.Builder retryHandler(RetryHandler retryHandler) { + public HttpClient.Builder retryHandler(RetryHandler retryHandler) { this.retryHandler = retryHandler; return this; } @Override - public HttpClientContext.Builder requestLogging(boolean requestLogging) { + public HttpClient.Builder requestLogging(boolean requestLogging) { this.requestLogging = requestLogging; return this; } @Override - public HttpClientContext.Builder requestListener(RequestListener... requestListener) { + public HttpClient.Builder requestListener(RequestListener... requestListener) { Collections.addAll(listeners, requestListener); return this; } @Override - public HttpClientContext.Builder requestIntercept(RequestIntercept... requestIntercept) { + public HttpClient.Builder requestIntercept(RequestIntercept... requestIntercept) { Collections.addAll(interceptors, requestIntercept); return this; } @Override - public HttpClientContext.Builder authTokenProvider(AuthTokenProvider authTokenProvider) { + public HttpClient.Builder authTokenProvider(AuthTokenProvider authTokenProvider) { this.authTokenProvider = authTokenProvider; return this; } @Override - public HttpClientContext.Builder cookieHandler(CookieHandler cookieHandler) { + public HttpClient.Builder cookieHandler(CookieHandler cookieHandler) { this.cookieHandler = cookieHandler; return this; } @Override - public HttpClientContext.Builder redirect(HttpClient.Redirect redirect) { + public HttpClient.Builder redirect(java.net.http.HttpClient.Redirect redirect) { this.redirect = redirect; return this; } @Override - public HttpClientContext.Builder version(HttpClient.Version version) { + public HttpClient.Builder version(java.net.http.HttpClient.Version version) { this.version = version; return this; } @Override - public HttpClientContext.Builder executor(Executor executor) { + public HttpClient.Builder executor(Executor executor) { this.executor = executor; return this; } @Override - public HttpClientContext.Builder proxy(ProxySelector proxySelector) { + public HttpClient.Builder proxy(ProxySelector proxySelector) { this.proxy = proxySelector; return this; } @Override - public HttpClientContext.Builder sslContext(SSLContext sslContext) { + public HttpClient.Builder sslContext(SSLContext sslContext) { this.sslContext = sslContext; return this; } @Override - public HttpClientContext.Builder sslParameters(SSLParameters sslParameters) { + public HttpClient.Builder sslParameters(SSLParameters sslParameters) { this.sslParameters = sslParameters; return this; } @Override - public HttpClientContext.Builder authenticator(Authenticator authenticator) { + public HttpClient.Builder authenticator(Authenticator authenticator) { this.authenticator = authenticator; return this; } @Override - public HttpClientContext.Builder priority(int priority) { + public HttpClient.Builder priority(int priority) { this.priority = priority; return this; } @@ -138,13 +137,13 @@ public State state() { } @Override - public HttpClientContext.Builder configureWith(BeanScope beanScope) { + public HttpClient.Builder configureWith(BeanScope beanScope) { super.configureFromScope(beanScope); return this; } @Override - public HttpClientContext build() { + public HttpClient build() { return super.buildClient(); } @@ -159,7 +158,7 @@ public BodyAdapter bodyAdapter() { } @Override - public HttpClient client() { + public java.net.http.HttpClient client() { return client; } diff --git a/http-client/src/main/java/io/avaje/http/client/HttpClientContext.java b/http-client/src/main/java/io/avaje/http/client/HttpClientContext.java deleted file mode 100644 index d34f9e42a..000000000 --- a/http-client/src/main/java/io/avaje/http/client/HttpClientContext.java +++ /dev/null @@ -1,323 +0,0 @@ -package io.avaje.http.client; - -import io.avaje.inject.BeanScope; - -import javax.net.ssl.SSLContext; -import javax.net.ssl.SSLParameters; -import java.net.Authenticator; -import java.net.CookieHandler; -import java.net.ProxySelector; -import java.net.http.HttpClient; -import java.time.Duration; -import java.util.concurrent.Executor; - -/** - * Deprecated in favor of {@link io.avaje.http.client.HttpClient}. - * Migrate to using {@link io.avaje.http.client.HttpClient#builder()}. - *

- * The HTTP client context that we use to build and process requests. - * - *

{@code
- *
- *   HttpClientContext ctx = HttpClientContext.builder()
- *       .baseUrl("http://localhost:8080")
- *       .bodyAdapter(new JacksonBodyAdapter())
- *       .build();
- *
- *  HelloDto dto = ctx.request()
- *       .path("hello")
- *       .queryParam("name", "Rob")
- *       .queryParam("say", "Whats up")
- *       .GET()
- *       .bean(HelloDto.class);
- *
- * }
- */ -@Deprecated -public interface HttpClientContext extends io.avaje.http.client.HttpClient { - - /** - * Deprecated - migrate to {@link io.avaje.http.client.HttpClient#builder()}. - *

- * Return the builder to config and build the client context. - * - *

{@code
-   *
-   *   HttpClientContext ctx = HttpClientContext.builder()
-   *       .baseUrl("http://localhost:8080")
-   *       .bodyAdapter(new JacksonBodyAdapter())
-   *       .build();
-   *
-   *  HttpResponse res = ctx.request()
-   *       .path("hello")
-   *       .GET().asString();
-   *
-   * }
- */ - @Deprecated - static HttpClientContext.Builder builder() { - return new DHttpClientContextBuilder(); - } - - /** - * Deprecated - migrate to builder(). - */ - @Deprecated - static HttpClientContext.Builder newBuilder() { - return builder(); - } - - /** - * Builds the HttpClientContext. - * - *
{@code
-   *
-   *   HttpClientContext ctx = HttpClientContext.builder()
-   *       .baseUrl("http://localhost:8080")
-   *       .bodyAdapter(new JacksonBodyAdapter())
-   *       .build();
-   *
-   *  HelloDto dto = ctx.request()
-   *       .path("hello")
-   *       .queryParam("name", "Rob")
-   *       .queryParam("say", "Whats up")
-   *       .GET()
-   *       .bean(HelloDto.class);
-   *
-   * }
- */ - interface Builder { - - /** - * Set the underlying HttpClient to use. - *

- * Used when we wish to control all options of the HttpClient. - */ - Builder client(HttpClient client); - - /** - * Set the base URL to use for requests created from the context. - *

- * Note that the base url can be replaced via {@link HttpClientRequest#url(String)}. - */ - Builder baseUrl(String baseUrl); - - /** - * Set the connection timeout to use. - * - * @see java.net.http.HttpClient.Builder#connectTimeout(Duration) - */ - Builder connectionTimeout(Duration connectionTimeout); - - /** - * Set the default request timeout. - * - * @see java.net.http.HttpRequest.Builder#timeout(Duration) - */ - Builder requestTimeout(Duration requestTimeout); - - /** - * Set the body adapter to use to convert beans to body content - * and response content back to beans. - */ - Builder bodyAdapter(BodyAdapter adapter); - - /** - * Set a RetryHandler to use to retry requests. - */ - Builder retryHandler(RetryHandler retryHandler); - - /** - * Disable or enable built in request and response logging. - *

- * By default request logging is enabled. Set this to false to stop - * the default {@link RequestLogger} being registered to log request - * and response headers and bodies etc. - *

- * With logging level set to {@code DEBUG} for - * {@code io.avaje.http.client.RequestLogger} the request and response - * are logged as a summary with response status and time. - *

- * Set the logging level to {@code TRACE} to include the request - * and response headers and body payloads with truncation for large - * bodies. - * - *

Suppression

- *

- * We can also use {@link HttpClientRequest#suppressLogging()} to suppress - * logging on specific requests. - *

- * Logging of Authorization headers is suppressed. - * {@link AuthTokenProvider} requests are suppressed. - * - * @param requestLogging Disable/enable the registration of the default logger - * @see RequestLogger - */ - Builder requestLogging(boolean requestLogging); - - /** - * Add a request listener. Multiple listeners may be added, when - * do so they will process events in the order they were added. - *

- * Note that {@link RequestLogger} is an implementation for debug - * logging request/response headers and content which is registered - * by default depending on {@link #requestLogging(boolean)}. - * - * @see RequestLogger - */ - Builder requestListener(RequestListener... requestListener); - - /** - * Add a request interceptor. Multiple interceptors may be added. - */ - Builder requestIntercept(RequestIntercept... requestIntercept); - - /** - * Add a Authorization token provider. - *

- * When set all requests are expected to use a Authorization Bearer token - * unless they are marked via {@link HttpClientRequest#skipAuthToken()}. - *

- * The AuthTokenProvider obtains a new token typically with an expiry. This - * is automatically called as needed and the Authorization Bearer header set - * on all requests (not marked with skipAuthToken()). - */ - Builder authTokenProvider(AuthTokenProvider authTokenProvider); - - /** - * Specify a cookie handler to use on the HttpClient. This would override the default cookie handler. - * - * @see HttpClient.Builder#cookieHandler(CookieHandler) - */ - Builder cookieHandler(CookieHandler cookieHandler); - - /** - * Specify the redirect policy. Defaults to HttpClient.Redirect.NORMAL. - * - * @see HttpClient.Builder#followRedirects(HttpClient.Redirect) - */ - Builder redirect(HttpClient.Redirect redirect); - - /** - * Specify the HTTP version. Defaults to not set. - * - * @see HttpClient.Builder#version(HttpClient.Version) - */ - Builder version(HttpClient.Version version); - - /** - * Specify the Executor to use for asynchronous tasks. - * If not specified a default executor will be used. - * - * @see HttpClient.Builder#executor(Executor) - */ - Builder executor(Executor executor); - - /** - * Set the proxy to the underlying {@link HttpClient}. - * - * @see HttpClient.Builder#proxy(ProxySelector) - */ - Builder proxy(ProxySelector proxySelector); - - /** - * Set the sslContext to the underlying {@link HttpClient}. - * - * @see HttpClient.Builder#sslContext(SSLContext) - */ - Builder sslContext(SSLContext sslContext); - - /** - * Set the sslParameters to the underlying {@link HttpClient}. - * - * @see HttpClient.Builder#sslParameters(SSLParameters) - */ - Builder sslParameters(SSLParameters sslParameters); - - /** - * Set a HttpClient authenticator to the underlying {@link HttpClient}. - * - * @see HttpClient.Builder#authenticator(Authenticator) - */ - Builder authenticator(Authenticator authenticator); - - /** - * Set the priority for HTTP/2 requests to the underlying {@link HttpClient}. - * - * @see HttpClient.Builder#priority(int) - */ - Builder priority(int priority); - - /** - * Configure BodyAdapter and RetryHandler using dependency injection BeanScope. - */ - Builder configureWith(BeanScope beanScope); - - /** - * Return the state of the builder. - */ - State state(); - - /** - * Build and return the context. - * - *

{@code
-     *
-     *   HttpClientContext ctx = HttpClientContext.builder()
-     *       .baseUrl("http://localhost:8080")
-     *       .bodyAdapter(new JacksonBodyAdapter())
-     *       .build();
-     *
-     *  HelloDto dto = ctx.request()
-     *       .path("hello")
-     *       .queryParam("say", "Whats up")
-     *       .GET()
-     *       .bean(HelloDto.class);
-     *
-     * }
- */ - HttpClientContext build(); - - /** - * The state of the builder with methods to read the set state. - */ - interface State extends io.avaje.http.client.HttpClient.Builder.State { - - } - } - - /** - * Statistic metrics collected to provide an overview of activity of this client. - */ - interface Metrics { - /** - * Return the total number of responses. - */ - long totalCount(); - - /** - * Return the total number of error responses (status code >= 300). - */ - long errorCount(); - - /** - * Return the total response bytes (excludes streaming responses). - */ - long responseBytes(); - - /** - * Return the total response time in microseconds. - */ - long totalMicros(); - - /** - * Return the max response time in microseconds (since the last reset). - */ - long maxMicros(); - - /** - * Return the average response time in microseconds. - */ - long avgMicros(); - } -} diff --git a/http-client/src/test/java/org/example/github/httpclient/BasicClientInterface$HttpClient.java b/http-client/src/test/java/org/example/github/httpclient/BasicClientInterface$HttpClient.java index 38dd068fc..7f311c299 100644 --- a/http-client/src/test/java/org/example/github/httpclient/BasicClientInterface$HttpClient.java +++ b/http-client/src/test/java/org/example/github/httpclient/BasicClientInterface$HttpClient.java @@ -1,6 +1,6 @@ package org.example.github.httpclient; -import io.avaje.http.client.HttpClientContext; +import io.avaje.http.client.HttpClient; import io.avaje.http.client.HttpException; import org.example.github.BasicClientInterface; import org.example.github.Repo; @@ -13,7 +13,7 @@ */ public class BasicClientInterface$HttpClient implements BasicClientInterface { - public BasicClientInterface$HttpClient(HttpClientContext context) { + public BasicClientInterface$HttpClient(HttpClient client) { } @Override From 5679853d1ca4de87ed1da27f762a715a99d89c9b Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sun, 18 Jun 2023 23:55:17 -0400 Subject: [PATCH 0767/1323] extendable clients --- .../main/java/io/avaje/http/api/Client.java | 52 ++++++++++++------- .../generator/client/ClientProcessor.java | 4 +- .../client/clients/ExampleClient.java | 6 +++ .../generator/client/clients/UserClient.java | 16 ++++++ .../http/generator/core/ControllerReader.java | 28 +++++++--- 5 files changed, 79 insertions(+), 27 deletions(-) create mode 100644 http-generator-client/src/test/java/io/avaje/http/generator/client/clients/ExampleClient.java create mode 100644 http-generator-client/src/test/java/io/avaje/http/generator/client/clients/UserClient.java diff --git a/http-api/src/main/java/io/avaje/http/api/Client.java b/http-api/src/main/java/io/avaje/http/api/Client.java index 664883299..334cf65fe 100644 --- a/http-api/src/main/java/io/avaje/http/api/Client.java +++ b/http-api/src/main/java/io/avaje/http/api/Client.java @@ -11,31 +11,29 @@ * Marker annotation for client. * *
{@code
+ * @Client
+ * interface CustomerApi {
+ *   ...
+ *   @Get("/{id}")
+ *   Customer getById(long id);
  *
- *   @Client
- *   interface CustomerApi {
- *     ...
- *     @Get("/{id}")
- *     Customer getById(long id);
- *
- *     @Post
- *     long save(Customer customer);
- *   }
+ *   @Post
+ *   long save(Customer customer);
+ * }
  *
  * }
* *

Client.Import

- *

- * When the client interface already exists in another module we - * use Client.Import to generate the client. - *

- * Specify the @Client.Import on the package or class - * to refer to the client interface we want to generate. * - *

{@code
+ * 

When the client interface already exists in another module we use Client.Import + * to generate the client. * - * @Client.Import(types = OtherApi.class) - * package org.example; + *

Specify the @Client.Import on the package or class to refer to the client + * interface we want to generate. + * + *

{@code
+ * @Client.Import(types = OtherApi.class)
+ * package org.example;
  *
  * }
*/ @@ -43,8 +41,24 @@ @Retention(value = RUNTIME) public @interface Client { + /** + * Flag to set whether to generate a Client Implementation. Set false if the interface exists merely to be extended by + * other client interfaces + */ + boolean generate() default true; + + /** + * Specify @Client.Import on a package or class to refer to the client interface we + * want to generate. + * + *
{@code
+   * @Client.Import(types = OtherApi.class)
+   * package org.example;
+   *
+   * }
+ */ @Target(value = {TYPE, PACKAGE}) - @Retention(value = RUNTIME) + @Retention(RUNTIME) @interface Import { /** diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java index 4a3a61fbf..8e84a99eb 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java @@ -65,7 +65,9 @@ public boolean process(Set annotations, RoundEnvironment readModule(); for (final Element controller : round.getElementsAnnotatedWith(typeElement(ClientPrism.PRISM_TYPE))) { - writeClient(controller); + if (ClientPrism.getInstanceOn(controller).generate()) { + writeClient(controller); + } } for (final var importedElement : round.getElementsAnnotatedWith(typeElement(ImportPrism.PRISM_TYPE))) { writeForImported(importedElement); diff --git a/http-generator-client/src/test/java/io/avaje/http/generator/client/clients/ExampleClient.java b/http-generator-client/src/test/java/io/avaje/http/generator/client/clients/ExampleClient.java new file mode 100644 index 000000000..eb5411b29 --- /dev/null +++ b/http-generator-client/src/test/java/io/avaje/http/generator/client/clients/ExampleClient.java @@ -0,0 +1,6 @@ +package io.avaje.http.generator.client.clients; + +import io.avaje.http.api.Client; + +@Client +public interface ExampleClient extends UserClient {} diff --git a/http-generator-client/src/test/java/io/avaje/http/generator/client/clients/UserClient.java b/http-generator-client/src/test/java/io/avaje/http/generator/client/clients/UserClient.java new file mode 100644 index 000000000..f81886c1f --- /dev/null +++ b/http-generator-client/src/test/java/io/avaje/http/generator/client/clients/UserClient.java @@ -0,0 +1,16 @@ +package io.avaje.http.generator.client.clients; + +import io.avaje.http.api.BodyString; +import io.avaje.http.api.Client; +import io.avaje.http.api.Get; +import io.avaje.http.api.Post; + +@Client(generate = false) +public interface UserClient { + + @Post("/users") + String createUser(@BodyString String body); + + @Get("/users/{userId}") + String getUserById(String userId); +} diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java index 933e22e42..ddb41e6e6 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java @@ -31,7 +31,7 @@ public final class ControllerReader { private final TypeElement beanType; - private final List interfaces; + private final List interfaces; private final List interfaceMethods; private final List roles; private final List methods = new ArrayList<>(); @@ -115,17 +115,18 @@ void addImports(boolean withSingleton) { } } - private List initInterfaces() { - final List interfaces = new ArrayList<>(); + private List initInterfaces() { + final List superInterfaces = new ArrayList<>(); for (final TypeMirror anInterface : beanType.getInterfaces()) { - final Element ifaceElement = asElement(anInterface); + final var ifaceElement = asElement(anInterface); final var controller = ControllerPrism.getInstanceOn(ifaceElement); if (controller != null && !controller.value().isBlank() - || PathPrism.isPresent(ifaceElement)) { - interfaces.add(ifaceElement); + || PathPrism.isPresent(ifaceElement) + || ClientPrism.isPresent(ifaceElement)) { + superInterfaces.add(ifaceElement); } } - return interfaces; + return superInterfaces; } private List initInterfaceMethods() { @@ -221,6 +222,10 @@ public void read(boolean withSingleton) { } } readSuper(beanType); + + if (platform().getClass().getSimpleName().contains("Client")) { + readInterfaces(); + } deriveIncludeValidation(); addImports(withSingleton); } @@ -268,6 +273,15 @@ private void readSuper(TypeElement beanType) { } } + /** Read methods from interfaces taking into account generics. */ + private void readInterfaces() { + for (final var superInterfaces : interfaces) { + for (final var element : ElementFilter.methodsIn(superInterfaces.getEnclosedElements())) { + readMethod(element, (DeclaredType) superInterfaces.asType()); + } + } + } + private void readMethod(ExecutableElement element) { readMethod(element, null); } From 8567dbea2702cc22f76ce2d04361e3f3267dba9f Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Mon, 19 Jun 2023 00:24:45 -0400 Subject: [PATCH 0768/1323] read entire chain --- .../client/clients/ExampleClient.java | 6 +++- .../client/clients/ExampleClient2.java | 10 ++++++ .../http/generator/core/ControllerReader.java | 32 ++++++++++++------- 3 files changed, 36 insertions(+), 12 deletions(-) create mode 100644 http-generator-client/src/test/java/io/avaje/http/generator/client/clients/ExampleClient2.java diff --git a/http-generator-client/src/test/java/io/avaje/http/generator/client/clients/ExampleClient.java b/http-generator-client/src/test/java/io/avaje/http/generator/client/clients/ExampleClient.java index eb5411b29..e89dac620 100644 --- a/http-generator-client/src/test/java/io/avaje/http/generator/client/clients/ExampleClient.java +++ b/http-generator-client/src/test/java/io/avaje/http/generator/client/clients/ExampleClient.java @@ -1,6 +1,10 @@ package io.avaje.http.generator.client.clients; import io.avaje.http.api.Client; +import io.avaje.http.api.Patch; @Client -public interface ExampleClient extends UserClient {} +public interface ExampleClient extends UserClient { + @Patch + void patchy(); +} diff --git a/http-generator-client/src/test/java/io/avaje/http/generator/client/clients/ExampleClient2.java b/http-generator-client/src/test/java/io/avaje/http/generator/client/clients/ExampleClient2.java new file mode 100644 index 000000000..38c0e7b49 --- /dev/null +++ b/http-generator-client/src/test/java/io/avaje/http/generator/client/clients/ExampleClient2.java @@ -0,0 +1,10 @@ +package io.avaje.http.generator.client.clients; + +import io.avaje.http.api.Client; +import io.avaje.http.api.Patch; + +@Client +public interface ExampleClient2 extends ExampleClient { + @Patch + void patchy2(); +} diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java index ddb41e6e6..ad51fbabd 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java @@ -10,6 +10,8 @@ import static java.util.function.Predicate.not; import java.util.ArrayList; +import java.util.HashSet; +import java.util.Iterator; import java.util.List; import java.util.Optional; import java.util.Set; @@ -35,6 +37,7 @@ public final class ControllerReader { private final List interfaceMethods; private final List roles; private final List methods = new ArrayList<>(); + private final Set seenMethods = new HashSet<>(); private final Set staticImportTypes = new TreeSet<>(); private final Set importTypes = new TreeSet<>(); private final List apiResponses; @@ -54,7 +57,7 @@ public final class ControllerReader { public ControllerReader(TypeElement beanType) { this.beanType = beanType; - this.interfaces = initInterfaces(); + this.interfaces = initInterfaces(beanType); this.interfaceMethods = initInterfaceMethods(); this.roles = buildRoles(); if (isOpenApiAvailable()) { @@ -115,9 +118,9 @@ void addImports(boolean withSingleton) { } } - private List initInterfaces() { + private List initInterfaces(TypeElement element) { final List superInterfaces = new ArrayList<>(); - for (final TypeMirror anInterface : beanType.getInterfaces()) { + for (final TypeMirror anInterface : element.getInterfaces()) { final var ifaceElement = asElement(anInterface); final var controller = ControllerPrism.getInstanceOn(ifaceElement); if (controller != null && !controller.value().isBlank() @@ -224,7 +227,9 @@ public void read(boolean withSingleton) { readSuper(beanType); if (platform().getClass().getSimpleName().contains("Client")) { - readInterfaces(); + for (final var superInterface : interfaces) { + readInterfaces(superInterface); + } } deriveIncludeValidation(); addImports(withSingleton); @@ -273,12 +278,17 @@ private void readSuper(TypeElement beanType) { } } - /** Read methods from interfaces taking into account generics. */ - private void readInterfaces() { - for (final var superInterfaces : interfaces) { - for (final var element : ElementFilter.methodsIn(superInterfaces.getEnclosedElements())) { - readMethod(element, (DeclaredType) superInterfaces.asType()); - } + /** + * Read methods from interfaces taking into account generics. + * + * @param interfaceElement + */ + private void readInterfaces(TypeElement interfaceElement) { + for (final var element : ElementFilter.methodsIn(interfaceElement.getEnclosedElements())) { + readMethod(element, (DeclaredType) interfaceElement.asType()); + } + for (final var element : initInterfaces(interfaceElement)) { + readInterfaces(element); } } @@ -293,7 +303,7 @@ private void readMethod(ExecutableElement method, DeclaredType declaredType) { actualExecutable = (ExecutableType) asMemberOf(declaredType, method); } final MethodReader methodReader = new MethodReader(this, method, actualExecutable); - if (methodReader.isWebMethod()) { + if (methodReader.isWebMethod() && seenMethods.add(method.toString())) { methodReader.read(); methods.add(methodReader); } From 9b167296b8daf1b80bf9b4f3f2b57ddd428439ec Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Mon, 19 Jun 2023 00:59:00 -0400 Subject: [PATCH 0769/1323] Create .lift.toml --- .lift.toml | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .lift.toml diff --git a/.lift.toml b/.lift.toml new file mode 100644 index 000000000..117e3a85f --- /dev/null +++ b/.lift.toml @@ -0,0 +1,3 @@ +ignoreFiles=""" +tests/** +""" \ No newline at end of file From 0e799afc396ad907b8825c73cfdebb99e7b67123 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 20 Jun 2023 08:20:34 +1200 Subject: [PATCH 0770/1323] Version 1.42 --- http-api/pom.xml | 2 +- http-client-gson-adapter/pom.xml | 4 ++-- http-client/pom.xml | 2 +- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 2 +- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-generator-nima/pom.xml | 2 +- http-inject-plugin/pom.xml | 2 +- pom.xml | 2 +- tests/pom.xml | 2 +- tests/test-client-generation/pom.xml | 2 +- tests/test-client/pom.xml | 2 +- tests/test-helidon/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- 20 files changed, 21 insertions(+), 21 deletions(-) diff --git a/http-api/pom.xml b/http-api/pom.xml index ab78397b2..12e831c53 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.42-SNAPSHOT + 1.42 .. diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index 51a93a33e..0eb292b65 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.42-SNAPSHOT + 1.42 avaje-http-client-gson @@ -20,7 +20,7 @@ io.avaje avaje-http-client - 1.42-SNAPSHOT + 1.42 provided diff --git a/http-client/pom.xml b/http-client/pom.xml index a4712fe2b..600fcf3d7 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.42-SNAPSHOT + 1.42 avaje-http-client diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index afe631da6..784ee6e39 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.42-SNAPSHOT + 1.42 avaje-http-client-generator diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 15a30dcd9..4832713bd 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.42-SNAPSHOT + 1.42 avaje-http-generator-core diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index 54e256acf..213b36a5f 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.42-SNAPSHOT + 1.42 avaje-http-helidon-generator diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index 027fb50e3..7d5f0736e 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.42-SNAPSHOT + 1.42 avaje-http-javalin-generator diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index 1f4706126..8412b9f4b 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.42-SNAPSHOT + 1.42 avaje-http-jex-generator diff --git a/http-generator-nima/pom.xml b/http-generator-nima/pom.xml index ac6e7b25c..1569722ce 100644 --- a/http-generator-nima/pom.xml +++ b/http-generator-nima/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 1.42-SNAPSHOT + 1.42 avaje-http-nima-generator diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index a2a8024b6..041885394 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.42-SNAPSHOT + 1.42 .. diff --git a/pom.xml b/pom.xml index cef13f3b9..65173b80d 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-parent - 1.42-SNAPSHOT + 1.42 pom diff --git a/tests/pom.xml b/tests/pom.xml index de2ec01bf..11647b0b8 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 1.42-SNAPSHOT + 1.42 tests diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index 596043397..14f31a395 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.42-SNAPSHOT + 1.42 test-client-generation diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index 33ca59584..495e7e616 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 1.42-SNAPSHOT + 1.42 test-client diff --git a/tests/test-helidon/pom.xml b/tests/test-helidon/pom.xml index 3be72dc7e..6caabcb99 100644 --- a/tests/test-helidon/pom.xml +++ b/tests/test-helidon/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.42-SNAPSHOT + 1.42 test-helidon diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 48c1bcedd..0c85f000b 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 1.42-SNAPSHOT + 1.42 test-javalin-jsonb diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 56a6fbfce..1e3bdd997 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.42-SNAPSHOT + 1.42 test-javalin diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index eac038ea6..c970d8443 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.42-SNAPSHOT + 1.42 test-jex diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index d4a526160..def4b9a92 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.42-SNAPSHOT + 1.42 test-nima-jsonb diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index f3ed587b5..7f2d890c7 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 1.42-SNAPSHOT + 1.42 test-nima From 691693972d5af38cd4e3ef1b8b748855335efdae Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 20 Jun 2023 08:24:28 +1200 Subject: [PATCH 0771/1323] Bump to 2.0-SNAPSHOT --- http-api/pom.xml | 2 +- http-client-gson-adapter/pom.xml | 4 ++-- http-client/pom.xml | 2 +- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 2 +- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-generator-nima/pom.xml | 2 +- http-inject-plugin/pom.xml | 2 +- pom.xml | 2 +- tests/pom.xml | 2 +- tests/test-client-generation/pom.xml | 2 +- tests/test-client/pom.xml | 2 +- tests/test-helidon/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- 20 files changed, 21 insertions(+), 21 deletions(-) diff --git a/http-api/pom.xml b/http-api/pom.xml index 12e831c53..f28e5d9a9 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.42 + 2.0-SNAPSHOT .. diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index 0eb292b65..ec3be33f3 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.42 + 2.0-SNAPSHOT avaje-http-client-gson @@ -20,7 +20,7 @@ io.avaje avaje-http-client - 1.42 + 2.0-SNAPSHOT provided diff --git a/http-client/pom.xml b/http-client/pom.xml index 600fcf3d7..6ce20dcc7 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.42 + 2.0-SNAPSHOT avaje-http-client diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index 784ee6e39..e27a75daf 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.42 + 2.0-SNAPSHOT avaje-http-client-generator diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 4832713bd..fc61ad4b6 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.42 + 2.0-SNAPSHOT avaje-http-generator-core diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index 213b36a5f..4764a0583 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.42 + 2.0-SNAPSHOT avaje-http-helidon-generator diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index 7d5f0736e..73d842f51 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.42 + 2.0-SNAPSHOT avaje-http-javalin-generator diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index 8412b9f4b..5686ea66c 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.42 + 2.0-SNAPSHOT avaje-http-jex-generator diff --git a/http-generator-nima/pom.xml b/http-generator-nima/pom.xml index 1569722ce..3b9d670a7 100644 --- a/http-generator-nima/pom.xml +++ b/http-generator-nima/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 1.42 + 2.0-SNAPSHOT avaje-http-nima-generator diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index 041885394..29c0cd168 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.42 + 2.0-SNAPSHOT .. diff --git a/pom.xml b/pom.xml index 65173b80d..b3518152a 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-parent - 1.42 + 2.0-SNAPSHOT pom diff --git a/tests/pom.xml b/tests/pom.xml index 11647b0b8..4a0d81dbc 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 1.42 + 2.0-SNAPSHOT tests diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index 14f31a395..e491690b1 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.42 + 2.0-SNAPSHOT test-client-generation diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index 495e7e616..25e359d7a 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 1.42 + 2.0-SNAPSHOT test-client diff --git a/tests/test-helidon/pom.xml b/tests/test-helidon/pom.xml index 6caabcb99..950528016 100644 --- a/tests/test-helidon/pom.xml +++ b/tests/test-helidon/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.42 + 2.0-SNAPSHOT test-helidon diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 0c85f000b..edb44b237 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 1.42 + 2.0-SNAPSHOT test-javalin-jsonb diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 1e3bdd997..b2c03098a 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.42 + 2.0-SNAPSHOT test-javalin diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index c970d8443..6e331c8ce 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.42 + 2.0-SNAPSHOT test-jex diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index def4b9a92..c3b176ea0 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.42 + 2.0-SNAPSHOT test-nima-jsonb diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index 7f2d890c7..0d1e6a174 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 1.42 + 2.0-SNAPSHOT test-nima From e7b856056f5e5032bbdf19b9cb72bf2f2b30eb22 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sat, 24 Jun 2023 19:35:00 -0400 Subject: [PATCH 0772/1323] (Javalin Jsonb) Write directly to Jetty HttpOutput Stream --- .../io/avaje/http/generator/javalin/ControllerMethodWriter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java index b034edbaa..ec5817548 100644 --- a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java +++ b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java @@ -137,7 +137,7 @@ private void writeContextReturn(final String resultVariableName) { if ("java.util.concurrent.CompletableFuture".equals(uType.mainType())) { uType = uType.paramRaw(); } - writer.append(" %sJsonType.toJson(%s, ctx.contentType(\"application/json\").outputStream());", uType.shortName(), resultVariableName); + writer.append(" %sJsonType.toJson(%s, ctx.contentType(\"application/json\").res().getOutputStream());", uType.shortName(), resultVariableName); } else { writer.append(" ctx.json(%s);", resultVariableName); } From 46ae11ea16817842d29815bbd61607184dead291 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sat, 24 Jun 2023 20:05:22 -0400 Subject: [PATCH 0773/1323] flag to disable jsonb direct writes --- .../avaje/http/generator/core/BaseProcessor.java | 2 +- .../http/generator/core/ProcessingContext.java | 6 ++++++ .../generator/javalin/ControllerMethodWriter.java | 14 ++++++++++---- .../helidon/nima/ControllerMethodWriter.java | 6 ++++-- 4 files changed, 21 insertions(+), 7 deletions(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java index 7e4e8be92..94e4dcea7 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java @@ -11,7 +11,7 @@ import javax.lang.model.element.Element; import javax.lang.model.element.TypeElement; -@SupportedOptions({"useJavax", "useSingleton", "instrumentRequests"}) +@SupportedOptions({"useJavax", "useSingleton", "instrumentRequests","disableDirectWrites"}) public abstract class BaseProcessor extends AbstractProcessor { @Override diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java index ba60509ec..d23ed6b63 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java @@ -41,6 +41,7 @@ private static final class Ctx { private final boolean useJavax; private final String diAnnotation; private final boolean instrumentAllMethods; + private final boolean disableDirectWrites; Ctx(ProcessingEnvironment env, PlatformAdapter adapter, boolean generateOpenAPI) { readAdapter = adapter; @@ -57,6 +58,7 @@ private static final class Ctx { final var options = env.getOptions(); final var singletonOverride = options.get("useSingleton"); this.instrumentAllMethods = Boolean.parseBoolean(options.get("instrumentRequests")); + this.disableDirectWrites = Boolean.parseBoolean(options.get("disableDirectWrites")); if (singletonOverride != null) { useComponent = !Boolean.parseBoolean(singletonOverride); } else { @@ -184,6 +186,10 @@ public static boolean instrumentAllWebMethods() { return CTX.get().instrumentAllMethods; } + public static boolean disabledDirectWrites() { + return CTX.get().disableDirectWrites; + } + public static Filer filer() { return CTX.get().filer; } diff --git a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java index ec5817548..b7e6460dc 100644 --- a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java +++ b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java @@ -1,6 +1,6 @@ package io.avaje.http.generator.javalin; -import static io.avaje.http.generator.core.ProcessingContext.platform; +import static io.avaje.http.generator.core.ProcessingContext.*; import io.avaje.http.generator.core.Append; import io.avaje.http.generator.core.MethodParam; @@ -26,7 +26,7 @@ class ControllerMethodWriter { this.method = method; this.writer = writer; this.webMethod = method.webMethod(); - this.useJsonB = useJsonB; + this.useJsonB = useJsonB && !disabledDirectWrites(); this.instrumentContext = method.instrumentContext(); } @@ -134,10 +134,16 @@ private void writeContextReturn(final String resultVariableName) { if (produces == null || MediaType.APPLICATION_JSON.getValue().equalsIgnoreCase(produces)) { if (useJsonB) { var uType = UType.parse(method.returnType()); - if ("java.util.concurrent.CompletableFuture".equals(uType.mainType())) { + final boolean isfuture = "java.util.concurrent.CompletableFuture".equals(uType.mainType()); + if (isfuture) { uType = uType.paramRaw(); + writer.append(" try {"); + } + writer.append(" %sJsonType.toJson(%s, ctx.contentType(\"application/json\").res().getOutputStream());", + uType.shortName(), resultVariableName); + if (isfuture) { + writer.append(" } catch (java.io.IOException e) { throw new java.io.UncheckedIOException(e); }"); } - writer.append(" %sJsonType.toJson(%s, ctx.contentType(\"application/json\").res().getOutputStream());", uType.shortName(), resultVariableName); } else { writer.append(" ctx.json(%s);", resultVariableName); } diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java index 6a20eb7aa..2d28454cc 100644 --- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java +++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java @@ -1,5 +1,6 @@ package io.avaje.http.generator.helidon.nima; +import static io.avaje.http.generator.core.ProcessingContext.disabledDirectWrites; import static io.avaje.http.generator.core.ProcessingContext.platform; import java.util.List; @@ -140,8 +141,9 @@ void writeHandler(boolean requestScoped) { private boolean producesJson() { return useJsonB - && !"byte[]".equals(method.returnType().toString()) - && (method.produces() == null || method.produces().toLowerCase().contains("json")); + && !disabledDirectWrites() + && !"byte[]".equals(method.returnType().toString()) + && (method.produces() == null || method.produces().toLowerCase().contains("json")); } private boolean missingServerResponse(List params) { From e01c5fe1f7a7a87cfbde709b77ab523ee550e94a Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Mon, 26 Jun 2023 08:11:36 +1200 Subject: [PATCH 0774/1323] Version 1.43 --- http-api/pom.xml | 2 +- http-client-gson-adapter/pom.xml | 4 ++-- http-client/pom.xml | 2 +- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 2 +- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-generator-nima/pom.xml | 2 +- http-inject-plugin/pom.xml | 2 +- pom.xml | 2 +- tests/pom.xml | 2 +- tests/test-client-generation/pom.xml | 2 +- tests/test-client/pom.xml | 2 +- tests/test-helidon/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- 20 files changed, 21 insertions(+), 21 deletions(-) diff --git a/http-api/pom.xml b/http-api/pom.xml index f28e5d9a9..3b6664aa5 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-SNAPSHOT + 1.43 .. diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index ec3be33f3..a7cbd5e51 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-SNAPSHOT + 1.43 avaje-http-client-gson @@ -20,7 +20,7 @@ io.avaje avaje-http-client - 2.0-SNAPSHOT + 1.43 provided diff --git a/http-client/pom.xml b/http-client/pom.xml index 6ce20dcc7..43fd10f1c 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-SNAPSHOT + 1.43 avaje-http-client diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index e27a75daf..9cb8adc19 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-SNAPSHOT + 1.43 avaje-http-client-generator diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index fc61ad4b6..2511d071f 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-SNAPSHOT + 1.43 avaje-http-generator-core diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index 4764a0583..fd26ca026 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-SNAPSHOT + 1.43 avaje-http-helidon-generator diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index 73d842f51..248d31771 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-SNAPSHOT + 1.43 avaje-http-javalin-generator diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index 5686ea66c..e3ee92168 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-SNAPSHOT + 1.43 avaje-http-jex-generator diff --git a/http-generator-nima/pom.xml b/http-generator-nima/pom.xml index 3b9d670a7..79952b7f1 100644 --- a/http-generator-nima/pom.xml +++ b/http-generator-nima/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.0-SNAPSHOT + 1.43 avaje-http-nima-generator diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index 29c0cd168..b47b5ad2a 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-SNAPSHOT + 1.43 .. diff --git a/pom.xml b/pom.xml index b3518152a..b2fa81561 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-parent - 2.0-SNAPSHOT + 1.43 pom diff --git a/tests/pom.xml b/tests/pom.xml index 4a0d81dbc..0ce77f31c 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.0-SNAPSHOT + 1.43 tests diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index e491690b1..9f3f58167 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.0-SNAPSHOT + 1.43 test-client-generation diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index 25e359d7a..6b79cf666 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.0-SNAPSHOT + 1.43 test-client diff --git a/tests/test-helidon/pom.xml b/tests/test-helidon/pom.xml index 950528016..a332363bd 100644 --- a/tests/test-helidon/pom.xml +++ b/tests/test-helidon/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.0-SNAPSHOT + 1.43 test-helidon diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index edb44b237..0b8fd137e 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 2.0-SNAPSHOT + 1.43 test-javalin-jsonb diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index b2c03098a..e8bc83b32 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.0-SNAPSHOT + 1.43 test-javalin diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 6e331c8ce..7d530bea3 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.0-SNAPSHOT + 1.43 test-jex diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index c3b176ea0..83ff5bd16 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.0-SNAPSHOT + 1.43 test-nima-jsonb diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index 0d1e6a174..581a0959b 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.0-SNAPSHOT + 1.43 test-nima From 5f541b1f22c86bd7089ac490d542d716fb940642 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Mon, 26 Jun 2023 08:12:13 +1200 Subject: [PATCH 0775/1323] Bump to next snapshot --- http-api/pom.xml | 2 +- http-client-gson-adapter/pom.xml | 4 ++-- http-client/pom.xml | 2 +- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 2 +- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-generator-nima/pom.xml | 2 +- http-inject-plugin/pom.xml | 2 +- pom.xml | 2 +- tests/pom.xml | 2 +- tests/test-client-generation/pom.xml | 2 +- tests/test-client/pom.xml | 2 +- tests/test-helidon/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- 20 files changed, 21 insertions(+), 21 deletions(-) diff --git a/http-api/pom.xml b/http-api/pom.xml index 3b6664aa5..ce424878a 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.43 + 1.44-SNAPSHOT .. diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index a7cbd5e51..7406ab9e1 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.43 + 1.44-SNAPSHOT avaje-http-client-gson @@ -20,7 +20,7 @@ io.avaje avaje-http-client - 1.43 + 1.44-SNAPSHOT provided diff --git a/http-client/pom.xml b/http-client/pom.xml index 43fd10f1c..af9b59ab9 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.43 + 1.44-SNAPSHOT avaje-http-client diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index 9cb8adc19..6d44c770a 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.43 + 1.44-SNAPSHOT avaje-http-client-generator diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 2511d071f..d5c634ca1 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.43 + 1.44-SNAPSHOT avaje-http-generator-core diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index fd26ca026..462a5ca06 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.43 + 1.44-SNAPSHOT avaje-http-helidon-generator diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index 248d31771..4e2b50512 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.43 + 1.44-SNAPSHOT avaje-http-javalin-generator diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index e3ee92168..138b88e0b 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.43 + 1.44-SNAPSHOT avaje-http-jex-generator diff --git a/http-generator-nima/pom.xml b/http-generator-nima/pom.xml index 79952b7f1..3f8dde5d6 100644 --- a/http-generator-nima/pom.xml +++ b/http-generator-nima/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 1.43 + 1.44-SNAPSHOT avaje-http-nima-generator diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index b47b5ad2a..103d32e1f 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.43 + 1.44-SNAPSHOT .. diff --git a/pom.xml b/pom.xml index b2fa81561..b0cbadb7e 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-parent - 1.43 + 1.44-SNAPSHOT pom diff --git a/tests/pom.xml b/tests/pom.xml index 0ce77f31c..3d769de71 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 1.43 + 1.44-SNAPSHOT tests diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index 9f3f58167..e36dbca02 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.43 + 1.44-SNAPSHOT test-client-generation diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index 6b79cf666..850eaefdd 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 1.43 + 1.44-SNAPSHOT test-client diff --git a/tests/test-helidon/pom.xml b/tests/test-helidon/pom.xml index a332363bd..d4639835b 100644 --- a/tests/test-helidon/pom.xml +++ b/tests/test-helidon/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.43 + 1.44-SNAPSHOT test-helidon diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 0b8fd137e..8a0572973 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 1.43 + 1.44-SNAPSHOT test-javalin-jsonb diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index e8bc83b32..e3d4ea09a 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.43 + 1.44-SNAPSHOT test-javalin diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 7d530bea3..5257102d3 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.43 + 1.44-SNAPSHOT test-jex diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 83ff5bd16..3e02b2ea9 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.43 + 1.44-SNAPSHOT test-nima-jsonb diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index 581a0959b..c833e406d 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 1.43 + 1.44-SNAPSHOT test-nima From 8d1c9f07916d022fe2668e46a4d87703aef5fa2b Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Mon, 3 Jul 2023 12:58:54 -0400 Subject: [PATCH 0776/1323] fix jsonb for modular projects --- .../generator/client/ClientProcessor.java | 13 ++----- .../http/generator/core/BaseProcessor.java | 19 ++++++----- .../avaje/http/generator/core/JsonBUtil.java | 12 ------- .../generator/core/ProcessingContext.java | 7 +++- .../generator/javalin/JavalinProcessor.java | 10 ------ .../generator/helidon/nima/NimaProcessor.java | 12 +------ .../http/generator/JavalinProcessorTest.java | 34 +++++++++++++------ .../http/generator/NimaProcessorTest.java | 4 +-- 8 files changed, 45 insertions(+), 66 deletions(-) diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java index 8e84a99eb..c74e44714 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java @@ -20,7 +20,6 @@ import io.avaje.http.generator.core.ClientPrism; import io.avaje.http.generator.core.ControllerReader; import io.avaje.http.generator.core.ImportPrism; -import io.avaje.http.generator.core.JsonBUtil; import io.avaje.http.generator.core.ProcessingContext; @SupportedAnnotationTypes({ClientPrism.PRISM_TYPE, ImportPrism.PRISM_TYPE}) @@ -28,20 +27,12 @@ public class ClientProcessor extends AbstractProcessor { private final ComponentMetaData metaData = new ComponentMetaData(); - private final boolean useJsonB; + private boolean useJsonB; private SimpleComponentWriter componentWriter; private boolean readModuleInfo; - public ClientProcessor() { - useJsonB = JsonBUtil.detectJsonb(); - } - - public ClientProcessor(boolean useJsonb) { - useJsonB = useJsonb; - } - @Override public SourceVersion getSupportedSourceVersion() { return SourceVersion.latest(); @@ -52,8 +43,8 @@ public synchronized void init(ProcessingEnvironment processingEnv) { super.init(processingEnv); this.processingEnv = processingEnv; ProcessingContext.init(processingEnv, new ClientPlatformAdapter(), false); - this.componentWriter = new SimpleComponentWriter(metaData); + useJsonB = ProcessingContext.useJsonb(); } @Override diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java index 94e4dcea7..e1d3ebe13 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java @@ -14,6 +14,8 @@ @SupportedOptions({"useJavax", "useSingleton", "instrumentRequests","disableDirectWrites"}) public abstract class BaseProcessor extends AbstractProcessor { + protected boolean useJsonB; + @Override public SourceVersion getSupportedSourceVersion() { return SourceVersion.latest(); @@ -28,6 +30,7 @@ public Set getSupportedAnnotationTypes() { public synchronized void init(ProcessingEnvironment processingEnv) { super.init(processingEnv); ProcessingContext.init(processingEnv, providePlatformAdapter()); + useJsonB = ProcessingContext.useJsonb(); } /** Provide the platform specific adapter to use for Javalin, Helidon etc. */ @@ -44,7 +47,7 @@ public boolean process(Set annotations, RoundEnvironment final Set controllers = round.getElementsAnnotatedWith(typeElement(ControllerPrism.PRISM_TYPE)); - for (Element controller : controllers) { + for (final Element controller : controllers) { writeAdapter(controller); } @@ -57,7 +60,7 @@ public boolean process(Set annotations, RoundEnvironment private void readOpenApiDefinition(RoundEnvironment round) { final Set elements = round.getElementsAnnotatedWith(typeElement(OpenAPIDefinitionPrism.PRISM_TYPE)); - for (Element element : elements) { + for (final Element element : elements) { doc().readApiDefinition(element); } } @@ -65,24 +68,24 @@ private void readOpenApiDefinition(RoundEnvironment round) { private void readTagDefinitions(RoundEnvironment round) { Set elements = round.getElementsAnnotatedWith(typeElement(TagPrism.PRISM_TYPE)); - for (Element element : elements) { + for (final Element element : elements) { doc().addTagDefinition(element); } elements = round.getElementsAnnotatedWith(typeElement(TagsPrism.PRISM_TYPE)); - for (Element element : elements) { + for (final Element element : elements) { doc().addTagsDefinition(element); } } private void readSecuritySchemes(RoundEnvironment round) { Set elements = round.getElementsAnnotatedWith(typeElement(SecuritySchemePrism.PRISM_TYPE)); - for (Element element : elements) { + for (final Element element : elements) { doc().addSecurityScheme(element); } elements = round.getElementsAnnotatedWith(typeElement(SecuritySchemesPrism.PRISM_TYPE)); - for (Element element : elements) { + for (final Element element : elements) { doc().addSecuritySchemes(element); } } @@ -93,11 +96,11 @@ private void writeOpenAPI() { private void writeAdapter(Element controller) { if (controller instanceof TypeElement) { - ControllerReader reader = new ControllerReader((TypeElement) controller); + final ControllerReader reader = new ControllerReader((TypeElement) controller); reader.read(true); try { writeControllerAdapter(reader); - } catch (Throwable e) { + } catch (final Throwable e) { e.printStackTrace(); logError(reader.beanType(), "Failed to write $Route class " + e); } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java index 4f40e1c39..f6332ba34 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java @@ -8,18 +8,6 @@ public class JsonBUtil { private JsonBUtil() {} - /** - * Return true if avaje-jsonb is detected in the classpath. - */ - public static boolean detectJsonb() { - try { - Class.forName("io.avaje.jsonb.Jsonb"); - return true; - } catch (final ClassNotFoundException e) { - return false; - } - } - public static Map jsonTypes(ControllerReader reader) { final Map jsonTypes = new LinkedHashMap<>(); diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java index d23ed6b63..3b7d5fcf9 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java @@ -42,6 +42,7 @@ private static final class Ctx { private final String diAnnotation; private final boolean instrumentAllMethods; private final boolean disableDirectWrites; + private final boolean useJsonb; Ctx(ProcessingEnvironment env, PlatformAdapter adapter, boolean generateOpenAPI) { readAdapter = adapter; @@ -65,7 +66,7 @@ private static final class Ctx { useComponent = elementUtils.getTypeElement(Constants.COMPONENT) != null; } diAnnotation = (useComponent ? "@Component" : "@Singleton"); - + useJsonb = elementUtils.getTypeElement("io.avaje.jsonb.Jsonb") != null; final var javax = elementUtils.getTypeElement(Constants.SINGLETON_JAVAX) != null; final var jakarta = elementUtils.getTypeElement(Constants.SINGLETON_JAKARTA) != null; final var override = options.get("useJavax"); @@ -186,6 +187,10 @@ public static boolean instrumentAllWebMethods() { return CTX.get().instrumentAllMethods; } + public static boolean useJsonb() { + return CTX.get().useJsonb; + } + public static boolean disabledDirectWrites() { return CTX.get().disableDirectWrites; } diff --git a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinProcessor.java b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinProcessor.java index 1e797b958..7d40e02c1 100644 --- a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinProcessor.java +++ b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinProcessor.java @@ -6,16 +6,6 @@ public class JavalinProcessor extends BaseProcessor { - private final boolean useJsonB; - - public JavalinProcessor() { - useJsonB = JsonBUtil.detectJsonb(); - } - - public JavalinProcessor(boolean useJsonb) { - useJsonB = useJsonb; - } - @Override protected PlatformAdapter providePlatformAdapter() { return new JavalinAdapter(useJsonB); diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/NimaProcessor.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/NimaProcessor.java index cb0311a0b..ff815ad8b 100644 --- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/NimaProcessor.java +++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/NimaProcessor.java @@ -6,16 +6,6 @@ public class NimaProcessor extends BaseProcessor { - private final boolean jsonB; - - public NimaProcessor() { - jsonB = JsonBUtil.detectJsonb(); - } - - public NimaProcessor(boolean useJsonb) { - jsonB = useJsonb; - } - @Override protected PlatformAdapter providePlatformAdapter() { return new NimaPlatformAdapter(); @@ -23,6 +13,6 @@ protected PlatformAdapter providePlatformAdapter() { @Override public void writeControllerAdapter(ControllerReader reader) throws IOException { - new ControllerWriter(reader, jsonB).write(); + new ControllerWriter(reader, useJsonB).write(); } } diff --git a/tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/JavalinProcessorTest.java b/tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/JavalinProcessorTest.java index c58970cdb..cc5441088 100644 --- a/tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/JavalinProcessorTest.java +++ b/tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/JavalinProcessorTest.java @@ -51,7 +51,12 @@ public void runAnnotationProcessor() throws Exception { final var task = compiler.getTask( - new PrintWriter(System.out), null, null, List.of("--release=11"), null, files); + new PrintWriter(System.out), + null, + null, + List.of("--release=11", "-AdisableDirectWrites=true"), + null, + files); task.setProcessors(List.of(new JavalinProcessor())); assertThat(task.call()).isTrue(); @@ -71,7 +76,7 @@ public void runAnnotationProcessorJsonB() throws Exception { final var task = compiler.getTask( new PrintWriter(System.out), null, null, List.of("--release=11"), null, files); - task.setProcessors(List.of(new JavalinProcessor(true), new Processor())); + task.setProcessors(List.of(new JavalinProcessor(), new Processor())); assertThat(task.call()).isTrue(); assert Files.readString( @@ -92,10 +97,14 @@ public void runAnnotationProcessorJavax() throws Exception { new PrintWriter(System.out), null, null, - List.of("--release=11", "-AuseJavax=true", "-AuseSingleton=true"), + List.of( + "--release=11", + "-AuseJavax=true", + "-AuseSingleton=true", + "-AdisableDirectWrites=true"), null, files); - task.setProcessors(List.of(new JavalinProcessor(false), new Processor())); + task.setProcessors(List.of(new JavalinProcessor(), new Processor())); // we don't have javax on the cp assertThat(task.call()).isFalse(); @@ -117,10 +126,14 @@ public void runAnnotationProcessorJakarta() throws Exception { new PrintWriter(System.out), null, null, - List.of("--release=11", "-AuseJavax=false", "-AuseSingleton=true"), + List.of( + "--release=11", + "-AuseJavax=false", + "-AuseSingleton=true", + "-AdisableDirectWrites=true"), null, files); - task.setProcessors(List.of(new JavalinProcessor(false), new Processor())); + task.setProcessors(List.of(new JavalinProcessor(), new Processor())); assertThat(task.call()).isTrue(); @@ -147,10 +160,10 @@ public void testOpenAPIGeneration() throws Exception { new PrintWriter(System.out), null, null, - List.of("--release=11"), + List.of("--release=11", "-AdisableDirectWrites=true"), null, openAPIController); - task.setProcessors(List.of(new JavalinProcessor(false), new Processor())); + task.setProcessors(List.of(new JavalinProcessor(), new Processor())); assertThat(task.call()).isTrue(); @@ -181,10 +194,10 @@ public void testInheritableOpenAPIGeneration() throws Exception { new PrintWriter(System.out), null, null, - List.of("--release=11"), + List.of("--release=11", "-AdisableDirectWrites=true"), null, openAPIController); - task.setProcessors(List.of(new JavalinProcessor(false), new Processor())); + task.setProcessors(List.of(new JavalinProcessor(), new Processor())); assertThat(task.call()).isTrue(); @@ -196,7 +209,6 @@ public void testInheritableOpenAPIGeneration() throws Exception { assert expectedOpenApiJson.equals(generatedOpenApi); } - private Iterable getSourceFiles(String source) throws Exception { final var compiler = ToolProvider.getSystemJavaCompiler(); final var files = compiler.getStandardFileManager(null, null, null); diff --git a/tests/test-nima-jsonb/src/test/java/io/avaje/http/generator/NimaProcessorTest.java b/tests/test-nima-jsonb/src/test/java/io/avaje/http/generator/NimaProcessorTest.java index de8967ad6..1bb383465 100644 --- a/tests/test-nima-jsonb/src/test/java/io/avaje/http/generator/NimaProcessorTest.java +++ b/tests/test-nima-jsonb/src/test/java/io/avaje/http/generator/NimaProcessorTest.java @@ -45,8 +45,8 @@ void runAnnotationProcessor() throws Exception { final var task = compiler.getTask( - new PrintWriter(System.out), null, null, List.of("--release=19"), null, files); - task.setProcessors(List.of(new NimaProcessor(false))); + new PrintWriter(System.out), null, null, List.of("--release=20", "-AdisableDirectWrites=true"), null, files); + task.setProcessors(List.of(new NimaProcessor())); assertThat(task.call()).isTrue(); } From 2ce08b8e6039b5bf9560d81739045dfa87351d0e Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Mon, 3 Jul 2023 13:10:30 -0400 Subject: [PATCH 0777/1323] Fix Nima Generated Jsonb code --- README.md | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 4ed06c76f..f9b774f97 100644 --- a/README.md +++ b/README.md @@ -159,7 +159,6 @@ public class WidgetController$Route implements WebRoutes { }); } - } ``` @@ -190,7 +189,6 @@ public class WidgetController$Route implements Service { private void _getAll(ServerRequest req, ServerResponse res) { res.send(controller.getAll()); } - } ``` @@ -224,7 +222,6 @@ public class WidgetController$Route implements HttpService { var result = controller.getAll(); res.send(result); } - } ``` @@ -264,7 +261,6 @@ public class WidgetController$Route implements WebRoutes { }); } - } ``` @@ -303,9 +299,8 @@ public class WidgetController$Route implements HttpService { private void _getAll(ServerRequest req, ServerResponse res) { var pathParams = req.path().pathParameters(); var result = controller.getAll(); - res.headers().contentType(io.helidon.common.http.HttpMediaType.APPLICATION_JSON); - listWidgetJsonType.toJson(result, res.outputStream()); + res.headers().contentType(HttpMediaType.APPLICATION_JSON); + listWidgetJsonType.toJson(result, JsonOutput.of(res)); } - } ``` From b3a7dff604cd866c747f0ef0a3d05edc0a145499 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Mon, 3 Jul 2023 13:11:02 -0400 Subject: [PATCH 0778/1323] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f9b774f97..fe4653c87 100644 --- a/README.md +++ b/README.md @@ -293,7 +293,7 @@ public class WidgetController$Route implements HttpService { int id = asInt(pathParams.first("id").get()); var result = controller.getById(id); res.headers().contentType(io.helidon.common.http.HttpMediaType.APPLICATION_JSON); - widgetJsonType.toJson(result, res.outputStream()); + widgetJsonType.toJson(result, JsonOutput.of(res)); } private void _getAll(ServerRequest req, ServerResponse res) { From 05f8f768906906db27796c89da919f2cf174771c Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Mon, 3 Jul 2023 13:12:56 -0400 Subject: [PATCH 0779/1323] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index fe4653c87..4e33f3806 100644 --- a/README.md +++ b/README.md @@ -292,7 +292,7 @@ public class WidgetController$Route implements HttpService { var pathParams = req.path().pathParameters(); int id = asInt(pathParams.first("id").get()); var result = controller.getById(id); - res.headers().contentType(io.helidon.common.http.HttpMediaType.APPLICATION_JSON); + res.headers().contentType(HttpMediaType.APPLICATION_JSON); widgetJsonType.toJson(result, JsonOutput.of(res)); } From b73c79025b00013fd45e42dac0421cbb0dace04c Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Tue, 4 Jul 2023 23:12:35 -0400 Subject: [PATCH 0780/1323] Update Trim Annotation Logic Now can handle all the wacky annotation situations --- .../io/avaje/http/generator/core/Util.java | 33 ++++++++++++++++--- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/Util.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/Util.java index 10d8081c5..5519fc06b 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/Util.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/Util.java @@ -11,8 +11,16 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; public class Util { + // whitespace not in quotes + private static final Pattern WHITE_SPACE_REGEX = + Pattern.compile("\\s+(?=([^\"]*\"[^\"]*\")*[^\"]*$)"); + // comma not in quotes + private static final Pattern COMMA_PATTERN = + Pattern.compile(", (?=(?:[^\\\"]*\\\"[^\\\"]*\\\")*[^\\\"]*$)"); /** * Parse the raw type potentially handling generic parameters. @@ -40,12 +48,29 @@ public static String typeDef(TypeMirror typeMirror) { } } - public static String trimAnnotations(String type) { - int pos = type.indexOf("@"); + /** Trim off annotations from the raw type if present. */ + public static String trimAnnotations(String input) { + + input = COMMA_PATTERN.matcher(input).replaceAll(","); + + return cutAnnotations(input); + } + + private static String cutAnnotations(String input) { + final int pos = input.indexOf("@"); if (pos == -1) { - return type; + return input; } - return type.substring(0, pos) + type.substring(type.lastIndexOf(' ') + 1); + + final Matcher matcher = WHITE_SPACE_REGEX.matcher(input); + + int currentIndex = 0; + if (matcher.find()) { + currentIndex = matcher.start(); + } + final var result = input.substring(0, pos) + input.substring(currentIndex + 1); + + return cutAnnotations(result); } static String trimPath(String value) { From 61eec2fa7d7ba49054c6026fe54a64c8ee4b43e4 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Wed, 5 Jul 2023 16:14:44 +1200 Subject: [PATCH 0781/1323] No effective change, tidy generator Util --- .../src/main/java/io/avaje/http/generator/core/Util.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/Util.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/Util.java index 5519fc06b..779f63fe5 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/Util.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/Util.java @@ -41,7 +41,6 @@ public static UType parse(String rawType) { public static String typeDef(TypeMirror typeMirror) { if (typeMirror.getKind() == TypeKind.DECLARED) { DeclaredType declaredType = (DeclaredType) typeMirror; - return declaredType.asElement().toString(); } else { return trimAnnotations(typeMirror.toString()); @@ -50,7 +49,6 @@ public static String typeDef(TypeMirror typeMirror) { /** Trim off annotations from the raw type if present. */ public static String trimAnnotations(String input) { - input = COMMA_PATTERN.matcher(input).replaceAll(","); return cutAnnotations(input); @@ -63,7 +61,6 @@ private static String cutAnnotations(String input) { } final Matcher matcher = WHITE_SPACE_REGEX.matcher(input); - int currentIndex = 0; if (matcher.find()) { currentIndex = matcher.start(); From cf5a047f7b51dc3e367877bdfc65da4f006e6f49 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Wed, 5 Jul 2023 23:08:25 +1200 Subject: [PATCH 0782/1323] Version 1.44 --- http-api/pom.xml | 2 +- http-client-gson-adapter/pom.xml | 4 ++-- http-client/pom.xml | 2 +- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 2 +- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-generator-nima/pom.xml | 2 +- http-inject-plugin/pom.xml | 2 +- pom.xml | 2 +- tests/pom.xml | 2 +- tests/test-client-generation/pom.xml | 2 +- tests/test-client/pom.xml | 2 +- tests/test-helidon/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- 20 files changed, 21 insertions(+), 21 deletions(-) diff --git a/http-api/pom.xml b/http-api/pom.xml index ce424878a..03a6ccb99 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.44-SNAPSHOT + 1.44 .. diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index 7406ab9e1..d76bc63fb 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.44-SNAPSHOT + 1.44 avaje-http-client-gson @@ -20,7 +20,7 @@ io.avaje avaje-http-client - 1.44-SNAPSHOT + 1.44 provided diff --git a/http-client/pom.xml b/http-client/pom.xml index af9b59ab9..454f31e20 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.44-SNAPSHOT + 1.44 avaje-http-client diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index 6d44c770a..5ba696d88 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.44-SNAPSHOT + 1.44 avaje-http-client-generator diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index d5c634ca1..fb5dfd613 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.44-SNAPSHOT + 1.44 avaje-http-generator-core diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index 462a5ca06..c8b591b53 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.44-SNAPSHOT + 1.44 avaje-http-helidon-generator diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index 4e2b50512..57b75a5a7 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.44-SNAPSHOT + 1.44 avaje-http-javalin-generator diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index 138b88e0b..0f34f6e63 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.44-SNAPSHOT + 1.44 avaje-http-jex-generator diff --git a/http-generator-nima/pom.xml b/http-generator-nima/pom.xml index 3f8dde5d6..64c805cfa 100644 --- a/http-generator-nima/pom.xml +++ b/http-generator-nima/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 1.44-SNAPSHOT + 1.44 avaje-http-nima-generator diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index 103d32e1f..ea9b71766 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.44-SNAPSHOT + 1.44 .. diff --git a/pom.xml b/pom.xml index b0cbadb7e..dc0b68474 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-parent - 1.44-SNAPSHOT + 1.44 pom diff --git a/tests/pom.xml b/tests/pom.xml index 3d769de71..1a2bf65e3 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 1.44-SNAPSHOT + 1.44 tests diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index e36dbca02..5fa3fcb20 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.44-SNAPSHOT + 1.44 test-client-generation diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index 850eaefdd..28e807aee 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 1.44-SNAPSHOT + 1.44 test-client diff --git a/tests/test-helidon/pom.xml b/tests/test-helidon/pom.xml index d4639835b..62b18712c 100644 --- a/tests/test-helidon/pom.xml +++ b/tests/test-helidon/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.44-SNAPSHOT + 1.44 test-helidon diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 8a0572973..a5084b0cb 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 1.44-SNAPSHOT + 1.44 test-javalin-jsonb diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index e3d4ea09a..4712cd449 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.44-SNAPSHOT + 1.44 test-javalin diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 5257102d3..8ec67288d 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.44-SNAPSHOT + 1.44 test-jex diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 3e02b2ea9..56e8883f7 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.44-SNAPSHOT + 1.44 test-nima-jsonb diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index c833e406d..2e0d20b75 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 1.44-SNAPSHOT + 1.44 test-nima From 8fc3fa24998628ea104c0cbc2510c00b7f7bff54 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Wed, 5 Jul 2023 23:09:00 +1200 Subject: [PATCH 0783/1323] Bump to next snapshot --- http-api/pom.xml | 2 +- http-client-gson-adapter/pom.xml | 4 ++-- http-client/pom.xml | 2 +- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 2 +- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-generator-nima/pom.xml | 2 +- http-inject-plugin/pom.xml | 2 +- pom.xml | 2 +- tests/pom.xml | 2 +- tests/test-client-generation/pom.xml | 2 +- tests/test-client/pom.xml | 2 +- tests/test-helidon/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- 20 files changed, 21 insertions(+), 21 deletions(-) diff --git a/http-api/pom.xml b/http-api/pom.xml index 03a6ccb99..518806f21 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.44 + 1.45-SNAPSHOT .. diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index d76bc63fb..d42761354 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.44 + 1.45-SNAPSHOT avaje-http-client-gson @@ -20,7 +20,7 @@ io.avaje avaje-http-client - 1.44 + 1.45-SNAPSHOT provided diff --git a/http-client/pom.xml b/http-client/pom.xml index 454f31e20..24959e50e 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.44 + 1.45-SNAPSHOT avaje-http-client diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index 5ba696d88..615f3382e 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.44 + 1.45-SNAPSHOT avaje-http-client-generator diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index fb5dfd613..2b30fa4fb 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.44 + 1.45-SNAPSHOT avaje-http-generator-core diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index c8b591b53..cbdca9ca3 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.44 + 1.45-SNAPSHOT avaje-http-helidon-generator diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index 57b75a5a7..4ddefab97 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.44 + 1.45-SNAPSHOT avaje-http-javalin-generator diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index 0f34f6e63..81fe263c1 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.44 + 1.45-SNAPSHOT avaje-http-jex-generator diff --git a/http-generator-nima/pom.xml b/http-generator-nima/pom.xml index 64c805cfa..573e59a5f 100644 --- a/http-generator-nima/pom.xml +++ b/http-generator-nima/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 1.44 + 1.45-SNAPSHOT avaje-http-nima-generator diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index ea9b71766..0fd01e2ff 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.44 + 1.45-SNAPSHOT .. diff --git a/pom.xml b/pom.xml index dc0b68474..1017b368a 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-parent - 1.44 + 1.45-SNAPSHOT pom diff --git a/tests/pom.xml b/tests/pom.xml index 1a2bf65e3..70a7e5109 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 1.44 + 1.45-SNAPSHOT tests diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index 5fa3fcb20..bde700ba3 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.44 + 1.45-SNAPSHOT test-client-generation diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index 28e807aee..e2ac460ac 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 1.44 + 1.45-SNAPSHOT test-client diff --git a/tests/test-helidon/pom.xml b/tests/test-helidon/pom.xml index 62b18712c..988129b05 100644 --- a/tests/test-helidon/pom.xml +++ b/tests/test-helidon/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.44 + 1.45-SNAPSHOT test-helidon diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index a5084b0cb..10d0d18b4 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 1.44 + 1.45-SNAPSHOT test-javalin-jsonb diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 4712cd449..9bdccfbee 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.44 + 1.45-SNAPSHOT test-javalin diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 8ec67288d..bf61100a0 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.44 + 1.45-SNAPSHOT test-jex diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 56e8883f7..34b2ed3ff 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.44 + 1.45-SNAPSHOT test-nima-jsonb diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index 2e0d20b75..fb1e3fb5b 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 1.44 + 1.45-SNAPSHOT test-nima From 85791e9c5009db9d9dbb6694f7c85b19f7ee3d77 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sat, 8 Jul 2023 15:45:07 -0400 Subject: [PATCH 0784/1323] add custom Content-Types to nima --- .../http/generator/helidon/nima/ControllerMethodWriter.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java index 2d28454cc..f00f09a60 100644 --- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java +++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java @@ -166,7 +166,9 @@ private void writeContextReturn() { case APPLICATION_JSON -> writer.append(contentTypeString + "APPLICATION_JSON);").eol(); case TEXT_HTML -> writer.append(contentTypeString + "TEXT_HTML);").eol(); case TEXT_PLAIN -> writer.append(contentTypeString + "TEXT_PLAIN);").eol(); - case UNKNOWN -> writer.append(contentTypeString + "create(\"%s\"));", produces).eol(); + case UNKNOWN -> writer + .append(contentTypeString + "create(\"%s\"));", producesOp.orElse("UNKNOWN")) + .eol(); } } From 11d33d153264833e04e0c0f65ec87f0b527a9c2d Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sat, 8 Jul 2023 16:22:33 -0400 Subject: [PATCH 0785/1323] support inputstream --- .../generator/core/ProcessingContext.java | 22 +++++++++++++++---- .../helidon/nima/ControllerMethodWriter.java | 15 ++++++++----- .../main/java/org/example/TestController.java | 4 ++-- 3 files changed, 30 insertions(+), 11 deletions(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java index 3b7d5fcf9..db0c5176c 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java @@ -3,7 +3,9 @@ import java.io.IOException; import java.util.List; import java.util.Objects; +import java.util.Optional; import java.util.stream.Collectors; +import java.util.stream.Stream; import javax.annotation.processing.Filer; import javax.annotation.processing.Messager; @@ -91,10 +93,6 @@ public static void init(ProcessingEnvironment env, PlatformAdapter adapter) { init(env, adapter, true); } - private static boolean isTypeAvailable(String canonicalName) { - return null != typeElement(canonicalName); - } - public static TypeElement typeElement(String canonicalName) { return CTX.get().elementUtils.getTypeElement(canonicalName); } @@ -198,4 +196,20 @@ public static boolean disabledDirectWrites() { public static Filer filer() { return CTX.get().filer; } + + public static boolean isAssignable2Interface(String type, String superType) { + return type.equals(superType) + || Optional.ofNullable(typeElement(type)).stream() + .flatMap(ProcessingContext::superTypes) + .anyMatch(superType::equals); + } + + static Stream superTypes(Element element) { + final Types types = CTX.get().typeUtils; + return types.directSupertypes(element.asType()).stream() + .filter(type -> !type.toString().contains("java.lang.Object")) + .map(superType -> (TypeElement) types.asElement(superType)) + .flatMap(e -> Stream.concat(superTypes(e), Stream.of(e))) + .map(Object::toString); + } } diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java index f00f09a60..b4b70ee98 100644 --- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java +++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java @@ -1,6 +1,6 @@ package io.avaje.http.generator.helidon.nima; -import static io.avaje.http.generator.core.ProcessingContext.disabledDirectWrites; +import static io.avaje.http.generator.core.ProcessingContext.*; import static io.avaje.http.generator.core.ProcessingContext.platform; import java.util.List; @@ -80,11 +80,11 @@ void writeHandler(boolean requestScoped) { } final var segments = method.pathSegments(); - if (!segments.isEmpty()) { + if (segments.fullPath().contains("{")) { writer.append(" var pathParams = req.path().pathParameters();").eol(); } - final var matrixSegments = segments.matrixSegments(); - for (final PathSegments.Segment matrixSegment : matrixSegments) { + + for (final PathSegments.Segment matrixSegment : segments.matrixSegments()) { matrixSegment.writeCreateSegment(writer, platform()); } @@ -127,9 +127,14 @@ void writeHandler(boolean requestScoped) { writer.append(")"); } writer.append(");").eol(); + if (!method.isVoid()) { writeContextReturn(); - if (producesJson()) { + + if (isAssignable2Interface(method.returnType().toString(), "java.io.InputStream")) { + final var uType = UType.parse(method.returnType()); + writer.append(" result.transferTo(res.outputStream());", uType.shortName()).eol(); + } else if (producesJson()) { final var uType = UType.parse(method.returnType()); writer.append(" %sJsonType.toJson(result, JsonOutput.of(res));", uType.shortName()).eol(); } else { diff --git a/tests/test-nima-jsonb/src/main/java/org/example/TestController.java b/tests/test-nima-jsonb/src/main/java/org/example/TestController.java index ae476c608..a0599753b 100644 --- a/tests/test-nima-jsonb/src/main/java/org/example/TestController.java +++ b/tests/test-nima-jsonb/src/main/java/org/example/TestController.java @@ -57,8 +57,8 @@ String enumQueryImplied(String s, @QueryParam ServerType type) { @InstrumentServerContext @Get(value = "/inputStream") - String stream(InputStream stream) { - return stream.toString(); + InputStream stream(InputStream stream) { + return stream; } From 6b2c63d92eb3ca1241a4e2422eee10acc3ffb8e1 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sun, 9 Jul 2023 16:44:46 -0400 Subject: [PATCH 0786/1323] throws exception --- .../http/generator/helidon/nima/ControllerMethodWriter.java | 2 +- .../src/main/java/org/example/TestController.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java index b4b70ee98..dd657b117 100644 --- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java +++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java @@ -41,7 +41,7 @@ void writeRule() { } void writeHandler(boolean requestScoped) { - writer.append(" private void _%s(ServerRequest req, ServerResponse res) {", method.simpleName()).eol(); + writer.append(" private void _%s(ServerRequest req, ServerResponse res) throws Exception {", method.simpleName()).eol(); final var bodyType = method.bodyType(); if (bodyType != null) { diff --git a/tests/test-nima-jsonb/src/main/java/org/example/TestController.java b/tests/test-nima-jsonb/src/main/java/org/example/TestController.java index a0599753b..3040911d1 100644 --- a/tests/test-nima-jsonb/src/main/java/org/example/TestController.java +++ b/tests/test-nima-jsonb/src/main/java/org/example/TestController.java @@ -57,7 +57,7 @@ String enumQueryImplied(String s, @QueryParam ServerType type) { @InstrumentServerContext @Get(value = "/inputStream") - InputStream stream(InputStream stream) { + InputStream stream(InputStream stream) throws Exception { return stream; } From c00b43c9f84069f8b8eb7a9fa9a3e5d0f1e80163 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Mon, 10 Jul 2023 15:33:31 +1200 Subject: [PATCH 0787/1323] No effective change, extract methods in Nima ControllerMethodWriter --- .../helidon/nima/ControllerMethodWriter.java | 66 ++++++++++--------- 1 file changed, 36 insertions(+), 30 deletions(-) diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java index dd657b117..32b052889 100644 --- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java +++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java @@ -15,6 +15,8 @@ import io.avaje.http.generator.core.WebMethod; import io.avaje.http.generator.core.openapi.MediaType; +import javax.lang.model.type.TypeMirror; + /** * Write code to register Web route for a given controller method. */ @@ -44,36 +46,13 @@ void writeHandler(boolean requestScoped) { writer.append(" private void _%s(ServerRequest req, ServerResponse res) throws Exception {", method.simpleName()).eol(); final var bodyType = method.bodyType(); if (bodyType != null) { - if ("InputStream".equals(bodyType)) { writer.append(" var %s = req.content().inputStream();", method.bodyName()).eol(); } else if (useJsonB) { - final var fieldName = - method.params().stream() - .filter(MethodParam::isBody) - .findFirst() - .orElseThrow() - .utype() - .shortName(); + final String fieldName = fieldNameOfBody(); writer.append(" var %s = %sJsonType.fromJson(req.content().inputStream());", method.bodyName(), fieldName).eol(); - } else { - // use default helidon content negotiation - method.params().stream() - .filter(MethodParam::isBody) - .forEach( - param -> { - final var type = param.utype(); - - writer.append(" var %s = req.content()", method.bodyName()); - writer.append(".as("); - if (type.param0() != null) { - writer.append("new io.helidon.common.GenericType<%s>() {}", type.full()); - } else { - writer.append("%s.class", type.full()); - } - writer.append(");").eol(); - }); + defaultHelidonBodyContent(); } } else if (usesFormParams()) { writer.append(" var formParams = req.content().as(Parameters.class);").eol(); @@ -130,8 +109,7 @@ void writeHandler(boolean requestScoped) { if (!method.isVoid()) { writeContextReturn(); - - if (isAssignable2Interface(method.returnType().toString(), "java.io.InputStream")) { + if (isInputStream(method.returnType())) { final var uType = UType.parse(method.returnType()); writer.append(" result.transferTo(res.outputStream());", uType.shortName()).eol(); } else if (producesJson()) { @@ -144,6 +122,36 @@ void writeHandler(boolean requestScoped) { writer.append(" }").eol().eol(); } + private boolean isInputStream(TypeMirror type) { + return isAssignable2Interface(type.toString(), "java.io.InputStream"); + } + + private void defaultHelidonBodyContent() { + method.params().stream() + .filter(MethodParam::isBody) + .forEach( + param -> { + final var type = param.utype(); + writer.append(" var %s = req.content()", method.bodyName()); + writer.append(".as("); + if (type.param0() != null) { + writer.append("new io.helidon.common.GenericType<%s>() {}", type.full()); + } else { + writer.append("%s.class", type.full()); + } + writer.append(");").eol(); + }); + } + + private String fieldNameOfBody() { + return method.params().stream() + .filter(MethodParam::isBody) + .findFirst() + .orElseThrow() + .utype() + .shortName(); + } + private boolean producesJson() { return useJsonB && !disabledDirectWrites() @@ -171,9 +179,7 @@ private void writeContextReturn() { case APPLICATION_JSON -> writer.append(contentTypeString + "APPLICATION_JSON);").eol(); case TEXT_HTML -> writer.append(contentTypeString + "TEXT_HTML);").eol(); case TEXT_PLAIN -> writer.append(contentTypeString + "TEXT_PLAIN);").eol(); - case UNKNOWN -> writer - .append(contentTypeString + "create(\"%s\"));", producesOp.orElse("UNKNOWN")) - .eol(); + case UNKNOWN -> writer.append(contentTypeString + "create(\"%s\"));", producesOp.orElse("UNKNOWN")).eol(); } } From 40173512b1c66cb43860f79144e33846797a7786 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Thu, 13 Jul 2023 01:36:07 -0400 Subject: [PATCH 0788/1323] add accept header to validation --- .../main/java/io/avaje/http/api/Valid.java | 25 +++++++----- .../java/io/avaje/http/api/Validator.java | 25 ++++++++---- .../webserver/HelloController$Route.java | 14 +++---- .../client/ClientPlatformAdapter.java | 20 ++++------ http-generator-core/pom.xml | 2 +- .../avaje/http/generator/core/Constants.java | 1 + .../http/generator/core/ControllerReader.java | 4 +- .../http/generator/core/ElementReader.java | 40 +++++++++++++------ .../http/generator/core/MethodReader.java | 10 +---- .../http/generator/core/PlatformAdapter.java | 2 + .../avaje/http/generator/core/ValidPrism.java | 35 ++++++++++++++++ .../http/generator/core/package-info.java | 3 -- .../helidon/HelidonPlatformAdapter.java | 6 +++ .../generator/javalin/JavalinAdapter.java | 6 +++ .../avaje/http/generator/jex/JexAdapter.java | 6 +++ .../helidon/nima/ControllerWriter.java | 1 + .../helidon/nima/NimaPlatformAdapter.java | 7 +++- http-hibernate-validator/pom.xml | 4 +- .../hibernate/validator/BeanValidator.java | 8 ++-- tests/test-javalin-jsonb/pom.xml | 2 +- .../org/example/myapp/web/GetBeanForm.java | 9 ++--- .../java/org/example/myapp/web/HelloForm.java | 11 +++-- tests/test-javalin/pom.xml | 2 +- .../org/example/myapp/web/GetBeanForm.java | 8 ++-- .../example/myapp/web/HelloController.java | 3 +- .../java/org/example/myapp/web/HelloForm.java | 13 +++--- tests/test-jex/pom.xml | 2 +- .../java/org/example/web/HelloController.java | 10 +++-- .../main/java/org/example/web/HelloDto.java | 4 +- 29 files changed, 182 insertions(+), 101 deletions(-) create mode 100644 http-generator-core/src/main/java/io/avaje/http/generator/core/ValidPrism.java diff --git a/http-api/src/main/java/io/avaje/http/api/Valid.java b/http-api/src/main/java/io/avaje/http/api/Valid.java index bc3fbe772..daddf6f65 100644 --- a/http-api/src/main/java/io/avaje/http/api/Valid.java +++ b/http-api/src/main/java/io/avaje/http/api/Valid.java @@ -9,18 +9,23 @@ import java.lang.annotation.Target; /** - * Add {@code @Valid} annotation on a controller/method/BeanParam that we want bean validation to - * be included for. When we do this controller methods that take a request payload will then have - * the request bean (populated by JSON payload or form parameters) validated before it is passed - * to the controller method. - *

- * When trying to validate a {@code @BeanParam} bean, this will need to be placed on the BeanParam type. - *

- * When using this annotation we need to provide an implementation of {@link Validator} to use. - *

- * Alternatively we can use the Jakarta {@code @Valid} along with a Jakarta validator implementation. + * Add {@code @Valid} annotation on a controller/method/BeanParam that we want bean validation to be + * included for. When we do this controller methods that take a request payload will then have the + * request bean (populated by JSON payload or form parameters) validated before it is passed to the + * controller method. + * + *

When trying to validate a {@code @BeanParam} bean, this will need to be placed on the + * BeanParam type. + * + *

When using this annotation we need to provide an implementation of {@link Validator} to use. + * + *

Alternatively we can use the Jakarta {@code @Valid} along with a Jakarta validator + * implementation. */ @Retention(SOURCE) @Target({METHOD, TYPE, PARAMETER}) public @interface Valid { + + /** Validation groups to use */ + Class[] groups() default {}; } diff --git a/http-api/src/main/java/io/avaje/http/api/Validator.java b/http-api/src/main/java/io/avaje/http/api/Validator.java index 1b2fa5a5c..8782e2d21 100644 --- a/http-api/src/main/java/io/avaje/http/api/Validator.java +++ b/http-api/src/main/java/io/avaje/http/api/Validator.java @@ -1,17 +1,28 @@ package io.avaje.http.api; -/** - * Validator for form beans or request beans. - */ +import java.util.Collection; +import java.util.List; +import java.util.Locale; +import java.util.Locale.LanguageRange; + +/** Validator for form beans or request beans. */ public interface Validator { /** * Validate the bean throwing an exception if the bean fails validation. - *

- * Typically the exception will be handled by a specific exception handler - * returning a 422 or 400 status code and usually a map of field paths to error messages. + * + *

Typically the exception will be handled by a specific exception handler returning a 422 or + * 400 status code and usually a map of field paths to error messages. * * @param bean The bean to validate */ - void validate(Object bean); + void validate(Object bean, String acceptLanguage, Class... groups) throws ValidationException; + + default Locale resolveLocale(String acceptLanguage, Collection locales) { + if (acceptLanguage == null) { + return null; + } + final List list = LanguageRange.parse(acceptLanguage); + return Locale.lookup(list, locales); + } } diff --git a/http-client/src/test/java/org/example/webserver/HelloController$Route.java b/http-client/src/test/java/org/example/webserver/HelloController$Route.java index 782f5f93f..729682f05 100644 --- a/http-client/src/test/java/org/example/webserver/HelloController$Route.java +++ b/http-client/src/test/java/org/example/webserver/HelloController$Route.java @@ -64,16 +64,16 @@ public void registerRoutes() { ApiBuilder.post("/hello", ctx -> { ctx.status(201); - HelloDto dto = ctx.bodyAsClass(HelloDto.class); - validator.validate(dto); + final HelloDto dto = ctx.bodyAsClass(HelloDto.class); + validator.validate(dto, "en-us"); ctx.json(controller.post(dto)); }); ApiBuilder.post("/hello/savebean/{foo}", ctx -> { ctx.status(201); - String foo = ctx.pathParam("foo"); - HelloDto dto = ctx.bodyAsClass(HelloDto.class); - validator.validate(dto); + final String foo = ctx.pathParam("foo"); + final HelloDto dto = ctx.bodyAsClass(HelloDto.class); + validator.validate(dto, "en-us"); controller.saveBean(foo, dto, ctx); }); @@ -86,7 +86,7 @@ public void registerRoutes() { helloForm.url = ctx.formParam("url"); helloForm.startDate = toLocalDate(ctx.formParam("startDate")); - validator.validate(helloForm); + validator.validate(helloForm, "en-us"); controller.saveForm(helloForm); }); @@ -107,7 +107,7 @@ public void registerRoutes() { helloForm.url = ctx.formParam("url"); helloForm.startDate = toLocalDate(ctx.formParam("startDate")); - validator.validate(helloForm); + validator.validate(helloForm, "en-us"); ctx.json(controller.saveForm3(helloForm)); }); diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientPlatformAdapter.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientPlatformAdapter.java index 0880fe3c7..509dc1ab4 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientPlatformAdapter.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientPlatformAdapter.java @@ -34,24 +34,20 @@ public boolean isBodyMethodParam() { public String indent() { return null; } - + // these have no meaning for client adapters @Override - public void controllerRoles(List roles, ControllerReader controller) { - - } + public void controllerRoles(List roles, ControllerReader controller) {} @Override - public void methodRoles(List roles, ControllerReader controller) { - - } + public void methodRoles(List roles, ControllerReader controller) {} @Override - public void writeReadParameter(Append writer, ParamType paramType, String paramName) { - - } + public void writeReadParameter(Append writer, ParamType paramType, String paramName) {} @Override - public void writeReadParameter(Append writer, ParamType paramType, String paramName, String paramDefault) { + public void writeReadParameter( + Append writer, ParamType paramType, String paramName, String paramDefault) {} - } + @Override + public void writeAcceptLanguage(Append writer) {} } diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 2b30fa4fb..4baf5b0a5 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -10,7 +10,7 @@ avaje-http-generator-core - 1.9 + 1.10 diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/Constants.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/Constants.java index 75d58dd2e..1fc3236f5 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/Constants.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/Constants.java @@ -19,6 +19,7 @@ public class Constants { static final String IMPORT_HTTP_API = "io.avaje.http.api.*"; static final String VALIDATOR = "io.avaje.http.api.Validator"; public static final String META_INF_COMPONENT = "META-INF/services/io.avaje.http.client.HttpClient$GeneratedComponent"; + public static final String ACCEPT_LANGUAGE = "Accept-Language"; } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java index ad51fbabd..cf6992745 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java @@ -180,9 +180,7 @@ private boolean initDocHidden() { private boolean initHasValid() { - return findAnnotation(JavaxValidPrism::getOptionalOn).isPresent() - || findAnnotation(JakartaValidPrism::getOptionalOn).isPresent() - || findAnnotation(ValidPrism::getOptionalOn).isPresent(); + return findAnnotation(ValidPrism::getOptionalOn).isPresent(); } String produces() { diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java index 0a64911d6..e537d4a7b 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java @@ -3,13 +3,16 @@ import static io.avaje.http.generator.core.ParamType.RESPONSE_HANDLER; import static io.avaje.http.generator.core.ProcessingContext.platform; import static io.avaje.http.generator.core.ProcessingContext.typeElement; +import static java.util.function.Predicate.not; +import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Optional; import java.util.Set; import javax.lang.model.element.*; +import javax.lang.model.type.TypeMirror; import io.avaje.http.generator.core.openapi.MethodDocBuilder; import io.avaje.http.generator.core.openapi.MethodParamDocBuilder; @@ -39,6 +42,8 @@ public class ElementReader { private boolean isParamMap; private final Set imports = new HashSet<>(); + private final List validationGroups = new ArrayList<>(); + ElementReader(Element element, ParamType defaultType, boolean formMarker) { this(element, null, Util.typeDef(element.asType()), defaultType, formMarker); } @@ -70,6 +75,11 @@ public class ElementReader { if (!contextType) { readAnnotations(element, defaultType); useValidation = useValidation(); + HttpValidPrism.getOptionalOn(element).map(HttpValidPrism::groups).stream() + .flatMap(List::stream) + .map(TypeMirror::toString) + .forEach(validationGroups::add); + this.imports.addAll(validationGroups); } else { paramType = ParamType.CONTEXT; useValidation = false; @@ -138,10 +148,7 @@ private boolean useValidation() { return false; } final var elementType = typeElement(rawType); - return elementType != null - && (ValidPrism.isPresent(elementType) - || JavaxValidPrism.isPresent(elementType) - || JakartaValidPrism.isPresent(elementType)); + return elementType != null && ValidPrism.isPresent(elementType); } private void readAnnotations(Element element, ParamType defaultType) { @@ -276,7 +283,14 @@ void buildApiDocumentation(MethodDocBuilder methodDoc) { void writeValidate(Append writer) { if (!contextType && typeHandler == null) { if (useValidation) { - writer.append("validator.validate(%s);", varName).eol(); + writer.append("validator.validate(%s, ", varName); + platform().writeAcceptLanguage(writer); + + if (!validationGroups.isEmpty()) { + validationGroups.forEach(g -> writer.append(", %s", Util.shortName(g))); + } + + writer.append(");").eol(); } else { writer.append("// no validation required on %s", varName).eol(); } @@ -290,7 +304,7 @@ void writeCtxGet(Append writer, PathSegments segments) { // body passed as method parameter (Helidon) return; } - String shortType = handlerShortType(); + final String shortType = handlerShortType(); writer.append("%s var %s = ", platform().indent(), varName); if (setValue(writer, segments, shortType)) { writer.append(";").eol(); @@ -320,12 +334,12 @@ private boolean setValue(Append writer, PathSegments segments, String shortType) return false; } if (impliedParamType) { - var name = matrixParamName != null ? matrixParamName : varName; - PathSegments.Segment segment = segments.segment(name); + final var name = matrixParamName != null ? matrixParamName : varName; + final PathSegments.Segment segment = segments.segment(name); if (segment != null) { // path or matrix parameter - boolean requiredParam = segment.isRequired(varName); - String asMethod = + final boolean requiredParam = segment.isRequired(varName); + final String asMethod = (typeHandler == null) ? null : (requiredParam) ? typeHandler.asMethod() : typeHandler.toMethod(); @@ -341,7 +355,7 @@ private boolean setValue(Append writer, PathSegments segments, String shortType) } } - String asMethod = (typeHandler == null) ? null : typeHandler.toMethod(); + final String asMethod = (typeHandler == null) ? null : typeHandler.toMethod(); if (asMethod != null) { writer.append(asMethod); } @@ -380,8 +394,8 @@ private boolean setValue(Append writer, PathSegments segments, String shortType) } private void writeForm(Append writer, String shortType, String varName, ParamType defaultParamType) { - TypeElement formBeanType = typeElement(rawType); - BeanParamReader form = new BeanParamReader(formBeanType, varName, shortType, defaultParamType); + final TypeElement formBeanType = typeElement(rawType); + final BeanParamReader form = new BeanParamReader(formBeanType, varName, shortType, defaultParamType); form.write(writer); } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java index dd7879347..eaf019493 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java @@ -126,18 +126,12 @@ private Javadoc buildJavadoc(ExecutableElement element) { } private boolean initValid() { - return findAnnotation(ValidPrism::getOptionalOn).isPresent() - || findAnnotation(JavaxValidPrism::getOptionalOn).isPresent() - || findAnnotation(JakartaValidPrism::getOptionalOn).isPresent() - || superMethodHasValid(); + return findAnnotation(ValidPrism::getOptionalOn).isPresent() || superMethodHasValid(); } private boolean superMethodHasValid() { return superMethods.stream() - .anyMatch( - e -> - findAnnotation(ValidPrism::getOptionalOn).isPresent() - || findAnnotation(JavaxValidPrism::getOptionalOn).isPresent()); + .anyMatch(e -> findAnnotation(ValidPrism::getOptionalOn).isPresent()); } @Override diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/PlatformAdapter.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/PlatformAdapter.java index 5f71734b0..4087af9bc 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/PlatformAdapter.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/PlatformAdapter.java @@ -48,6 +48,8 @@ public interface PlatformAdapter { void writeReadParameter( Append writer, ParamType paramType, String paramName, String paramDefault); + void writeAcceptLanguage(Append writer); + default void writeReadMapParameter(Append writer, ParamType paramType) { throw new UnsupportedOperationException("Unsupported Map Parameter"); } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ValidPrism.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ValidPrism.java new file mode 100644 index 000000000..ccbb4bd1d --- /dev/null +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ValidPrism.java @@ -0,0 +1,35 @@ +package io.avaje.http.generator.core; + +import java.util.Optional; + +import javax.lang.model.element.Element; + +import io.avaje.prism.GeneratePrism; + +@GeneratePrism( + value = javax.validation.Valid.class, + name = "JavaxValidPrism", + superInterfaces = ValidPrism.class) +@GeneratePrism( + value = jakarta.validation.Valid.class, + name = "JakartaValidPrism", + superInterfaces = ValidPrism.class) +@GeneratePrism( + value = io.avaje.http.api.Valid.class, + name = "HttpValidPrism", + superInterfaces = ValidPrism.class) +public interface ValidPrism { + + static Optional getOptionalOn(Element e) { + return Optional.empty() + .or(() -> HttpValidPrism.getOptionalOn(e)) + .or(() -> JakartaValidPrism.getOptionalOn(e)) + .or(() -> JavaxValidPrism.getOptionalOn(e)); + } + + static boolean isPresent(Element e) { + return JakartaValidPrism.isPresent(e) + || JavaxValidPrism.isPresent(e) + || HttpValidPrism.isPresent(e); + } +} diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/package-info.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/package-info.java index f5a9a1b0c..2fb3aa273 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/package-info.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/package-info.java @@ -35,9 +35,6 @@ @GeneratePrism(value = io.avaje.http.api.Client.class, publicAccess = true) @GeneratePrism(value = io.avaje.http.api.Client.Import.class, publicAccess = true) @GeneratePrism(value = io.avaje.http.api.RequestTimeout.class, publicAccess = true) -@GeneratePrism(value = javax.validation.Valid.class, name = "JavaxValidPrism") -@GeneratePrism(value = jakarta.validation.Valid.class, name = "JakartaValidPrism") -@GeneratePrism(value = io.avaje.http.api.Valid.class) package io.avaje.http.generator.core; import io.avaje.prism.GeneratePrism; diff --git a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/HelidonPlatformAdapter.java b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/HelidonPlatformAdapter.java index 62a569b11..6b0aef52e 100644 --- a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/HelidonPlatformAdapter.java +++ b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/HelidonPlatformAdapter.java @@ -3,6 +3,7 @@ import java.util.List; import io.avaje.http.generator.core.Append; +import io.avaje.http.generator.core.Constants; import io.avaje.http.generator.core.ControllerReader; import io.avaje.http.generator.core.ParamType; import io.avaje.http.generator.core.PlatformAdapter; @@ -168,4 +169,9 @@ public void writeReadCollectionParameter( throw new UnsupportedOperationException("Unsupported MultiValue Parameter"); } } + + @Override + public void writeAcceptLanguage(Append writer) { + writer.append("req.headers().first(\"%s\").orElse(null)", Constants.ACCEPT_LANGUAGE); + } } diff --git a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinAdapter.java b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinAdapter.java index a1653155e..f9abb089f 100644 --- a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinAdapter.java +++ b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinAdapter.java @@ -3,6 +3,7 @@ import java.util.List; import io.avaje.http.generator.core.Append; +import io.avaje.http.generator.core.Constants; import io.avaje.http.generator.core.ControllerReader; import io.avaje.http.generator.core.ParamType; import io.avaje.http.generator.core.PlatformAdapter; @@ -108,4 +109,9 @@ public void writeReadCollectionParameter( } writer.append("withDefault(ctx.queryParams(\"%s\"), java.util.List.of(\"%s\"))", paramName, String.join(",", paramDefault)); } + + @Override + public void writeAcceptLanguage(Append writer) { + writer.append("ctx.header(\"%s\")", Constants.ACCEPT_LANGUAGE); + } } diff --git a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/JexAdapter.java b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/JexAdapter.java index f417f306f..fc0daba4e 100644 --- a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/JexAdapter.java +++ b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/JexAdapter.java @@ -3,6 +3,7 @@ import java.util.List; import io.avaje.http.generator.core.Append; +import io.avaje.http.generator.core.Constants; import io.avaje.http.generator.core.ControllerReader; import io.avaje.http.generator.core.ParamType; import io.avaje.http.generator.core.PlatformAdapter; @@ -84,4 +85,9 @@ public void writeReadCollectionParameter( } writer.append("withDefault(ctx.queryParams(\"%s\"), java.util.List.of(\"%s\"))", paramName, String.join(",", paramDefault)); } + + @Override + public void writeAcceptLanguage(Append writer) { + writer.append("ctx.header(\"%s\")", Constants.ACCEPT_LANGUAGE); + } } diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java index 9d0b32794..cb61eebb8 100644 --- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java +++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java @@ -45,6 +45,7 @@ class ControllerWriter extends BaseControllerWriter { reader.addImportType("io.helidon.nima.webserver.http.ServerRequest"); reader.addImportType("io.helidon.nima.webserver.http.ServerResponse"); reader.addImportType("io.helidon.nima.webserver.http.HttpService"); + reader.addImportType("io.helidon.common.http.Http.Header"); } void write() { diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/NimaPlatformAdapter.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/NimaPlatformAdapter.java index 72ee72a59..82229d03a 100644 --- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/NimaPlatformAdapter.java +++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/NimaPlatformAdapter.java @@ -71,7 +71,7 @@ public void writeReadParameter(Append writer, ParamType paramType, String paramN writer.append("formParams.first(\"%s\").orElse(null)", paramName); break; case HEADER: - writer.append("req.headers().value(io.helidon.common.http.Http.Header.create(\"%s\")).orElse(null)", paramName); + writer.append("req.headers().value(Header.create(\"%s\")).orElse(null)", paramName); break; case COOKIE: writer.append("req.headers().cookies().first(\"%s\").orElse(null)", paramName); @@ -159,4 +159,9 @@ public void writeReadCollectionParameter( throw new UnsupportedOperationException("Unsupported MultiValue Parameter"); } } + + @Override + public void writeAcceptLanguage(Append writer) { + writer.append("req.headers().first(Header.create(\"%s\")).orElse(null)", Constants.ACCEPT_LANGUAGE); + } } diff --git a/http-hibernate-validator/pom.xml b/http-hibernate-validator/pom.xml index 07a2a4ce9..56893a269 100644 --- a/http-hibernate-validator/pom.xml +++ b/http-hibernate-validator/pom.xml @@ -36,14 +36,14 @@ io.avaje avaje-http-api - 1.30 + 1.45-SNAPSHOT provided io.avaje avaje-inject - 9.0 + 9.3 provided diff --git a/http-hibernate-validator/src/main/java/io/avaje/http/hibernate/validator/BeanValidator.java b/http-hibernate-validator/src/main/java/io/avaje/http/hibernate/validator/BeanValidator.java index a2dda202c..ed71bdd11 100644 --- a/http-hibernate-validator/src/main/java/io/avaje/http/hibernate/validator/BeanValidator.java +++ b/http-hibernate-validator/src/main/java/io/avaje/http/hibernate/validator/BeanValidator.java @@ -1,6 +1,5 @@ package io.avaje.http.hibernate.validator; - import java.util.LinkedHashMap; import java.util.Map; import java.util.Set; @@ -16,8 +15,11 @@ public class BeanValidator implements Validator { private static final ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); @Override - public void validate(Object bean) { - final Set> violations = factory.getValidator().validate(bean); + public void validate(Object bean, String acceptLanguage, Class... groups) + throws ValidationException { + + final Set> violations = + factory.getValidator().validate(bean, groups); if (!violations.isEmpty()) { throwExceptionWith(violations); } diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 10d0d18b4..564627fd8 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -53,7 +53,7 @@ io.avaje avaje-http-hibernate-validator - 2.8 + 3.2 diff --git a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/GetBeanForm.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/GetBeanForm.java index dd54b25e8..70818500d 100644 --- a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/GetBeanForm.java +++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/GetBeanForm.java @@ -3,15 +3,14 @@ import java.util.List; import java.util.Set; -import javax.validation.Valid; -import javax.validation.constraints.Email; -import javax.validation.constraints.NotNull; -import javax.validation.constraints.Size; - import io.avaje.http.api.Header; import io.avaje.http.api.Ignore; import io.avaje.http.api.QueryParam; import io.avaje.jsonb.Json; +import jakarta.validation.Valid; +import jakarta.validation.constraints.Email; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; @Json @Valid diff --git a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/HelloForm.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/HelloForm.java index 7f6aeab63..51dcfb085 100644 --- a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/HelloForm.java +++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/HelloForm.java @@ -2,15 +2,14 @@ import java.time.LocalDate; -import javax.validation.Valid; -import javax.validation.constraints.Email; -import javax.validation.constraints.Future; -import javax.validation.constraints.NotNull; -import javax.validation.constraints.Size; - import org.hibernate.validator.constraints.URL; import io.avaje.jsonb.Json; +import jakarta.validation.Valid; +import jakarta.validation.constraints.Email; +import jakarta.validation.constraints.Future; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; @Json @Valid diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 9bdccfbee..7800126c4 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -58,7 +58,7 @@ io.avaje avaje-http-hibernate-validator - 2.8 + 3.2 diff --git a/tests/test-javalin/src/main/java/org/example/myapp/web/GetBeanForm.java b/tests/test-javalin/src/main/java/org/example/myapp/web/GetBeanForm.java index f92072efb..d9337c43d 100644 --- a/tests/test-javalin/src/main/java/org/example/myapp/web/GetBeanForm.java +++ b/tests/test-javalin/src/main/java/org/example/myapp/web/GetBeanForm.java @@ -1,9 +1,9 @@ package org.example.myapp.web; -import javax.validation.Valid; -import javax.validation.constraints.Email; -import javax.validation.constraints.NotNull; -import javax.validation.constraints.Size; +import jakarta.validation.Valid; +import jakarta.validation.constraints.Email; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; @Valid public class GetBeanForm { diff --git a/tests/test-javalin/src/main/java/org/example/myapp/web/HelloController.java b/tests/test-javalin/src/main/java/org/example/myapp/web/HelloController.java index 9960fad0d..4ddd454ba 100644 --- a/tests/test-javalin/src/main/java/org/example/myapp/web/HelloController.java +++ b/tests/test-javalin/src/main/java/org/example/myapp/web/HelloController.java @@ -8,8 +8,6 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.Executors; -import javax.validation.Valid; - import org.example.myapp.service.MyService; import io.avaje.http.api.BeanParam; @@ -26,6 +24,7 @@ import io.javalin.http.Context; import io.swagger.v3.oas.annotations.Hidden; import jakarta.inject.Inject; +import jakarta.validation.Valid; /** * Hello resource manager. diff --git a/tests/test-javalin/src/main/java/org/example/myapp/web/HelloForm.java b/tests/test-javalin/src/main/java/org/example/myapp/web/HelloForm.java index e29d4141a..ea8750600 100644 --- a/tests/test-javalin/src/main/java/org/example/myapp/web/HelloForm.java +++ b/tests/test-javalin/src/main/java/org/example/myapp/web/HelloForm.java @@ -1,13 +1,14 @@ package org.example.myapp.web; +import java.time.LocalDate; + import org.hibernate.validator.constraints.URL; -import javax.validation.Valid; -import javax.validation.constraints.Email; -import javax.validation.constraints.Future; -import javax.validation.constraints.NotNull; -import javax.validation.constraints.Size; -import java.time.LocalDate; +import jakarta.validation.Valid; +import jakarta.validation.constraints.Email; +import jakarta.validation.constraints.Future; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; @Valid public class HelloForm { diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index bf61100a0..ae282ff71 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -57,7 +57,7 @@ io.avaje avaje-http-hibernate-validator - 2.8 + 3.2 diff --git a/tests/test-jex/src/main/java/org/example/web/HelloController.java b/tests/test-jex/src/main/java/org/example/web/HelloController.java index b9ac7cc07..a630fa209 100644 --- a/tests/test-jex/src/main/java/org/example/web/HelloController.java +++ b/tests/test-jex/src/main/java/org/example/web/HelloController.java @@ -1,10 +1,14 @@ package org.example.web; -import io.avaje.http.api.*; +import io.avaje.http.api.Controller; +import io.avaje.http.api.Default; +import io.avaje.http.api.Get; +import io.avaje.http.api.Path; +import io.avaje.http.api.Produces; +import io.avaje.http.api.Put; +import io.avaje.http.api.Valid; import io.avaje.jex.Context; -import javax.validation.Valid; - // @Roles(AppRoles.BASIC_USER) @Controller @Path("/") diff --git a/tests/test-jex/src/main/java/org/example/web/HelloDto.java b/tests/test-jex/src/main/java/org/example/web/HelloDto.java index 884fcdb5a..721795d78 100644 --- a/tests/test-jex/src/main/java/org/example/web/HelloDto.java +++ b/tests/test-jex/src/main/java/org/example/web/HelloDto.java @@ -1,7 +1,7 @@ package org.example.web; -import javax.validation.Valid; -import javax.validation.constraints.NotNull; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; @Valid public class HelloDto { From 73d28524679c43b5b84feeb38c729110ae64b0d5 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Thu, 13 Jul 2023 13:33:37 -0400 Subject: [PATCH 0789/1323] Update Validator.java --- http-api/src/main/java/io/avaje/http/api/Validator.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/http-api/src/main/java/io/avaje/http/api/Validator.java b/http-api/src/main/java/io/avaje/http/api/Validator.java index 8782e2d21..374500e55 100644 --- a/http-api/src/main/java/io/avaje/http/api/Validator.java +++ b/http-api/src/main/java/io/avaje/http/api/Validator.java @@ -18,11 +18,11 @@ public interface Validator { */ void validate(Object bean, String acceptLanguage, Class... groups) throws ValidationException; - default Locale resolveLocale(String acceptLanguage, Collection locales) { + default Locale resolveLocale(String acceptLanguage, Collection acceptLocales) { if (acceptLanguage == null) { return null; } final List list = LanguageRange.parse(acceptLanguage); - return Locale.lookup(list, locales); + return Locale.lookup(list, acceptLocales); } } From 53df00f0533b24f2a8c6917780a41c8ff945b972 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Fri, 14 Jul 2023 09:23:30 +1200 Subject: [PATCH 0790/1323] Bump hibernate-validator to version 3.3 with new API --- http-client/pom.xml | 2 +- http-hibernate-validator/pom.xml | 2 +- .../io/avaje/http/hibernate/validator/BeanValidator.java | 7 ++----- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- 7 files changed, 8 insertions(+), 11 deletions(-) diff --git a/http-client/pom.xml b/http-client/pom.xml index 24959e50e..506f348bb 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -80,7 +80,7 @@ io.avaje avaje-http-hibernate-validator - 3.2 + 3.3 test diff --git a/http-hibernate-validator/pom.xml b/http-hibernate-validator/pom.xml index 56893a269..4a01e79f7 100644 --- a/http-hibernate-validator/pom.xml +++ b/http-hibernate-validator/pom.xml @@ -5,7 +5,7 @@ io.avaje avaje-http-hibernate-validator - 3.2 + 3.3 org.avaje diff --git a/http-hibernate-validator/src/main/java/io/avaje/http/hibernate/validator/BeanValidator.java b/http-hibernate-validator/src/main/java/io/avaje/http/hibernate/validator/BeanValidator.java index ed71bdd11..5eca15e54 100644 --- a/http-hibernate-validator/src/main/java/io/avaje/http/hibernate/validator/BeanValidator.java +++ b/http-hibernate-validator/src/main/java/io/avaje/http/hibernate/validator/BeanValidator.java @@ -15,11 +15,8 @@ public class BeanValidator implements Validator { private static final ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); @Override - public void validate(Object bean, String acceptLanguage, Class... groups) - throws ValidationException { - - final Set> violations = - factory.getValidator().validate(bean, groups); + public void validate(Object bean, String acceptLanguage, Class... groups) throws ValidationException { + final Set> violations = factory.getValidator().validate(bean, groups); if (!violations.isEmpty()) { throwExceptionWith(violations); } diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 564627fd8..ab6a78e26 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -53,7 +53,7 @@ io.avaje avaje-http-hibernate-validator - 3.2 + 3.3 diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 7800126c4..0e83c0ad7 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -58,7 +58,7 @@ io.avaje avaje-http-hibernate-validator - 3.2 + 3.3 diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index ae282ff71..b24b12a3e 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -57,7 +57,7 @@ io.avaje avaje-http-hibernate-validator - 3.2 + 3.3 diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 34b2ed3ff..847b85dde 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -36,7 +36,7 @@ io.avaje avaje-http-hibernate-validator - 3.2 + 3.3 io.helidon.nima.webserver From 29f32840c6fa01e03dca8da18df05e4ba2e6231c Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Fri, 14 Jul 2023 09:29:25 +1200 Subject: [PATCH 0791/1323] Bump to next snapshot --- http-api/pom.xml | 2 +- http-client-gson-adapter/pom.xml | 4 ++-- http-client/pom.xml | 2 +- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 2 +- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-generator-nima/pom.xml | 2 +- http-inject-plugin/pom.xml | 2 +- pom.xml | 2 +- tests/pom.xml | 2 +- tests/test-client-generation/pom.xml | 2 +- tests/test-client/pom.xml | 2 +- tests/test-helidon/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- 20 files changed, 21 insertions(+), 21 deletions(-) diff --git a/http-api/pom.xml b/http-api/pom.xml index 518806f21..2e2315412 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.45-SNAPSHOT + 1.46-SNAPSHOT .. diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index d42761354..0998545ec 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.45-SNAPSHOT + 1.46-SNAPSHOT avaje-http-client-gson @@ -20,7 +20,7 @@ io.avaje avaje-http-client - 1.45-SNAPSHOT + 1.46-SNAPSHOT provided diff --git a/http-client/pom.xml b/http-client/pom.xml index 506f348bb..59220a16b 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.45-SNAPSHOT + 1.46-SNAPSHOT avaje-http-client diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index 615f3382e..e19a210ba 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.45-SNAPSHOT + 1.46-SNAPSHOT avaje-http-client-generator diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 4baf5b0a5..66ec057b6 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.45-SNAPSHOT + 1.46-SNAPSHOT avaje-http-generator-core diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index cbdca9ca3..b6a6cb1e4 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.45-SNAPSHOT + 1.46-SNAPSHOT avaje-http-helidon-generator diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index 4ddefab97..54c57e004 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.45-SNAPSHOT + 1.46-SNAPSHOT avaje-http-javalin-generator diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index 81fe263c1..e933b1f0f 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.45-SNAPSHOT + 1.46-SNAPSHOT avaje-http-jex-generator diff --git a/http-generator-nima/pom.xml b/http-generator-nima/pom.xml index 573e59a5f..d1187dc43 100644 --- a/http-generator-nima/pom.xml +++ b/http-generator-nima/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 1.45-SNAPSHOT + 1.46-SNAPSHOT avaje-http-nima-generator diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index 0fd01e2ff..302f69b46 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.45-SNAPSHOT + 1.46-SNAPSHOT .. diff --git a/pom.xml b/pom.xml index 1017b368a..a9db990a8 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-parent - 1.45-SNAPSHOT + 1.46-SNAPSHOT pom diff --git a/tests/pom.xml b/tests/pom.xml index 70a7e5109..dbff168fa 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 1.45-SNAPSHOT + 1.46-SNAPSHOT tests diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index bde700ba3..a9247fe3e 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.45-SNAPSHOT + 1.46-SNAPSHOT test-client-generation diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index e2ac460ac..cfe21cdae 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 1.45-SNAPSHOT + 1.46-SNAPSHOT test-client diff --git a/tests/test-helidon/pom.xml b/tests/test-helidon/pom.xml index 988129b05..3815380ba 100644 --- a/tests/test-helidon/pom.xml +++ b/tests/test-helidon/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.45-SNAPSHOT + 1.46-SNAPSHOT test-helidon diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index ab6a78e26..893a53ef3 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 1.45-SNAPSHOT + 1.46-SNAPSHOT test-javalin-jsonb diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 0e83c0ad7..1fec0a20d 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.45-SNAPSHOT + 1.46-SNAPSHOT test-javalin diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index b24b12a3e..2c3a47d34 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.45-SNAPSHOT + 1.46-SNAPSHOT test-jex diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 847b85dde..dfa4f9fbf 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.45-SNAPSHOT + 1.46-SNAPSHOT test-nima-jsonb diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index fb1e3fb5b..ad0b0169d 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 1.45-SNAPSHOT + 1.46-SNAPSHOT test-nima From a5fb3f35b08c41ec0b8c2a416dde3fc7ac1722df Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Tue, 18 Jul 2023 22:15:54 -0400 Subject: [PATCH 0792/1323] nima M1 --- tests/pom.xml | 1 + tests/test-nima-jsonb/pom.xml | 4 ++-- tests/test-nima-jsonb/src/main/java/org/example/Main.java | 1 + tests/test-nima/pom.xml | 4 ++-- tests/test-nima/src/main/java/org/example/Main.java | 1 + 5 files changed, 7 insertions(+), 4 deletions(-) diff --git a/tests/pom.xml b/tests/pom.xml index dbff168fa..8f7132109 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -17,6 +17,7 @@ 2.14.1 2.5 9.0 + 4.0.0-M1 diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index dfa4f9fbf..36fb11ee2 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -41,12 +41,12 @@ io.helidon.nima.webserver helidon-nima-webserver - 4.0.0-ALPHA6 + ${nima.version} io.helidon.nima.http.media helidon-nima-http-media-jsonb - 4.0.0-ALPHA6 + ${nima.version} io.avaje diff --git a/tests/test-nima-jsonb/src/main/java/org/example/Main.java b/tests/test-nima-jsonb/src/main/java/org/example/Main.java index 07d52bcdf..4a5455322 100644 --- a/tests/test-nima-jsonb/src/main/java/org/example/Main.java +++ b/tests/test-nima-jsonb/src/main/java/org/example/Main.java @@ -24,6 +24,7 @@ public static void main(String[] args) { .addRouting(httpRouting) // .routing(Main::routing) .port(8081) + .build() .start(); System.out.println("started"); diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index ad0b0169d..72196d5af 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -32,12 +32,12 @@ io.helidon.nima.webserver helidon-nima-webserver - 4.0.0-ALPHA6 + ${nima.version} io.helidon.nima.http.media helidon-nima-http-media-jsonb - 4.0.0-ALPHA6 + ${nima.version} diff --git a/tests/test-nima/src/main/java/org/example/Main.java b/tests/test-nima/src/main/java/org/example/Main.java index 4ec2d7148..31f39dd9b 100644 --- a/tests/test-nima/src/main/java/org/example/Main.java +++ b/tests/test-nima/src/main/java/org/example/Main.java @@ -24,6 +24,7 @@ public static void main(String[] args) { .addRouting(httpRouting) //.routing(Main::routing) .port(8081) + .build() .start(); System.out.println("started"); From 50cc4047baa85192874e13c2b9c1bfb9ac43fd78 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Thu, 20 Jul 2023 08:53:02 +1200 Subject: [PATCH 0793/1323] Nima - When returning JSON as String assume the string is raw json --- .../helidon/nima/ControllerMethodWriter.java | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java index 32b052889..8158ad0b6 100644 --- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java +++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java @@ -113,8 +113,12 @@ void writeHandler(boolean requestScoped) { final var uType = UType.parse(method.returnType()); writer.append(" result.transferTo(res.outputStream());", uType.shortName()).eol(); } else if (producesJson()) { - final var uType = UType.parse(method.returnType()); - writer.append(" %sJsonType.toJson(result, JsonOutput.of(res));", uType.shortName()).eol(); + if (returnTypeString()) { + writer.append(" res.send(result); // send raw JSON").eol(); + } else { + final var uType = UType.parse(method.returnType()); + writer.append(" %sJsonType.toJson(result, JsonOutput.of(res));", uType.shortName()).eol(); + } } else { writer.append(" res.send(result);").eol(); } @@ -159,6 +163,10 @@ private boolean producesJson() { && (method.produces() == null || method.produces().toLowerCase().contains("json")); } + private boolean returnTypeString() { + return "java.lang.String".equals(method.returnType().toString()); + } + private boolean missingServerResponse(List params) { return method.isVoid() && params.stream().noneMatch(p -> "ServerResponse".equals(p.shortType())); } From 2932882d0ef280a78d4b8459bc5c4141e471ae03 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Fri, 21 Jul 2023 13:05:50 +1200 Subject: [PATCH 0794/1323] Nima - Fix for String request body when Jsonb present --- .../http/generator/helidon/nima/ControllerMethodWriter.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java index 8158ad0b6..997cab3b1 100644 --- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java +++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java @@ -48,6 +48,8 @@ void writeHandler(boolean requestScoped) { if (bodyType != null) { if ("InputStream".equals(bodyType)) { writer.append(" var %s = req.content().inputStream();", method.bodyName()).eol(); + } else if ("String".equals(bodyType)) { + writer.append(" var %s = req.content().as(String.class);", method.bodyName()).eol(); } else if (useJsonB) { final String fieldName = fieldNameOfBody(); writer.append(" var %s = %sJsonType.fromJson(req.content().inputStream());", method.bodyName(), fieldName).eol(); From 526cd58311afc22749189becf8c06ebadb786379 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Fri, 21 Jul 2023 13:06:08 +1200 Subject: [PATCH 0795/1323] Nima - Fix for InputStream use with Jsonb present --- .../generator/helidon/nima/ControllerWriter.java | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java index cb61eebb8..cb3b06ae7 100644 --- a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java +++ b/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java @@ -1,6 +1,7 @@ package io.avaje.http.generator.helidon.nima; import static io.avaje.http.generator.core.ProcessingContext.diAnnotation; +import static io.avaje.http.generator.core.ProcessingContext.isAssignable2Interface; import java.io.IOException; import java.util.List; @@ -106,8 +107,10 @@ private void writeClassStart() { } for (final UType type : jsonTypes.values()) { - final var typeString = PrimitiveUtil.wrap(type.shortType()).replace(",", ", "); - writer.append(" private final JsonType<%s> %sJsonType;", typeString, type.shortName()).eol(); + if (!isInputStream(type.full())) { + final var typeString = PrimitiveUtil.wrap(type.shortType()).replace(",", ", "); + writer.append(" private final JsonType<%s> %sJsonType;", typeString, type.shortName()).eol(); + } } writer.eol(); @@ -133,9 +136,15 @@ private void writeClassStart() { if (useJsonB) { for (final UType type : jsonTypes.values()) { - JsonBUtil.writeJsonbType(type, writer); + if (!isInputStream(type.full())) { + JsonBUtil.writeJsonbType(type, writer); + } } } writer.append(" }").eol().eol(); } + + private boolean isInputStream(String type) { + return isAssignable2Interface(type.toString(), "java.io.InputStream"); + } } From 2cbcb2ab0753082aa1f75cc3af6b87d8ef3473b9 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Fri, 21 Jul 2023 13:06:38 +1200 Subject: [PATCH 0796/1323] Nima - Tests for when returning JSON as String assume the string is raw json --- tests/test-nima-jsonb/pom.xml | 21 ++++++-- .../main/java/org/example/TestController.java | 19 +++---- .../java/org/example/TestControllerTest.java | 45 ++++++++++++++++ .../src/test/java/org/example/TestPair.java | 53 +++++++++++++++++++ 4 files changed, 124 insertions(+), 14 deletions(-) create mode 100644 tests/test-nima-jsonb/src/test/java/org/example/TestControllerTest.java create mode 100644 tests/test-nima-jsonb/src/test/java/org/example/TestPair.java diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 36fb11ee2..d7379ae40 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -14,6 +14,7 @@ 20 20 UTF-8 + false @@ -31,7 +32,7 @@ io.avaje avaje-jsonb - 1.4 + 1.6-RC6 io.avaje @@ -48,6 +49,11 @@ helidon-nima-http-media-jsonb ${nima.version} + + io.avaje + avaje-http-client + ${project.version} + io.avaje avaje-http-nima-generator @@ -69,6 +75,7 @@ maven-compiler-plugin 3.10.1 + true 20 @@ -84,17 +91,25 @@ io.avaje avaje-jsonb-generator - 1.4 + 1.6-RC6 19 19 + + org.apache.maven.plugins + maven-surefire-plugin + 3.0.0 + + --enable-preview + + io.repaint.maven tiles-maven-plugin - 2.22 + 2.34 true diff --git a/tests/test-nima-jsonb/src/main/java/org/example/TestController.java b/tests/test-nima-jsonb/src/main/java/org/example/TestController.java index 3040911d1..f1be700c4 100644 --- a/tests/test-nima-jsonb/src/main/java/org/example/TestController.java +++ b/tests/test-nima-jsonb/src/main/java/org/example/TestController.java @@ -4,21 +4,18 @@ import java.util.List; import java.util.Set; -import io.avaje.http.api.BodyString; -import io.avaje.http.api.Controller; -import io.avaje.http.api.Default; -import io.avaje.http.api.Form; -import io.avaje.http.api.FormParam; -import io.avaje.http.api.Get; -import io.avaje.http.api.InstrumentServerContext; -import io.avaje.http.api.Path; -import io.avaje.http.api.Post; -import io.avaje.http.api.QueryParam; +import io.avaje.http.api.*; -@Path("test/") +@Path("test") @Controller public class TestController { + @Produces("text/plain") + @Get + String hello() { + return "hi"; + } + @Get("/paramMulti") String paramMulti(Set strings) { return strings.toString(); diff --git a/tests/test-nima-jsonb/src/test/java/org/example/TestControllerTest.java b/tests/test-nima-jsonb/src/test/java/org/example/TestControllerTest.java new file mode 100644 index 000000000..b44fa4c7c --- /dev/null +++ b/tests/test-nima-jsonb/src/test/java/org/example/TestControllerTest.java @@ -0,0 +1,45 @@ +package org.example; + +import io.avaje.http.client.HttpClient; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.Test; + +import java.net.http.HttpResponse; + +import static org.assertj.core.api.Assertions.as; +import static org.assertj.core.api.Assertions.assertThat; + +class TestControllerTest { + + private static TestPair pair = new TestPair(); + private static HttpClient client = pair.client(); + + @AfterAll + static void end() { + pair.stop(); + } + + @Test + void hello() { + HttpResponse res = client.request() + .GET() + .asString(); + + assertThat(res.statusCode()).isEqualTo(200); + assertThat(res.body()).isEqualTo("Hello world - index"); + } + + @Test + void strBody() { + HttpResponse res = client.request() + .path("test/strBody") + .body("{\"key\":42}") + .POST() + .asString(); + + assertThat(res.statusCode()).isEqualTo(200); + assertThat(res.body()).isEqualTo("{\"key\":42}"); + assertThat(res.headers().firstValue("Content-Type")).isPresent().get().isEqualTo("application/json"); + assertThat(res.headers().firstValue("Content-Length")).isPresent(); + } +} diff --git a/tests/test-nima-jsonb/src/test/java/org/example/TestPair.java b/tests/test-nima-jsonb/src/test/java/org/example/TestPair.java new file mode 100644 index 000000000..93021abb0 --- /dev/null +++ b/tests/test-nima-jsonb/src/test/java/org/example/TestPair.java @@ -0,0 +1,53 @@ +package org.example; + +import io.avaje.http.api.context.ThreadLocalRequestContextResolver; +import io.avaje.http.client.HttpClient; +import io.avaje.http.hibernate.validator.BeanValidator; +import io.avaje.jsonb.Jsonb; +import io.helidon.nima.webserver.WebServer; +import io.helidon.nima.webserver.http.HttpRouting; + +public class TestPair { + + WebServer webServer; + HttpClient httpClient; + int port; + + public TestPair() { + this.webServer = WebServer.builder() + .routing(routing().build()) + .build(); + + webServer.start(); + this.port = webServer.port(); + + this.httpClient = HttpClient.builder() + .baseUrl("http://localhost:" + port) + .build(); + } + + public HttpClient client() { + return httpClient; + } + + void stop() { + webServer.stop(); + } + + private static HttpRouting.Builder routing() { + HttpRouting.Builder routing = HttpRouting.builder(); + + var beanValidator = new BeanValidator(); + Jsonb jsonb = Jsonb.builder().build(); + + var hc = new HelloController(); + var hello = new HelloController$Route(hc, beanValidator, jsonb); + hello.routing(routing); + + var cr = new ThreadLocalRequestContextResolver(); + var tc = new TestController(); + TestController$Route tcr = new TestController$Route(tc, jsonb, cr); + tcr.routing(routing); + return routing; + } +} From 8e51a285401a99b8649e516f7a66ed84433a6476 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Fri, 21 Jul 2023 13:17:03 +1200 Subject: [PATCH 0797/1323] Version 1.46 --- http-api/pom.xml | 2 +- http-client-gson-adapter/pom.xml | 4 ++-- http-client/pom.xml | 2 +- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 2 +- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-generator-nima/pom.xml | 2 +- http-inject-plugin/pom.xml | 2 +- pom.xml | 2 +- tests/pom.xml | 2 +- tests/test-client-generation/pom.xml | 2 +- tests/test-client/pom.xml | 2 +- tests/test-helidon/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- 20 files changed, 21 insertions(+), 21 deletions(-) diff --git a/http-api/pom.xml b/http-api/pom.xml index 2e2315412..2885e0f2c 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.46-SNAPSHOT + 1.46 .. diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index 0998545ec..577ccdacb 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.46-SNAPSHOT + 1.46 avaje-http-client-gson @@ -20,7 +20,7 @@ io.avaje avaje-http-client - 1.46-SNAPSHOT + 1.46 provided diff --git a/http-client/pom.xml b/http-client/pom.xml index 59220a16b..4a3509357 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.46-SNAPSHOT + 1.46 avaje-http-client diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index e19a210ba..78ffc99f1 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.46-SNAPSHOT + 1.46 avaje-http-client-generator diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 66ec057b6..747b27556 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.46-SNAPSHOT + 1.46 avaje-http-generator-core diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index b6a6cb1e4..209101123 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.46-SNAPSHOT + 1.46 avaje-http-helidon-generator diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index 54c57e004..e5b270154 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.46-SNAPSHOT + 1.46 avaje-http-javalin-generator diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index e933b1f0f..26c608a48 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.46-SNAPSHOT + 1.46 avaje-http-jex-generator diff --git a/http-generator-nima/pom.xml b/http-generator-nima/pom.xml index d1187dc43..b56ccf155 100644 --- a/http-generator-nima/pom.xml +++ b/http-generator-nima/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 1.46-SNAPSHOT + 1.46 avaje-http-nima-generator diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index 302f69b46..7554bb656 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.46-SNAPSHOT + 1.46 .. diff --git a/pom.xml b/pom.xml index a9db990a8..422cd3ba6 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-parent - 1.46-SNAPSHOT + 1.46 pom diff --git a/tests/pom.xml b/tests/pom.xml index 8f7132109..fe9ec746c 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 1.46-SNAPSHOT + 1.46 tests diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index a9247fe3e..e316e2dc5 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.46-SNAPSHOT + 1.46 test-client-generation diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index cfe21cdae..9ffc93cf7 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 1.46-SNAPSHOT + 1.46 test-client diff --git a/tests/test-helidon/pom.xml b/tests/test-helidon/pom.xml index 3815380ba..c35370b20 100644 --- a/tests/test-helidon/pom.xml +++ b/tests/test-helidon/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.46-SNAPSHOT + 1.46 test-helidon diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 893a53ef3..fcb529680 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 1.46-SNAPSHOT + 1.46 test-javalin-jsonb diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 1fec0a20d..c0debd11b 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.46-SNAPSHOT + 1.46 test-javalin diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 2c3a47d34..9f24fb365 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.46-SNAPSHOT + 1.46 test-jex diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index d7379ae40..90993ea4d 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.46-SNAPSHOT + 1.46 test-nima-jsonb diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index 72196d5af..5640b8cc7 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 1.46-SNAPSHOT + 1.46 test-nima From 20db38502d6ccb246ac467fa2c4b92862c8b97ee Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Fri, 21 Jul 2023 13:17:46 +1200 Subject: [PATCH 0798/1323] Bump to 2.0-SNAPSHOT --- http-api/pom.xml | 2 +- http-client-gson-adapter/pom.xml | 4 ++-- http-client/pom.xml | 2 +- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 2 +- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-generator-nima/pom.xml | 2 +- http-inject-plugin/pom.xml | 2 +- pom.xml | 2 +- tests/pom.xml | 2 +- tests/test-client-generation/pom.xml | 2 +- tests/test-client/pom.xml | 2 +- tests/test-helidon/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- 20 files changed, 21 insertions(+), 21 deletions(-) diff --git a/http-api/pom.xml b/http-api/pom.xml index 2885e0f2c..f28e5d9a9 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.46 + 2.0-SNAPSHOT .. diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index 577ccdacb..ec3be33f3 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.46 + 2.0-SNAPSHOT avaje-http-client-gson @@ -20,7 +20,7 @@ io.avaje avaje-http-client - 1.46 + 2.0-SNAPSHOT provided diff --git a/http-client/pom.xml b/http-client/pom.xml index 4a3509357..416c95f67 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.46 + 2.0-SNAPSHOT avaje-http-client diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index 78ffc99f1..e27a75daf 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.46 + 2.0-SNAPSHOT avaje-http-client-generator diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 747b27556..75128302f 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.46 + 2.0-SNAPSHOT avaje-http-generator-core diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index 209101123..4764a0583 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.46 + 2.0-SNAPSHOT avaje-http-helidon-generator diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index e5b270154..73d842f51 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.46 + 2.0-SNAPSHOT avaje-http-javalin-generator diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index 26c608a48..5686ea66c 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.46 + 2.0-SNAPSHOT avaje-http-jex-generator diff --git a/http-generator-nima/pom.xml b/http-generator-nima/pom.xml index b56ccf155..3b9d670a7 100644 --- a/http-generator-nima/pom.xml +++ b/http-generator-nima/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 1.46 + 2.0-SNAPSHOT avaje-http-nima-generator diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index 7554bb656..29c0cd168 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 1.46 + 2.0-SNAPSHOT .. diff --git a/pom.xml b/pom.xml index 422cd3ba6..b3518152a 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-parent - 1.46 + 2.0-SNAPSHOT pom diff --git a/tests/pom.xml b/tests/pom.xml index fe9ec746c..f8075847f 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 1.46 + 2.0-SNAPSHOT tests diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index e316e2dc5..e491690b1 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.46 + 2.0-SNAPSHOT test-client-generation diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index 9ffc93cf7..25e359d7a 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 1.46 + 2.0-SNAPSHOT test-client diff --git a/tests/test-helidon/pom.xml b/tests/test-helidon/pom.xml index c35370b20..950528016 100644 --- a/tests/test-helidon/pom.xml +++ b/tests/test-helidon/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.46 + 2.0-SNAPSHOT test-helidon diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index fcb529680..065935419 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 1.46 + 2.0-SNAPSHOT test-javalin-jsonb diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index c0debd11b..0ea40571b 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.46 + 2.0-SNAPSHOT test-javalin diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 9f24fb365..c4804dc28 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.46 + 2.0-SNAPSHOT test-jex diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 90993ea4d..2ec0cec0e 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 1.46 + 2.0-SNAPSHOT test-nima-jsonb diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index 5640b8cc7..a3e1cccd1 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 1.46 + 2.0-SNAPSHOT test-nima From 9b61ba0127c8f4f9ed71c781ab10bfd719c728c9 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Thu, 20 Jul 2023 21:18:33 -0400 Subject: [PATCH 0799/1323] [Http Api] Remove deprecated instrumentRequestContext() (#228) * [HttpClient] Remove deprecated HttpClientContext, migrate to HttpClient * remove all deprecated stuff * Update DHttpApi.java * fix tests * fix more tests * last test? * Update Simple$HttpClient.java * Update SimpleTest.java * Update SimpleTest.java * Update module-info.java * Update DHttpApi.java --------- Co-authored-by: robin.bygrave --- .../java/io/avaje/http/api/Controller.java | 8 ---- .../main/java/io/avaje/http/api/Delete.java | 8 +--- .../src/main/java/io/avaje/http/api/Get.java | 7 --- .../main/java/io/avaje/http/api/Patch.java | 7 --- .../src/main/java/io/avaje/http/api/Post.java | 7 --- .../src/main/java/io/avaje/http/api/Put.java | 8 +--- .../java/io/avaje/http/client/DHttpApi.java | 21 +++------ .../avaje/http/client/DHttpClientContext.java | 8 +--- .../io/avaje/http/client/HttpApiProvider.java | 7 --- http-client/src/main/java/module-info.java | 1 - .../io/avaje/http/client/DHttpApiTest.java | 4 +- .../org/example/github/SimpleProvider.java | 18 -------- .../github/httpclient/Simple$HttpClient.java | 14 ------ .../http/generator/core/ControllerReader.java | 7 +-- .../src/test/java/org/example/SimpleTest.java | 16 +------ .../java/example/github/SimpleHttpClient.java | 43 ------------------- .../github/httpclient/Simple$HttpClient.java | 31 +++++++++++++ .../src/main/java/module-info.java | 4 -- .../java/org/example/ReqScopedController.java | 4 +- .../myapp/web/test/TestController2.java | 20 +++------ .../org/example/myapp/web/BarInterface.java | 8 ++-- .../java/org/example/web/TestController.java | 11 ++--- 22 files changed, 61 insertions(+), 201 deletions(-) delete mode 100644 http-client/src/test/java/org/example/github/SimpleProvider.java delete mode 100644 tests/test-client/src/main/java/example/github/SimpleHttpClient.java create mode 100644 tests/test-client/src/main/java/example/github/httpclient/Simple$HttpClient.java diff --git a/http-api/src/main/java/io/avaje/http/api/Controller.java b/http-api/src/main/java/io/avaje/http/api/Controller.java index 14e112205..e920e7352 100644 --- a/http-api/src/main/java/io/avaje/http/api/Controller.java +++ b/http-api/src/main/java/io/avaje/http/api/Controller.java @@ -23,12 +23,4 @@ /** Specify the path mapping request to the controller. */ String value() default ""; - - /** - * Specify if the http request context should be instrumented via RequestContextResolver - * - * @deprecated use InstrumentServerContext annotation instead - */ - @Deprecated - boolean instrumentRequestContext() default false; } diff --git a/http-api/src/main/java/io/avaje/http/api/Delete.java b/http-api/src/main/java/io/avaje/http/api/Delete.java index 3c06a7564..307943237 100644 --- a/http-api/src/main/java/io/avaje/http/api/Delete.java +++ b/http-api/src/main/java/io/avaje/http/api/Delete.java @@ -25,11 +25,5 @@ /** Specify the path. */ String value() default ""; - /** - * Specify if the http request context should be instrumented via RequestContextResolver - * - * @deprecated use InstrumentServerContext annotation instead - */ - @Deprecated - boolean instrumentRequestContext() default false; + } diff --git a/http-api/src/main/java/io/avaje/http/api/Get.java b/http-api/src/main/java/io/avaje/http/api/Get.java index c51769d98..cef216dbb 100644 --- a/http-api/src/main/java/io/avaje/http/api/Get.java +++ b/http-api/src/main/java/io/avaje/http/api/Get.java @@ -53,11 +53,4 @@ /** Specify the path. */ String value() default ""; - /** - * Specify if the http request context should be instrumented via RequestContextResolver - * - * @deprecated use InstrumentServerContext annotation instead - */ - @Deprecated - boolean instrumentRequestContext() default false; } diff --git a/http-api/src/main/java/io/avaje/http/api/Patch.java b/http-api/src/main/java/io/avaje/http/api/Patch.java index 3b9491ef7..5b96cdaca 100644 --- a/http-api/src/main/java/io/avaje/http/api/Patch.java +++ b/http-api/src/main/java/io/avaje/http/api/Patch.java @@ -14,11 +14,4 @@ /** Specify the path. */ String value() default ""; - /** - * Specify if the http request context should be instrumented via RequestContextResolver - * - * @deprecated use InstrumentServerContext annotation instead - */ - @Deprecated - boolean instrumentRequestContext() default false; } diff --git a/http-api/src/main/java/io/avaje/http/api/Post.java b/http-api/src/main/java/io/avaje/http/api/Post.java index 244854c33..7f94c8102 100644 --- a/http-api/src/main/java/io/avaje/http/api/Post.java +++ b/http-api/src/main/java/io/avaje/http/api/Post.java @@ -24,11 +24,4 @@ /** Specify the path. */ String value() default ""; - /** - * Specify if the http request context should be instrumented via RequestContextResolver - * - * @deprecated use InstrumentServerContext annotation instead - */ - @Deprecated - boolean instrumentRequestContext() default false; } diff --git a/http-api/src/main/java/io/avaje/http/api/Put.java b/http-api/src/main/java/io/avaje/http/api/Put.java index 65ab54fd4..909e73607 100644 --- a/http-api/src/main/java/io/avaje/http/api/Put.java +++ b/http-api/src/main/java/io/avaje/http/api/Put.java @@ -16,11 +16,5 @@ /** Specify the path. */ String value() default ""; - /** - * Specify if the http request context should be instrumented via RequestContextResolver - * - * @deprecated use InstrumentServerContext annotation instead - */ - @Deprecated - boolean instrumentRequestContext() default false; + } diff --git a/http-client/src/main/java/io/avaje/http/client/DHttpApi.java b/http-client/src/main/java/io/avaje/http/client/DHttpApi.java index 9f4ceec1b..22f147f75 100644 --- a/http-client/src/main/java/io/avaje/http/client/DHttpApi.java +++ b/http-client/src/main/java/io/avaje/http/client/DHttpApi.java @@ -9,8 +9,8 @@ import static java.lang.System.Logger.Level.*; -/** - * Service loads the HttpApiProvider for HttpApi. +/** + * Service loads the HttpApiProvider for HttpApi. */ final class DHttpApi { @@ -24,19 +24,15 @@ final class DHttpApi { init(); } - @SuppressWarnings("rawtypes") void init() { - for (final HttpApiProvider apiProvider : ServiceLoader.load(HttpApiProvider.class)) { - addProvider(apiProvider); - } for (final GeneratedComponent apiProvider : ServiceLoader.load(GeneratedComponent.class)) { apiProvider.register(providerMap); } log.log(DEBUG, "providers for {0}", providerMap.keySet()); } - void addProvider(HttpApiProvider apiProvider) { - providerMap.put(apiProvider.type(), apiProvider); + void addProvider(Class type, HttpApiProvider apiProvider) { + providerMap.put(type, apiProvider); } @SuppressWarnings("unchecked") @@ -44,7 +40,6 @@ private HttpApiProvider lookup(Class type) { return (HttpApiProvider) providerMap.get(type); } - @SuppressWarnings("unchecked") T provideFor(Class type, HttpClient httpClient) { final HttpApiProvider apiProvider = lookup(type); if (apiProvider == null) { @@ -53,16 +48,12 @@ T provideFor(Class type, HttpClient httpClient) { return apiProvider.provide(httpClient); } - /** - * Return the client implementation via service loading. - */ + /** Return the client implementation via service loading. */ static T provide(Class type, HttpClient httpClient) { return INSTANCE.provideFor(type, httpClient); } - /** - * Return the HttpApiProvider for the client interface type or null if not registered. - */ + /** Return the HttpApiProvider for the client interface type or null if not registered. */ static HttpApiProvider get(Class type) { return INSTANCE.lookup(type); } diff --git a/http-client/src/main/java/io/avaje/http/client/DHttpClientContext.java b/http-client/src/main/java/io/avaje/http/client/DHttpClientContext.java index 936de98bc..5f0b3f75e 100644 --- a/http-client/src/main/java/io/avaje/http/client/DHttpClientContext.java +++ b/http-client/src/main/java/io/avaje/http/client/DHttpClientContext.java @@ -62,13 +62,7 @@ public T create(Class clientInterface) { if (apiProvider != null) { return apiProvider.provide(this); } - try { - final Class implementationClass = implementationClass(clientInterface); - final Constructor constructor = implementationClass.getConstructor(HttpClient.class); - return (T) constructor.newInstance(this); - } catch (final Exception e) { - return constructReflectively(clientInterface); - } + return constructReflectively(clientInterface); } @SuppressWarnings("unchecked") diff --git a/http-client/src/main/java/io/avaje/http/client/HttpApiProvider.java b/http-client/src/main/java/io/avaje/http/client/HttpApiProvider.java index e4ed08d8a..3cc408b7a 100644 --- a/http-client/src/main/java/io/avaje/http/client/HttpApiProvider.java +++ b/http-client/src/main/java/io/avaje/http/client/HttpApiProvider.java @@ -1,7 +1,5 @@ package io.avaje.http.client; -import java.util.Map; - /** * Provides http client implementations for an interface. * @@ -10,11 +8,6 @@ @FunctionalInterface public interface HttpApiProvider { - /** Return the interface type this API implements. */ - default Class type() { - throw new UnsupportedOperationException(); - } - /** Return the provided implementation of the API. */ T provide(HttpClient client); } diff --git a/http-client/src/main/java/module-info.java b/http-client/src/main/java/module-info.java index d5d23f60f..f8445cd87 100644 --- a/http-client/src/main/java/module-info.java +++ b/http-client/src/main/java/module-info.java @@ -1,6 +1,5 @@ module io.avaje.http.client { - uses io.avaje.http.client.HttpApiProvider; uses io.avaje.http.client.HttpClient.GeneratedComponent; requires transitive java.net.http; diff --git a/http-client/src/test/java/io/avaje/http/client/DHttpApiTest.java b/http-client/src/test/java/io/avaje/http/client/DHttpApiTest.java index 7d4511103..90ee7ca38 100644 --- a/http-client/src/test/java/io/avaje/http/client/DHttpApiTest.java +++ b/http-client/src/test/java/io/avaje/http/client/DHttpApiTest.java @@ -24,7 +24,7 @@ void test_github_listRepos() { .build(); DHttpApi httpApi = new DHttpApi(); - httpApi.addProvider(new Simple$HttpClient.Provider()); + httpApi.addProvider(Simple.class, Simple$HttpClient::new); final Simple simple = httpApi.provideFor(Simple.class, clientContext); final List repos = simple.listRepos("rbygrave", "junk"); @@ -45,7 +45,7 @@ void jsonb_github_listRepos() { .build(); DHttpApi httpApi = new DHttpApi(); - httpApi.addProvider(new Simple$HttpClient.Provider()); + httpApi.addProvider(Simple.class, Simple$HttpClient::new); final Simple simple = httpApi.provideFor(Simple.class, client); final List repos = simple.listRepos("rbygrave", "junk"); diff --git a/http-client/src/test/java/org/example/github/SimpleProvider.java b/http-client/src/test/java/org/example/github/SimpleProvider.java deleted file mode 100644 index aa5897e8f..000000000 --- a/http-client/src/test/java/org/example/github/SimpleProvider.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.example.github; - -import io.avaje.http.client.HttpApiProvider; -import io.avaje.http.client.HttpClient; -import org.example.github.httpclient.Simple$HttpClient; - -public class SimpleProvider implements HttpApiProvider { - - @Override - public Class type() { - return Simple.class; - } - - @Override - public Simple provide(HttpClient client) { - return new Simple$HttpClient(client); - } -} diff --git a/http-client/src/test/java/org/example/github/httpclient/Simple$HttpClient.java b/http-client/src/test/java/org/example/github/httpclient/Simple$HttpClient.java index ed6b73487..5e74ebfe2 100644 --- a/http-client/src/test/java/org/example/github/httpclient/Simple$HttpClient.java +++ b/http-client/src/test/java/org/example/github/httpclient/Simple$HttpClient.java @@ -64,18 +64,4 @@ public InputStream getById2(String id, InputStream is) { public HttpResponse getById2(String id) { return null; } - - public static class Provider implements HttpApiProvider { - - @Override - public Class type() { - return Simple.class; - } - - @Override - public Simple provide(HttpClient client) { - return new Simple$HttpClient(client); - } - } - } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java index cf6992745..9a5f21f8a 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java @@ -68,11 +68,8 @@ public ControllerReader(TypeElement beanType) { this.apiResponses = buildApiResponses(); hasInstrument = instrumentAllWebMethods() - || findAnnotation(ControllerPrism::getOptionalOn) - .map(ControllerPrism::instrumentRequestContext) - .or( - () -> - findAnnotation(InstrumentServerContextPrism::getOptionalOn).map(x -> true)) + || findAnnotation(InstrumentServerContextPrism::getOptionalOn) + .map(x -> true) .orElse(false); } diff --git a/tests/test-client-generation/src/test/java/org/example/SimpleTest.java b/tests/test-client-generation/src/test/java/org/example/SimpleTest.java index d3593983c..5a74828cc 100644 --- a/tests/test-client-generation/src/test/java/org/example/SimpleTest.java +++ b/tests/test-client-generation/src/test/java/org/example/SimpleTest.java @@ -2,10 +2,8 @@ import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; -import io.avaje.http.client.HttpApiProvider; import io.avaje.http.client.HttpClient; import io.avaje.http.client.JacksonBodyAdapter; -import org.example.httpclient.GitHubUsersHttpClient; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; @@ -27,7 +25,7 @@ void listRepos() { .bodyAdapter(new JacksonBodyAdapter(objectMapper)) .build(); - GitHubUsers simple = client.create(GitHubUsers.class); + final GitHubUsers simple = client.create(GitHubUsers.class); final List repos = simple.listRepos("rbygrave"); System.out.println("got repos - " + repos.size()); @@ -35,16 +33,4 @@ void listRepos() { assertThat(repos).hasSizeGreaterThan(5); } - public static class AP implements HttpApiProvider { - - @Override - public Class type() { - return GitHubUsers.class; - } - - @Override - public GitHubUsers provide(HttpClient client) { - return new GitHubUsersHttpClient(client); - } - } } diff --git a/tests/test-client/src/main/java/example/github/SimpleHttpClient.java b/tests/test-client/src/main/java/example/github/SimpleHttpClient.java deleted file mode 100644 index 882685577..000000000 --- a/tests/test-client/src/main/java/example/github/SimpleHttpClient.java +++ /dev/null @@ -1,43 +0,0 @@ -package example.github; - -import io.avaje.http.client.HttpApiProvider; -import io.avaje.http.client.HttpClient; -import io.avaje.http.client.HttpException; - -import java.util.List; - -/** - * This code could be generated from the interface definition. - */ -public class SimpleHttpClient implements HttpApiProvider { - - @Override - public Class type() { - return Simple.class; - } - - @Override - public Simple provide(HttpClient client) { - return new SimpleClient(client); - } - - private static class SimpleClient implements Simple { - - private final HttpClient context; - - SimpleClient(HttpClient context) { - this.context = context; - } - - //@Get("users/{user}/repos") - @Override - public List listRepos(String user, String other) throws HttpException { - return context.request() - .path("users").path(user).path("repos") - .queryParam("other", other) - .GET().list(Repo.class); - } - - } - -} diff --git a/tests/test-client/src/main/java/example/github/httpclient/Simple$HttpClient.java b/tests/test-client/src/main/java/example/github/httpclient/Simple$HttpClient.java new file mode 100644 index 000000000..1a8a351a0 --- /dev/null +++ b/tests/test-client/src/main/java/example/github/httpclient/Simple$HttpClient.java @@ -0,0 +1,31 @@ +package example.github.httpclient; + +import java.util.List; + +import example.github.Repo; +import example.github.Simple; +import io.avaje.http.client.HttpClient; +import io.avaje.http.client.HttpException; + +/** This code could be generated from the interface definition. */ +public class Simple$HttpClient implements Simple { + + private final HttpClient context; + + public Simple$HttpClient(HttpClient context) { + this.context = context; + } + + // @Get("users/{user}/repos") + @Override + public List listRepos(String user, String other) throws HttpException { + return context + .request() + .path("users") + .path(user) + .path("repos") + .queryParam("other", other) + .GET() + .list(Repo.class); + } +} diff --git a/tests/test-client/src/main/java/module-info.java b/tests/test-client/src/main/java/module-info.java index af18dba30..807302394 100644 --- a/tests/test-client/src/main/java/module-info.java +++ b/tests/test-client/src/main/java/module-info.java @@ -1,12 +1,8 @@ -import example.github.SimpleHttpClient; - open module test { requires io.avaje.http.client; requires com.fasterxml.jackson.databind; requires com.google.gson; - provides io.avaje.http.client.HttpApiProvider with SimpleHttpClient; - exports example.github; } diff --git a/tests/test-helidon/src/main/java/org/example/ReqScopedController.java b/tests/test-helidon/src/main/java/org/example/ReqScopedController.java index ec5c2b37e..87978c361 100644 --- a/tests/test-helidon/src/main/java/org/example/ReqScopedController.java +++ b/tests/test-helidon/src/main/java/org/example/ReqScopedController.java @@ -2,14 +2,16 @@ import io.avaje.http.api.Controller; import io.avaje.http.api.Get; +import io.avaje.http.api.InstrumentServerContext; import io.avaje.http.api.Path; import io.avaje.http.api.Produces; import io.helidon.webserver.ServerRequest; import io.helidon.webserver.ServerResponse; import jakarta.inject.Inject; -@Controller(instrumentRequestContext = true) +@Controller @Path("/req-scoped") +@InstrumentServerContext public class ReqScopedController { @Inject diff --git a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController2.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController2.java index 13d5190a5..dbc5ad2ef 100644 --- a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController2.java +++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController2.java @@ -6,16 +6,7 @@ import org.example.myapp.web.ServerType; -import io.avaje.http.api.BodyString; -import io.avaje.http.api.Consumes; -import io.avaje.http.api.Controller; -import io.avaje.http.api.Default; -import io.avaje.http.api.Form; -import io.avaje.http.api.FormParam; -import io.avaje.http.api.Get; -import io.avaje.http.api.Path; -import io.avaje.http.api.Post; -import io.avaje.http.api.QueryParam; +import io.avaje.http.api.*; import io.javalin.http.Context; @Path("test/") @@ -23,12 +14,14 @@ public class TestController2 { @Form - @Get(value = "/enumForm", instrumentRequestContext = true) + @Get("/enumForm") + @InstrumentServerContext void enumForm(String s, ServerType type, Context ctx) { ctx.result(s); } - @Get(value = "/enumFormParam", instrumentRequestContext = true) + @Get("/enumFormParam") + @InstrumentServerContext String enumFormParam(@FormParam String s, @FormParam ServerType type) throws Exception { return type.name(); } @@ -64,7 +57,8 @@ String bytes(byte[] array) { return array.toString(); } - @Post(value = "/strBody", instrumentRequestContext = true) + @Post("/strBody") + @InstrumentServerContext String strBody(@BodyString String body) { return body; } diff --git a/tests/test-javalin/src/main/java/org/example/myapp/web/BarInterface.java b/tests/test-javalin/src/main/java/org/example/myapp/web/BarInterface.java index 7aae1aba8..18d8ce110 100644 --- a/tests/test-javalin/src/main/java/org/example/myapp/web/BarInterface.java +++ b/tests/test-javalin/src/main/java/org/example/myapp/web/BarInterface.java @@ -1,9 +1,6 @@ package org.example.myapp.web; -import io.avaje.http.api.Get; -import io.avaje.http.api.MediaType; -import io.avaje.http.api.Path; -import io.avaje.http.api.Produces; +import io.avaje.http.api.*; import io.swagger.v3.oas.annotations.links.Link; import io.swagger.v3.oas.annotations.responses.ApiResponse; @@ -19,7 +16,8 @@ public interface BarInterface { @Get("/find/:code") List findByCode(String code); + @Get @Produces(MediaType.TEXT_PLAIN) - @Get(instrumentRequestContext = true) + @InstrumentServerContext String barMessage(); } diff --git a/tests/test-jex/src/main/java/org/example/web/TestController.java b/tests/test-jex/src/main/java/org/example/web/TestController.java index 1afed2f56..00f23d717 100644 --- a/tests/test-jex/src/main/java/org/example/web/TestController.java +++ b/tests/test-jex/src/main/java/org/example/web/TestController.java @@ -2,17 +2,12 @@ import java.util.Set; -import io.avaje.http.api.BodyString; -import io.avaje.http.api.Controller; -import io.avaje.http.api.Default; -import io.avaje.http.api.Get; -import io.avaje.http.api.Path; -import io.avaje.http.api.Post; -import io.avaje.http.api.QueryParam; +import io.avaje.http.api.*; import io.avaje.jex.Context; @Path("test/") -@Controller(instrumentRequestContext = true) +@Controller +@InstrumentServerContext public class TestController { @Get("/paramMulti") From c22f6f139852c5c02fd418cb9e726cac0678295e Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Fri, 21 Jul 2023 13:24:04 +1200 Subject: [PATCH 0800/1323] Deprecate the old reactive Helidon, effectively replaced by Nima going forward --- {http-generator-helidon => deprecated-generator-helidon}/pom.xml | 0 .../src/etc/activate-shade-module | 0 .../io/avaje/http/generator/helidon/ControllerMethodWriter.java | 0 .../java/io/avaje/http/generator/helidon/ControllerWriter.java | 0 .../io/avaje/http/generator/helidon/HelidonPlatformAdapter.java | 0 .../java/io/avaje/http/generator/helidon/HelidonProcessor.java | 0 .../src/main/java/module-info.java | 0 .../META-INF/services/javax.annotation.processing.Processor | 0 .../resources/META-INF/gradle/incremental.annotation.processors | 1 - pom.xml | 1 - tests/{test-helidon => deprecated-test-helidon}/logback.xml | 0 tests/{test-helidon => deprecated-test-helidon}/pom.xml | 0 .../src/main/java/org/example/FooController.java | 0 .../src/main/java/org/example/GreetService.java | 0 .../src/main/java/org/example/Main.java | 0 .../src/main/java/org/example/ReqScopedController.java | 0 .../src/main/java/org/example/ServerType.java | 0 .../src/main/java/org/example/TestController.java | 0 .../src/main/java/org/example/api/Foo.java | 0 .../src/main/java/org/example/api/FooBody.java | 0 .../src/test/java/org/example/BaseWebTest.java | 0 .../src/test/java/org/example/FooControllerTest.java | 0 .../src/test/java/org/example/ReqScopedControllerTest.java | 0 .../src/test/resources/logback-test.xml | 0 tests/pom.xml | 1 - 25 files changed, 3 deletions(-) rename {http-generator-helidon => deprecated-generator-helidon}/pom.xml (100%) rename {http-generator-helidon => deprecated-generator-helidon}/src/etc/activate-shade-module (100%) rename {http-generator-helidon => deprecated-generator-helidon}/src/main/java/io/avaje/http/generator/helidon/ControllerMethodWriter.java (100%) rename {http-generator-helidon => deprecated-generator-helidon}/src/main/java/io/avaje/http/generator/helidon/ControllerWriter.java (100%) rename {http-generator-helidon => deprecated-generator-helidon}/src/main/java/io/avaje/http/generator/helidon/HelidonPlatformAdapter.java (100%) rename {http-generator-helidon => deprecated-generator-helidon}/src/main/java/io/avaje/http/generator/helidon/HelidonProcessor.java (100%) rename {http-generator-helidon => deprecated-generator-helidon}/src/main/java/module-info.java (100%) rename {http-generator-helidon => deprecated-generator-helidon}/src/main/resources/META-INF/services/javax.annotation.processing.Processor (100%) delete mode 100644 http-generator-helidon/src/main/resources/META-INF/gradle/incremental.annotation.processors rename tests/{test-helidon => deprecated-test-helidon}/logback.xml (100%) rename tests/{test-helidon => deprecated-test-helidon}/pom.xml (100%) rename tests/{test-helidon => deprecated-test-helidon}/src/main/java/org/example/FooController.java (100%) rename tests/{test-helidon => deprecated-test-helidon}/src/main/java/org/example/GreetService.java (100%) rename tests/{test-helidon => deprecated-test-helidon}/src/main/java/org/example/Main.java (100%) rename tests/{test-helidon => deprecated-test-helidon}/src/main/java/org/example/ReqScopedController.java (100%) rename tests/{test-helidon => deprecated-test-helidon}/src/main/java/org/example/ServerType.java (100%) rename tests/{test-helidon => deprecated-test-helidon}/src/main/java/org/example/TestController.java (100%) rename tests/{test-helidon => deprecated-test-helidon}/src/main/java/org/example/api/Foo.java (100%) rename tests/{test-helidon => deprecated-test-helidon}/src/main/java/org/example/api/FooBody.java (100%) rename tests/{test-helidon => deprecated-test-helidon}/src/test/java/org/example/BaseWebTest.java (100%) rename tests/{test-helidon => deprecated-test-helidon}/src/test/java/org/example/FooControllerTest.java (100%) rename tests/{test-helidon => deprecated-test-helidon}/src/test/java/org/example/ReqScopedControllerTest.java (100%) rename tests/{test-helidon => deprecated-test-helidon}/src/test/resources/logback-test.xml (100%) diff --git a/http-generator-helidon/pom.xml b/deprecated-generator-helidon/pom.xml similarity index 100% rename from http-generator-helidon/pom.xml rename to deprecated-generator-helidon/pom.xml diff --git a/http-generator-helidon/src/etc/activate-shade-module b/deprecated-generator-helidon/src/etc/activate-shade-module similarity index 100% rename from http-generator-helidon/src/etc/activate-shade-module rename to deprecated-generator-helidon/src/etc/activate-shade-module diff --git a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/ControllerMethodWriter.java b/deprecated-generator-helidon/src/main/java/io/avaje/http/generator/helidon/ControllerMethodWriter.java similarity index 100% rename from http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/ControllerMethodWriter.java rename to deprecated-generator-helidon/src/main/java/io/avaje/http/generator/helidon/ControllerMethodWriter.java diff --git a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/ControllerWriter.java b/deprecated-generator-helidon/src/main/java/io/avaje/http/generator/helidon/ControllerWriter.java similarity index 100% rename from http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/ControllerWriter.java rename to deprecated-generator-helidon/src/main/java/io/avaje/http/generator/helidon/ControllerWriter.java diff --git a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/HelidonPlatformAdapter.java b/deprecated-generator-helidon/src/main/java/io/avaje/http/generator/helidon/HelidonPlatformAdapter.java similarity index 100% rename from http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/HelidonPlatformAdapter.java rename to deprecated-generator-helidon/src/main/java/io/avaje/http/generator/helidon/HelidonPlatformAdapter.java diff --git a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/HelidonProcessor.java b/deprecated-generator-helidon/src/main/java/io/avaje/http/generator/helidon/HelidonProcessor.java similarity index 100% rename from http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/HelidonProcessor.java rename to deprecated-generator-helidon/src/main/java/io/avaje/http/generator/helidon/HelidonProcessor.java diff --git a/http-generator-helidon/src/main/java/module-info.java b/deprecated-generator-helidon/src/main/java/module-info.java similarity index 100% rename from http-generator-helidon/src/main/java/module-info.java rename to deprecated-generator-helidon/src/main/java/module-info.java diff --git a/http-generator-helidon/src/main/resources/META-INF/services/javax.annotation.processing.Processor b/deprecated-generator-helidon/src/main/resources/META-INF/services/javax.annotation.processing.Processor similarity index 100% rename from http-generator-helidon/src/main/resources/META-INF/services/javax.annotation.processing.Processor rename to deprecated-generator-helidon/src/main/resources/META-INF/services/javax.annotation.processing.Processor diff --git a/http-generator-helidon/src/main/resources/META-INF/gradle/incremental.annotation.processors b/http-generator-helidon/src/main/resources/META-INF/gradle/incremental.annotation.processors deleted file mode 100644 index 35bdfd2c5..000000000 --- a/http-generator-helidon/src/main/resources/META-INF/gradle/incremental.annotation.processors +++ /dev/null @@ -1 +0,0 @@ -io.avaje.http.generator.helidon.HelidonProcessor,aggregating diff --git a/pom.xml b/pom.xml index b3518152a..7e2900a48 100644 --- a/pom.xml +++ b/pom.xml @@ -43,7 +43,6 @@ http-generator-core http-generator-javalin http-generator-jex - http-generator-helidon http-generator-client http-generator-nima diff --git a/tests/test-helidon/logback.xml b/tests/deprecated-test-helidon/logback.xml similarity index 100% rename from tests/test-helidon/logback.xml rename to tests/deprecated-test-helidon/logback.xml diff --git a/tests/test-helidon/pom.xml b/tests/deprecated-test-helidon/pom.xml similarity index 100% rename from tests/test-helidon/pom.xml rename to tests/deprecated-test-helidon/pom.xml diff --git a/tests/test-helidon/src/main/java/org/example/FooController.java b/tests/deprecated-test-helidon/src/main/java/org/example/FooController.java similarity index 100% rename from tests/test-helidon/src/main/java/org/example/FooController.java rename to tests/deprecated-test-helidon/src/main/java/org/example/FooController.java diff --git a/tests/test-helidon/src/main/java/org/example/GreetService.java b/tests/deprecated-test-helidon/src/main/java/org/example/GreetService.java similarity index 100% rename from tests/test-helidon/src/main/java/org/example/GreetService.java rename to tests/deprecated-test-helidon/src/main/java/org/example/GreetService.java diff --git a/tests/test-helidon/src/main/java/org/example/Main.java b/tests/deprecated-test-helidon/src/main/java/org/example/Main.java similarity index 100% rename from tests/test-helidon/src/main/java/org/example/Main.java rename to tests/deprecated-test-helidon/src/main/java/org/example/Main.java diff --git a/tests/test-helidon/src/main/java/org/example/ReqScopedController.java b/tests/deprecated-test-helidon/src/main/java/org/example/ReqScopedController.java similarity index 100% rename from tests/test-helidon/src/main/java/org/example/ReqScopedController.java rename to tests/deprecated-test-helidon/src/main/java/org/example/ReqScopedController.java diff --git a/tests/test-helidon/src/main/java/org/example/ServerType.java b/tests/deprecated-test-helidon/src/main/java/org/example/ServerType.java similarity index 100% rename from tests/test-helidon/src/main/java/org/example/ServerType.java rename to tests/deprecated-test-helidon/src/main/java/org/example/ServerType.java diff --git a/tests/test-helidon/src/main/java/org/example/TestController.java b/tests/deprecated-test-helidon/src/main/java/org/example/TestController.java similarity index 100% rename from tests/test-helidon/src/main/java/org/example/TestController.java rename to tests/deprecated-test-helidon/src/main/java/org/example/TestController.java diff --git a/tests/test-helidon/src/main/java/org/example/api/Foo.java b/tests/deprecated-test-helidon/src/main/java/org/example/api/Foo.java similarity index 100% rename from tests/test-helidon/src/main/java/org/example/api/Foo.java rename to tests/deprecated-test-helidon/src/main/java/org/example/api/Foo.java diff --git a/tests/test-helidon/src/main/java/org/example/api/FooBody.java b/tests/deprecated-test-helidon/src/main/java/org/example/api/FooBody.java similarity index 100% rename from tests/test-helidon/src/main/java/org/example/api/FooBody.java rename to tests/deprecated-test-helidon/src/main/java/org/example/api/FooBody.java diff --git a/tests/test-helidon/src/test/java/org/example/BaseWebTest.java b/tests/deprecated-test-helidon/src/test/java/org/example/BaseWebTest.java similarity index 100% rename from tests/test-helidon/src/test/java/org/example/BaseWebTest.java rename to tests/deprecated-test-helidon/src/test/java/org/example/BaseWebTest.java diff --git a/tests/test-helidon/src/test/java/org/example/FooControllerTest.java b/tests/deprecated-test-helidon/src/test/java/org/example/FooControllerTest.java similarity index 100% rename from tests/test-helidon/src/test/java/org/example/FooControllerTest.java rename to tests/deprecated-test-helidon/src/test/java/org/example/FooControllerTest.java diff --git a/tests/test-helidon/src/test/java/org/example/ReqScopedControllerTest.java b/tests/deprecated-test-helidon/src/test/java/org/example/ReqScopedControllerTest.java similarity index 100% rename from tests/test-helidon/src/test/java/org/example/ReqScopedControllerTest.java rename to tests/deprecated-test-helidon/src/test/java/org/example/ReqScopedControllerTest.java diff --git a/tests/test-helidon/src/test/resources/logback-test.xml b/tests/deprecated-test-helidon/src/test/resources/logback-test.xml similarity index 100% rename from tests/test-helidon/src/test/resources/logback-test.xml rename to tests/deprecated-test-helidon/src/test/resources/logback-test.xml diff --git a/tests/pom.xml b/tests/pom.xml index f8075847f..a5957df9b 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -21,7 +21,6 @@ - test-helidon test-javalin test-javalin-jsonb test-jex From 65d8a162cc9e7d96998bded07607075fc6364df4 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Thu, 20 Jul 2023 23:40:37 -0400 Subject: [PATCH 0801/1323] Rename Nima Generator (#239) * rename nima generator * Update README.md * Update pom.xml --- README.md | 45 ------------------- .../pom.xml | 2 +- .../src/etc/activate-shade-module | 0 .../helidon/nima/ControllerMethodWriter.java | 0 .../helidon/nima/ControllerWriter.java | 0 .../helidon/nima/NimaPlatformAdapter.java | 0 .../generator/helidon/nima/NimaProcessor.java | 0 .../src/main/java/module-info.java | 0 .../javax.annotation.processing.Processor | 0 .../gradle/incremental.annotation.processors | 1 - pom.xml | 10 ++++- tests/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 4 +- tests/test-nima/pom.xml | 2 +- 14 files changed, 14 insertions(+), 52 deletions(-) rename {http-generator-nima => http-generator-helidon}/pom.xml (95%) rename {http-generator-nima => http-generator-helidon}/src/etc/activate-shade-module (100%) rename {http-generator-nima => http-generator-helidon}/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java (100%) rename {http-generator-nima => http-generator-helidon}/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java (100%) rename {http-generator-nima => http-generator-helidon}/src/main/java/io/avaje/http/generator/helidon/nima/NimaPlatformAdapter.java (100%) rename {http-generator-nima => http-generator-helidon}/src/main/java/io/avaje/http/generator/helidon/nima/NimaProcessor.java (100%) rename {http-generator-nima => http-generator-helidon}/src/main/java/module-info.java (100%) rename {http-generator-nima => http-generator-helidon}/src/main/resources/META-INF/services/javax.annotation.processing.Processor (100%) delete mode 100644 http-generator-nima/src/main/resources/META-INF/gradle/incremental.annotation.processors diff --git a/README.md b/README.md index 4e33f3806..517b2589e 100644 --- a/README.md +++ b/README.md @@ -94,21 +94,6 @@ Javalin.create() .start(); ``` -### Usage with Helidon SE - -The annotation processor will generate controller classes implementing the Helidon Service interface, which we can use -get all the Services and register them with Helidon `RoutingBuilder`. - -```java -var routes = BeanScope.builder().build().list(Service.class); -var routingBuilder = Routing.builder().register(routes.stream().toArray(Service[]::new)); -WebServer.builder() - .addMediaSupport(JacksonSupport.create()) - .routing(routingBuilder) - .build() - .start(); -``` - ### Usage with Helidon Nima The annotation processor will generate controller classes implementing the Helidon HttpService interface, which we can use @@ -162,36 +147,6 @@ public class WidgetController$Route implements WebRoutes { } ``` -### (Helidon SE) The generated WidgetController$Route.java is: -```java -@Generated("avaje-helidon-generator") -@Singleton -public class WidgetController$Route implements Service { - - private final WidgetController controller; - - public WidgetController$Route(WidgetController controller) { - this.controller = controller; - } - - @Override - public void update(Routing.Rules rules) { - - rules.get("/widgets/{id}", this::_getById); - rules.post("/widgets", this::_getAll); - } - - private void _getById(ServerRequest req, ServerResponse res) { - int id = asInt(req.path().param("id")); - res.send(controller.getById(id)); - } - - private void _getAll(ServerRequest req, ServerResponse res) { - res.send(controller.getAll()); - } -} -``` - ### (Helidon Nima) The generated WidgetController$Route.java is: ```java diff --git a/http-generator-nima/pom.xml b/http-generator-helidon/pom.xml similarity index 95% rename from http-generator-nima/pom.xml rename to http-generator-helidon/pom.xml index 3b9d670a7..e1cbc2577 100644 --- a/http-generator-nima/pom.xml +++ b/http-generator-helidon/pom.xml @@ -7,7 +7,7 @@ 2.0-SNAPSHOT - avaje-http-nima-generator + avaje-http-helidon-generator 20 diff --git a/http-generator-nima/src/etc/activate-shade-module b/http-generator-helidon/src/etc/activate-shade-module similarity index 100% rename from http-generator-nima/src/etc/activate-shade-module rename to http-generator-helidon/src/etc/activate-shade-module diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java similarity index 100% rename from http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java rename to http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java similarity index 100% rename from http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java rename to http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/NimaPlatformAdapter.java b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/NimaPlatformAdapter.java similarity index 100% rename from http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/NimaPlatformAdapter.java rename to http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/NimaPlatformAdapter.java diff --git a/http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/NimaProcessor.java b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/NimaProcessor.java similarity index 100% rename from http-generator-nima/src/main/java/io/avaje/http/generator/helidon/nima/NimaProcessor.java rename to http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/NimaProcessor.java diff --git a/http-generator-nima/src/main/java/module-info.java b/http-generator-helidon/src/main/java/module-info.java similarity index 100% rename from http-generator-nima/src/main/java/module-info.java rename to http-generator-helidon/src/main/java/module-info.java diff --git a/http-generator-nima/src/main/resources/META-INF/services/javax.annotation.processing.Processor b/http-generator-helidon/src/main/resources/META-INF/services/javax.annotation.processing.Processor similarity index 100% rename from http-generator-nima/src/main/resources/META-INF/services/javax.annotation.processing.Processor rename to http-generator-helidon/src/main/resources/META-INF/services/javax.annotation.processing.Processor diff --git a/http-generator-nima/src/main/resources/META-INF/gradle/incremental.annotation.processors b/http-generator-nima/src/main/resources/META-INF/gradle/incremental.annotation.processors deleted file mode 100644 index cbda140e4..000000000 --- a/http-generator-nima/src/main/resources/META-INF/gradle/incremental.annotation.processors +++ /dev/null @@ -1 +0,0 @@ -io.avaje.http.generator.helidon.nima.HelidonProcessor,aggregating diff --git a/pom.xml b/pom.xml index 7e2900a48..8d2d455b7 100644 --- a/pom.xml +++ b/pom.xml @@ -44,7 +44,6 @@ http-generator-javalin http-generator-jex http-generator-client - http-generator-nima @@ -60,6 +59,15 @@ tests + + jdk19plus + + [20,21] + + + http-generator-helidon + + diff --git a/tests/pom.xml b/tests/pom.xml index a5957df9b..f512c27e3 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -32,7 +32,7 @@ jdk19plus - [19,20] + [19,20,21] test-nima diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 2ec0cec0e..37cb8abb7 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -56,7 +56,7 @@ io.avaje - avaje-http-nima-generator + avaje-http-helidon-generator ${project.version} test @@ -80,7 +80,7 @@ io.avaje - avaje-http-nima-generator + avaje-http-helidon-generator ${project.version} diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index a3e1cccd1..ff0340ea6 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -63,7 +63,7 @@ io.avaje - avaje-http-nima-generator + avaje-http-helidon-generator ${project.version} From 9c63c91df3e7d580685628f364719d059d269e80 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Fri, 21 Jul 2023 17:10:07 +1200 Subject: [PATCH 0802/1323] Fix build for rename nima generator to avaje-http-helidon-generator --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 1c8e40d52..4df2a955a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -35,7 +35,7 @@ jobs: run: | if (( JAVA_VERSION < 20 )); then - mvn clean package -pl "!:avaje-http-nima-generator" + mvn clean package -pl "!:avaje-http-helidon-generator" else mvn clean package fi From 33483ccafc54e09c8056ad61a3a8fb9f690af714 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Fri, 21 Jul 2023 17:14:51 +1200 Subject: [PATCH 0803/1323] Fix build for rename nima generator to avaje-http-helidon-generator --- .github/workflows/build.yml | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 4df2a955a..46803152e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -33,9 +33,4 @@ jobs: env: JAVA_VERSION: ${{ matrix.java_version }} run: | - if (( JAVA_VERSION < 20 )); - then - mvn clean package -pl "!:avaje-http-helidon-generator" - else - mvn clean package - fi + mvn clean package From 668c2d6090923af0f4ed7bb45b5c38e6bd2f83b0 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sat, 22 Jul 2023 21:45:28 -0400 Subject: [PATCH 0804/1323] Add Client to README --- README.md | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 517b2589e..f00b7a4ec 100644 --- a/README.md +++ b/README.md @@ -6,14 +6,26 @@ HTTP server and client libraries via code generation. -## HTTP Server +## [HTTP Client](https://avaje.io/http-client/) -A jax-rs style controllers with annotations (`@Path`, `@Get` ...) -that is lightweight by using source code generation (annotation processors) +An enhanced wrapper to the [JDK 11+ Java Http Client](http://openjdk.java.net/groups/net/httpclient/intro.html). Additionally, you can create Feign-style interfaces and have implementations generated via annotation processing. + +- Fluid API for building URLs and payload +- JSON marshaling using Avaje Jsonb/Jackson/Gson +- Light Feign-style interfaces via annotation processing. +- Request/Response Interception +- Authorization via Basic Auth or OAuth Bearer Tokens +- Async and sync API + +## [HTTP Server](https://avaje.io/http/) + +Use jax-rs style controllers with annotations (`@Path`, `@Get` ...) +that are lightweight by using source code generation (annotation processors) to generate adapter code for Javalin and Helidon SE/Nima. -- Lightweight as in 65Kb library + generated source code +- Lightweight (65Kb library + generated source code) - Full use of Javalin or Helidon SE/Nima as desired +- Bean Validation of request bodies supported ## Add dependencies ```xml From a7a10d3f683da3aa61f5ebbe36ce04dae64be115 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sat, 22 Jul 2023 21:49:54 -0400 Subject: [PATCH 0805/1323] Update README.md --- README.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/README.md b/README.md index f00b7a4ec..2785041dc 100644 --- a/README.md +++ b/README.md @@ -19,9 +19,7 @@ An enhanced wrapper to the [JDK 11+ Java Http Client](http://openjdk.java.net/gr ## [HTTP Server](https://avaje.io/http/) -Use jax-rs style controllers with annotations (`@Path`, `@Get` ...) -that are lightweight by using source code generation (annotation processors) -to generate adapter code for Javalin and Helidon SE/Nima. +Use source code generation to adapt annotated REST controllers `@Path, @Get, @Post, etc` to Javalin, Helidon SE, and similar web routing HTTP servers. - Lightweight (65Kb library + generated source code) - Full use of Javalin or Helidon SE/Nima as desired From d4fc7adf4e0d58dd12d14832e135c5d2e35765f0 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Mon, 24 Jul 2023 19:00:59 +1200 Subject: [PATCH 0806/1323] Format pom only --- pom.xml | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/pom.xml b/pom.xml index 8d2d455b7..41e4444ad 100644 --- a/pom.xml +++ b/pom.xml @@ -59,16 +59,15 @@ tests - - jdk19plus - - [20,21] - - - http-generator-helidon - - - + + jdk19plus + + [20,21] + + + http-generator-helidon + + module-info.shade From 19602c25be6b6a8342653c8e27897ac332e296f6 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Mon, 24 Jul 2023 19:05:24 +1200 Subject: [PATCH 0807/1323] Version 2.0-RC1 --- http-api/pom.xml | 2 +- http-client-gson-adapter/pom.xml | 4 ++-- http-client/pom.xml | 2 +- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 2 +- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-inject-plugin/pom.xml | 2 +- pom.xml | 2 +- tests/pom.xml | 2 +- tests/test-client-generation/pom.xml | 2 +- tests/test-client/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- 18 files changed, 19 insertions(+), 19 deletions(-) diff --git a/http-api/pom.xml b/http-api/pom.xml index f28e5d9a9..20750789d 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-SNAPSHOT + 2.0-RC1 .. diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index ec3be33f3..6c97bc449 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-SNAPSHOT + 2.0-RC1 avaje-http-client-gson @@ -20,7 +20,7 @@ io.avaje avaje-http-client - 2.0-SNAPSHOT + 2.0-RC1 provided diff --git a/http-client/pom.xml b/http-client/pom.xml index 416c95f67..11c7f7b51 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-SNAPSHOT + 2.0-RC1 avaje-http-client diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index e27a75daf..caa827f6c 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-SNAPSHOT + 2.0-RC1 avaje-http-client-generator diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 75128302f..1ad4e98d1 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-SNAPSHOT + 2.0-RC1 avaje-http-generator-core diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index e1cbc2577..f7be6bef1 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.0-SNAPSHOT + 2.0-RC1 avaje-http-helidon-generator diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index 73d842f51..706959d19 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-SNAPSHOT + 2.0-RC1 avaje-http-javalin-generator diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index 5686ea66c..ca47c886c 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-SNAPSHOT + 2.0-RC1 avaje-http-jex-generator diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index 29c0cd168..16246b28d 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-SNAPSHOT + 2.0-RC1 .. diff --git a/pom.xml b/pom.xml index 41e4444ad..eddd479a0 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-parent - 2.0-SNAPSHOT + 2.0-RC1 pom diff --git a/tests/pom.xml b/tests/pom.xml index f512c27e3..e12f789ae 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.0-SNAPSHOT + 2.0-RC1 tests diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index e491690b1..b234ca7d1 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.0-SNAPSHOT + 2.0-RC1 test-client-generation diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index 25e359d7a..a5bcedc7f 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.0-SNAPSHOT + 2.0-RC1 test-client diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 065935419..9fc5b2a01 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 2.0-SNAPSHOT + 2.0-RC1 test-javalin-jsonb diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 0ea40571b..6c22fc6b1 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.0-SNAPSHOT + 2.0-RC1 test-javalin diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index c4804dc28..0eaac75f9 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.0-SNAPSHOT + 2.0-RC1 test-jex diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 37cb8abb7..5d9674e1a 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.0-SNAPSHOT + 2.0-RC1 test-nima-jsonb diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index ff0340ea6..494bca7e7 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.0-SNAPSHOT + 2.0-RC1 test-nima From 840d92ea40aed7c089c518e7b410d448687657f4 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Mon, 24 Jul 2023 13:15:49 -0400 Subject: [PATCH 0808/1323] Correct Generated Helidon Code in README --- README.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 2785041dc..b4dce8fdb 100644 --- a/README.md +++ b/README.md @@ -76,7 +76,7 @@ public class WidgetController { ## DI Usage The annotation processor will generate controller adapters that can register routes to Javalin/Helidon. The natural way to use the generated adapters is to get a DI library to find and wire them. This is what the below examples do and they use [Avaje-Inject](https://avaje.io/inject/) to do this. The AP will automatically detect the presence of avaje-inject and generate the class to use avaje-inject's `@Component` as the DI annotation. -There isn't a hard requirement to use Avaje for dependency injection. In the absence of avaje-inject the generated class will use `@jakarta.inject.Singleton` or `@javax.inject.Singleton` depending on what's on the classpath. Any DI library that can find and wire the generated @Singleton beans can be used. You can even use Dagger2 or Guice to wire the controllers if you so desire. +There isn't a hard requirement to use Avaje for dependency injection. In the absence of avaje-inject, the generated class will use `@jakarta.inject.Singleton` or `@javax.inject.Singleton` depending on what's on the classpath. Any DI library that can find and wire the generated @Singleton beans can be used. You can even use Dagger2 or Guice to wire the controllers if you so desire. To force the AP to generate with `@javax.inject.Singleton`(in the case where you have both jakarta and javax on the classpath), use the compiler arg `-AuseJavax=true` ```xml @@ -97,7 +97,7 @@ The annotation processor will generate controller classes implementing the WebRo get all the WebRoutes and register them with Javalin using: ```java -var routes = BeanScope.builder().build().list(WebRoutes.class); +List routes = BeanScope.builder().build().list(WebRoutes.class); Javalin.create() .routes(() -> routes.forEach(WebRoutes::registerRoutes)) @@ -110,7 +110,7 @@ The annotation processor will generate controller classes implementing the Helid get all the services and register them with the Helidon `HttpRouting`. ```java -var routes = BeanScope.builder().build().list(HttpService.class); +List routes = BeanScope.builder().build().list(HttpService.class); final var builder = HttpRouting.builder(); for (final HttpService httpService : routes) { @@ -170,12 +170,12 @@ public class WidgetController$Route implements HttpService { } @Override - public void routing(HttpRules rules) { + public void routing(HttpRules rules) throws Exception { rules.get("/widgets/{id}", this::_getById); rules.get("/widgets", this::_getAll); } - private void _getById(ServerRequest req, ServerResponse res) { + private void _getById(ServerRequest req, ServerResponse res) throws Exception { var pathParams = req.path().pathParameters(); int id = asInt(pathParams.first("id").get()); var result = controller.getById(id); @@ -253,7 +253,7 @@ public class WidgetController$Route implements HttpService { rules.get("/widgets", this::_getAll); } - private void _getById(ServerRequest req, ServerResponse res) { + private void _getById(ServerRequest req, ServerResponse res) throws Exception { var pathParams = req.path().pathParameters(); int id = asInt(pathParams.first("id").get()); var result = controller.getById(id); @@ -261,7 +261,7 @@ public class WidgetController$Route implements HttpService { widgetJsonType.toJson(result, JsonOutput.of(res)); } - private void _getAll(ServerRequest req, ServerResponse res) { + private void _getAll(ServerRequest req, ServerResponse res) throws Exception { var pathParams = req.path().pathParameters(); var result = controller.getAll(); res.headers().contentType(HttpMediaType.APPLICATION_JSON); From b43e003f23cf4b711cb7c34339a92a6e4cfa274d Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Mon, 24 Jul 2023 13:19:35 -0400 Subject: [PATCH 0809/1323] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index b4dce8fdb..c005e9eb9 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # [Avaje-HTTP](https://avaje.io/http/) [![Build](https://github.com/avaje/avaje-http/actions/workflows/build.yml/badge.svg)](https://github.com/avaje/avaje-http/actions/workflows/build.yml) - +[![Maven Central : avaje-inject](https://img.shields.io/maven-central/v/io.avaje/avaje-http-api.svg?label=Maven%20Central)](https://maven-badges.herokuapp.com/maven-central/io.avaje/avaje-http-api) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://github.com/avaje/avaje-inject/blob/master/LICENSE) [![Discord](https://img.shields.io/discord/1074074312421683250?color=%237289da&label=discord)](https://discord.gg/Qcqf9R27BR) @@ -33,13 +33,13 @@ Use source code generation to adapt annotated REST controllers `@Path, @Get, @Po ${avaje.http.version} ``` -#### Add the generator module for your desired microframework as a annotation processor. +#### Add the generator module for your desired microframework as an annotation processor. ```xml io.avaje - avaje-http-javalin-generator + avaje-http-{javalin/helidon}-generator ${avaje-http.version} provided From a41798ab9901aa04eacdfe4b83ff552086650e8d Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Mon, 24 Jul 2023 13:29:28 -0400 Subject: [PATCH 0810/1323] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c005e9eb9..b3c66d190 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ HTTP server and client libraries via code generation. ## [HTTP Client](https://avaje.io/http-client/) -An enhanced wrapper to the [JDK 11+ Java Http Client](http://openjdk.java.net/groups/net/httpclient/intro.html). Additionally, you can create Feign-style interfaces and have implementations generated via annotation processing. +A light (~80kb) wrapper to the [JDK 11+ Java Http Client](http://openjdk.java.net/groups/net/httpclient/intro.html). Additionally, you can create Feign-style interfaces and have implementations generated via annotation processing. - Fluid API for building URLs and payload - JSON marshaling using Avaje Jsonb/Jackson/Gson From 8771db71da37a00b29c60821abf5701f48690679 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 25 Jul 2023 23:26:06 +1200 Subject: [PATCH 0811/1323] Add io.avaje.validation.constraints.Valid to ValidPrism --- http-generator-core/pom.xml | 8 ++++++++ .../io/avaje/http/generator/core/ValidPrism.java | 12 +++++++++--- http-generator-core/src/main/java/module-info.java | 11 ++++++----- 3 files changed, 23 insertions(+), 8 deletions(-) diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 1ad4e98d1..3fc8d7b12 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -47,6 +47,14 @@ + + io.avaje + validator-constraints + 0.15 + true + provided + + jakarta.validation jakarta.validation-api diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ValidPrism.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ValidPrism.java index ccbb4bd1d..c9f6a4f26 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ValidPrism.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ValidPrism.java @@ -7,9 +7,13 @@ import io.avaje.prism.GeneratePrism; @GeneratePrism( - value = javax.validation.Valid.class, - name = "JavaxValidPrism", + value = io.avaje.validation.constraints.Valid.class, + name = "AvajeValidPrism", superInterfaces = ValidPrism.class) +@GeneratePrism( + value = javax.validation.Valid.class, + name = "JavaxValidPrism", + superInterfaces = ValidPrism.class) @GeneratePrism( value = jakarta.validation.Valid.class, name = "JakartaValidPrism", @@ -22,13 +26,15 @@ public interface ValidPrism { static Optional getOptionalOn(Element e) { return Optional.empty() + .or(() -> AvajeValidPrism.getOptionalOn(e)) .or(() -> HttpValidPrism.getOptionalOn(e)) .or(() -> JakartaValidPrism.getOptionalOn(e)) .or(() -> JavaxValidPrism.getOptionalOn(e)); } static boolean isPresent(Element e) { - return JakartaValidPrism.isPresent(e) + return AvajeValidPrism.isPresent(e) + || JakartaValidPrism.isPresent(e) || JavaxValidPrism.isPresent(e) || HttpValidPrism.isPresent(e); } diff --git a/http-generator-core/src/main/java/module-info.java b/http-generator-core/src/main/java/module-info.java index 0521e3adc..0d5787e3f 100644 --- a/http-generator-core/src/main/java/module-info.java +++ b/http-generator-core/src/main/java/module-info.java @@ -9,9 +9,10 @@ // SHADED: All content after this line will be removed at package time requires static io.avaje.prism; - requires static transitive io.avaje.http.api; - requires static transitive io.swagger.v3.oas.models; - requires static transitive io.swagger.v3.oas.annotations; - requires static transitive java.validation; - requires static transitive jakarta.validation; + requires static io.avaje.http.api; + requires static io.swagger.v3.oas.models; + requires static io.swagger.v3.oas.annotations; + requires static java.validation; + requires static jakarta.validation; + requires static io.avaje.validation.contraints; } From 236a21277fe605601f6f47ddc28130ca50bbf481 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Tue, 25 Jul 2023 21:15:54 -0400 Subject: [PATCH 0812/1323] add validation cause --- .../avaje/http/api/ValidationException.java | 50 ++++++++----------- .../http/generator/core/ElementReader.java | 4 +- 2 files changed, 25 insertions(+), 29 deletions(-) diff --git a/http-api/src/main/java/io/avaje/http/api/ValidationException.java b/http-api/src/main/java/io/avaje/http/api/ValidationException.java index 5139b6de3..60b4fb26c 100644 --- a/http-api/src/main/java/io/avaje/http/api/ValidationException.java +++ b/http-api/src/main/java/io/avaje/http/api/ValidationException.java @@ -4,68 +4,62 @@ /** * Exception used with Validator. - *

- * Typically this is used when validating a bean populated by request - * body content. - *

- * Generally this exception type is registered with an exception handler - * and configured to return a 422 or 400 http status response with the - * errors as a map of fields to error message. + * + *

Typically this is used when validating a bean populated by request body content. + * + *

Generally this exception type is registered with an exception handler and configured to return + * a 422 or 400 http status response with the errors as a map of fields to error message. */ public class ValidationException extends IllegalArgumentException { + private static final long serialVersionUID = 1L; + private int status = 422; private Map errors; - /** - * Create with a message. - */ + /** Create with a message. */ public ValidationException(String message) { super(message); } - /** - * Create with a status and message. - */ + /** Create with a status and message. */ public ValidationException(int status, String message) { super(message); this.status = status; } - /** - * Create with a status message and errors. - */ + /** Create with a status message and errors. */ public ValidationException(int status, String message, Map errors) { super(message); this.status = status; this.errors = errors; } - /** - * Return the suggested HTTP status to use in the response. - */ + /** Create with a status message and errors. */ + public ValidationException( + int status, String message, Throwable cause, Map errors) { + super(message, cause); + this.status = status; + this.errors = errors; + } + + /** Return the suggested HTTP status to use in the response. */ public int getStatus() { return status; } - /** - * Set the suggested HTTP status to use in the response. - */ + /** Set the suggested HTTP status to use in the response. */ public void setStatus(int status) { this.status = status; } - /** - * Return the errors typically as a map of field to error message. - */ + /** Return the errors typically as a map of field to error message. */ public Map getErrors() { return errors; } - /** - * Set the errors. - */ + /** Set the errors. */ public void setErrors(Map errors) { this.errors = errors; } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java index e537d4a7b..fef0c9494 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java @@ -283,8 +283,10 @@ void buildApiDocumentation(MethodDocBuilder methodDoc) { void writeValidate(Append writer) { if (!contextType && typeHandler == null) { if (useValidation) { - writer.append("validator.validate(%s, ", varName); + writer.append("var validLanguage = "); platform().writeAcceptLanguage(writer); + writer.append(";").eol(); + writer.append(" validator.validate(%s, validLanguage", varName); if (!validationGroups.isEmpty()) { validationGroups.forEach(g -> writer.append(", %s", Util.shortName(g))); From 9c59e38752cd7d991f648ae3225ec76a12fdf0df Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Tue, 25 Jul 2023 21:20:23 -0400 Subject: [PATCH 0813/1323] Update ElementReader.java --- .../main/java/io/avaje/http/generator/core/ElementReader.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java index fef0c9494..08575907b 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java @@ -288,9 +288,7 @@ void writeValidate(Append writer) { writer.append(";").eol(); writer.append(" validator.validate(%s, validLanguage", varName); - if (!validationGroups.isEmpty()) { - validationGroups.forEach(g -> writer.append(", %s", Util.shortName(g))); - } + validationGroups.forEach(g -> writer.append(", %s", Util.shortName(g))); writer.append(");").eol(); } else { From 268b2e0505c6e8327669cd29fe3cb21ceda6909e Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Tue, 25 Jul 2023 21:22:16 -0400 Subject: [PATCH 0814/1323] Update build.yml --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 46803152e..fe0c3516b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -10,7 +10,7 @@ jobs: strategy: fail-fast: false matrix: - java_version: [11, 17, 20] + java_version: [17, 20, 21] os: [ubuntu-latest] steps: From dc9be4195e40394feb2007b979aa5a2a0c8592bb Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Tue, 25 Jul 2023 21:22:51 -0400 Subject: [PATCH 0815/1323] Update build.yml --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index fe0c3516b..e8bba21d3 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -10,7 +10,7 @@ jobs: strategy: fail-fast: false matrix: - java_version: [17, 20, 21] + java_version: [17, 20] os: [ubuntu-latest] steps: From 9d2cb4a99ddfcf30b169d17adeedc569b8c93e09 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Wed, 26 Jul 2023 22:20:29 +1200 Subject: [PATCH 0816/1323] Nima - have validation Accept-Language helper method Plus use platform indent with validLanguage and validator() generated code --- .../io/avaje/http/api/ValidationException.java | 3 +-- .../avaje/http/generator/core/ElementReader.java | 10 ++++------ .../helidon/nima/ControllerMethodWriter.java | 1 - .../generator/helidon/nima/ControllerWriter.java | 14 ++++++++++++++ .../helidon/nima/NimaPlatformAdapter.java | 5 ++--- .../generator/javalin/ControllerMethodWriter.java | 3 +-- .../http/generator/jex/ControllerMethodWriter.java | 2 +- 7 files changed, 23 insertions(+), 15 deletions(-) diff --git a/http-api/src/main/java/io/avaje/http/api/ValidationException.java b/http-api/src/main/java/io/avaje/http/api/ValidationException.java index 60b4fb26c..e17b64e57 100644 --- a/http-api/src/main/java/io/avaje/http/api/ValidationException.java +++ b/http-api/src/main/java/io/avaje/http/api/ValidationException.java @@ -37,8 +37,7 @@ public ValidationException(int status, String message, Map error } /** Create with a status message and errors. */ - public ValidationException( - int status, String message, Throwable cause, Map errors) { + public ValidationException(int status, String message, Throwable cause, Map errors) { super(message, cause); this.status = status; this.errors = errors; diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java index 08575907b..b43e17d31 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java @@ -282,19 +282,17 @@ void buildApiDocumentation(MethodDocBuilder methodDoc) { void writeValidate(Append writer) { if (!contextType && typeHandler == null) { + final var indent = platform().indent(); if (useValidation) { - writer.append("var validLanguage = "); + writer.append("%s var validLanguage = ", indent); platform().writeAcceptLanguage(writer); writer.append(";").eol(); - writer.append(" validator.validate(%s, validLanguage", varName); - + writer.append("%s validator.validate(%s, validLanguage", indent, varName); validationGroups.forEach(g -> writer.append(", %s", Util.shortName(g))); - writer.append(");").eol(); } else { - writer.append("// no validation required on %s", varName).eol(); + writer.append("%s // no validation required on %s", indent, varName).eol(); } - writer.append(" "); } } diff --git a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java index 997cab3b1..4ee726117 100644 --- a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java +++ b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java @@ -76,7 +76,6 @@ void writeHandler(boolean requestScoped) { if (method.includeValidate()) { for (final MethodParam param : params) { - writer.append(" "); param.writeValidate(writer); } } diff --git a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java index cb3b06ae7..f9714633c 100644 --- a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java +++ b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java @@ -47,6 +47,9 @@ class ControllerWriter extends BaseControllerWriter { reader.addImportType("io.helidon.nima.webserver.http.ServerResponse"); reader.addImportType("io.helidon.nima.webserver.http.HttpService"); reader.addImportType("io.helidon.common.http.Http.Header"); + if (reader.isIncludeValidator()) { + reader.addImportType("io.helidon.common.http.Http"); + } } void write() { @@ -96,6 +99,11 @@ private void writeClassStart() { controllerName = "factory"; controllerType += Constants.FACTORY_SUFFIX; } + + if (reader.isIncludeValidator()) { + writer.append(" private static final Http.HeaderName HEADER_ACCEPT_LANGUAGE = Header.create(\"Accept-Language\");").eol(); + } + writer.append(" private final %s %s;", controllerType, controllerName).eol(); if (reader.isIncludeValidator()) { @@ -142,6 +150,12 @@ private void writeClassStart() { } } writer.append(" }").eol().eol(); + + if (reader.isIncludeValidator()) { + writer.append(" private String language(ServerRequest req) {").eol(); + writer.append(" return req.headers().first(HEADER_ACCEPT_LANGUAGE).orElse(null);").eol(); + writer.append(" }").eol().eol(); + } } private boolean isInputStream(String type) { diff --git a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/NimaPlatformAdapter.java b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/NimaPlatformAdapter.java index 82229d03a..08bf8173f 100644 --- a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/NimaPlatformAdapter.java +++ b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/NimaPlatformAdapter.java @@ -137,8 +137,7 @@ public void writeReadCollectionParameter(Append writer, ParamType paramType, Str } @Override - public void writeReadCollectionParameter( - Append writer, ParamType paramType, String paramName, List paramDefault) { + public void writeReadCollectionParameter(Append writer, ParamType paramType, String paramName, List paramDefault) { switch (paramType) { case QUERYPARAM: writer.append( @@ -162,6 +161,6 @@ public void writeReadCollectionParameter( @Override public void writeAcceptLanguage(Append writer) { - writer.append("req.headers().first(Header.create(\"%s\")).orElse(null)", Constants.ACCEPT_LANGUAGE); + writer.append("language(req)"); } } diff --git a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java index b7e6460dc..ea23b782a 100644 --- a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java +++ b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java @@ -46,13 +46,12 @@ void write(boolean requestScoped) { for (final MethodParam param : params) { param.writeCtxGet(writer, segments); } - writer.append(" "); if (method.includeValidate()) { for (final MethodParam param : params) { param.writeValidate(writer); } } - + writer.append(" "); if (!method.isVoid()) { writer.append("var result = "); } diff --git a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java index f73c42e24..bf2440ded 100644 --- a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java +++ b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java @@ -44,12 +44,12 @@ void write(boolean requestScoped) { for (MethodParam param : params) { param.writeCtxGet(writer, segments); } - writer.append(" "); if (method.includeValidate()) { for (MethodParam param : params) { param.writeValidate(writer); } } + writer.append(" "); if (!method.isVoid()) { writeContextReturn(); } From 4c2aaf332fa7f1f8cdc7c055968e7e0a1d01dd95 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Thu, 27 Jul 2023 08:56:50 +1200 Subject: [PATCH 0817/1323] Change ValidationException errors to be a List - This is effectively an API breaking change from Map -> List + explicit type - The ValidationException.Error type is fairly opinionated. If that doesn't match application requirements the error handler needs to obtain the cause and pull the constraint violation errors from that to build its error response payload message --- .../avaje/http/api/ValidationException.java | 64 +++++++++++++++++-- http-client/pom.xml | 8 +-- .../http/client/HelloControllerTest.java | 37 ++++------- .../org/example/github/RepoJsonAdapter.java | 2 +- .../org/example/webserver/ErrorResponse.java | 25 ++++++-- http-hibernate-validator/pom.xml | 6 +- .../hibernate/validator/BeanValidator.java | 25 ++++++-- tests/test-javalin-jsonb/pom.xml | 2 +- .../java/org/example/myapp/ErrorResponse.java | 25 ++++++-- .../example/myapp/HelloControllerTest.java | 12 ++-- tests/test-javalin/pom.xml | 2 +- .../java/org/example/myapp/ErrorResponse.java | 25 ++++++-- .../example/myapp/HelloControllerTest.java | 12 ++-- tests/test-jex/pom.xml | 2 +- .../java/org/example/web/ErrorResponse.java | 25 ++++++-- .../org/example/web/HelloControllerTest.java | 4 +- 16 files changed, 190 insertions(+), 86 deletions(-) diff --git a/http-api/src/main/java/io/avaje/http/api/ValidationException.java b/http-api/src/main/java/io/avaje/http/api/ValidationException.java index e17b64e57..ec5707705 100644 --- a/http-api/src/main/java/io/avaje/http/api/ValidationException.java +++ b/http-api/src/main/java/io/avaje/http/api/ValidationException.java @@ -1,6 +1,7 @@ package io.avaje.http.api; -import java.util.Map; +import java.util.ArrayList; +import java.util.List; /** * Exception used with Validator. @@ -8,7 +9,7 @@ *

Typically this is used when validating a bean populated by request body content. * *

Generally this exception type is registered with an exception handler and configured to return - * a 422 or 400 http status response with the errors as a map of fields to error message. + * a 422 or 400 http status response with the errors as a list of field error message. */ public class ValidationException extends IllegalArgumentException { @@ -16,28 +17,30 @@ public class ValidationException extends IllegalArgumentException { private int status = 422; - private Map errors; + private List errors; /** Create with a message. */ public ValidationException(String message) { super(message); + this.errors = new ArrayList<>(); } /** Create with a status and message. */ public ValidationException(int status, String message) { super(message); this.status = status; + this.errors = new ArrayList<>(); } /** Create with a status message and errors. */ - public ValidationException(int status, String message, Map errors) { + public ValidationException(int status, String message, List errors) { super(message); this.status = status; this.errors = errors; } /** Create with a status message and errors. */ - public ValidationException(int status, String message, Throwable cause, Map errors) { + public ValidationException(int status, String message, Throwable cause, List errors) { super(message, cause); this.status = status; this.errors = errors; @@ -54,12 +57,59 @@ public void setStatus(int status) { } /** Return the errors typically as a map of field to error message. */ - public Map getErrors() { + public List getErrors() { return errors; } /** Set the errors. */ - public void setErrors(Map errors) { + public void setErrors(List errors) { this.errors = errors; } + + /** Error details including the field, error message and path */ + public static class Error { + + protected String path; + protected String field; + protected String message; + + public Error(String path, String field, String message) { + this.path = path; + this.field = field; + this.message = message; + } + + public Error() { + } + + /** Return the path of this error message. */ + public String getPath() { + return path; + } + + /** Return the field for this error message. */ + public String getField() { + return field; + } + + /** Return the error message. */ + public String getMessage() { + return message; + } + + /** Set the path for this error. */ + public void setPath(String path) { + this.path = path; + } + + /** Set the field for this error. */ + public void setField(String field) { + this.field = field; + } + + /** Set the error message. */ + public void setMessage(String message) { + this.message = message; + } + } } diff --git a/http-client/pom.xml b/http-client/pom.xml index 11c7f7b51..7e5f1f58c 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -36,14 +36,14 @@ io.avaje avaje-jsonb - 1.4 + 1.7-RC1 true io.avaje avaje-inject - 9.0 + 9.4 true @@ -80,7 +80,7 @@ io.avaje avaje-http-hibernate-validator - 3.3 + 3.5-RC1 test @@ -106,7 +106,7 @@ io.avaje avaje-inject-generator - 9.0 + 9.4 diff --git a/http-client/src/test/java/io/avaje/http/client/HelloControllerTest.java b/http-client/src/test/java/io/avaje/http/client/HelloControllerTest.java index f33a2185b..a3b888401 100644 --- a/http-client/src/test/java/io/avaje/http/client/HelloControllerTest.java +++ b/http-client/src/test/java/io/avaje/http/client/HelloControllerTest.java @@ -516,8 +516,7 @@ void asPlainString_throwingHttpException() { // convert json error response body to a bean final ErrorResponse errorResponse = httpException.bean(ErrorResponse.class); - final Map errorMap = errorResponse.getErrors(); - assertThat(errorMap.get("email")).isEqualTo("must be a well-formed email address"); + assertThat(errorResponse.get("email")).isEqualTo("must be a well-formed email address"); } @Test @@ -535,8 +534,7 @@ void asString_readInvalidResponse() { final ErrorResponse errorResponse = clientContext.bodyAdapter() .beanReader(ErrorResponse.class).readBody(hres.body()); - final Map errorMap = errorResponse.getErrors(); - assertThat(errorMap.get("email")).isEqualTo("must be a well-formed email address"); + assertThat(errorResponse.get("email")).isEqualTo("must be a well-formed email address"); } @Test @@ -926,9 +924,8 @@ void async_whenComplete_throwingHttpException() { // convert json error response body to a bean final ErrorResponse errorResponse = httpException.bean(ErrorResponse.class); - final Map errorMap = errorResponse.getErrors(); - assertThat(errorMap.get("url")).isEqualTo("must be a valid URL"); - assertThat(errorMap.get("email")).isEqualTo("must be a well-formed email address"); + assertThat(errorResponse.get("url")).isEqualTo("must be a valid URL"); + assertThat(errorResponse.get("email")).isEqualTo("must be a well-formed email address"); }); try { @@ -1129,10 +1126,8 @@ void postForm_asVoid_invokesValidation_expect_badRequest_extractError() { assertEquals(422, httpResponse.statusCode()); final ErrorResponse errorResponse = e.bean(ErrorResponse.class); - - final Map errorMap = errorResponse.getErrors(); - assertThat(errorMap.get("url")).isEqualTo("must be a valid URL"); - assertThat(errorMap.get("name")).isEqualTo("must not be null"); + assertThat(errorResponse.get("url")).isEqualTo("must be a valid URL"); + assertThat(errorResponse.get("name")).isEqualTo("must not be null"); } } @@ -1158,9 +1153,8 @@ void asyncAsVoid_extractError() throws InterruptedException { assertEquals(422, httpResponse.statusCode()); final ErrorResponse errorResponse = cause.bean(ErrorResponse.class); - final Map errorMap = errorResponse.getErrors(); - assertThat(errorMap.get("url")).isEqualTo("must be a valid URL"); - assertThat(errorMap.get("name")).isEqualTo("must not be null"); + assertThat(errorResponse.get("url")).isEqualTo("must be a valid URL"); + assertThat(errorResponse.get("name")).isEqualTo("must not be null"); }); try { @@ -1193,9 +1187,8 @@ void callAsVoid_async_extractError() throws InterruptedException { assertEquals(422, httpResponse.statusCode()); final ErrorResponse errorResponse = cause.bean(ErrorResponse.class); - final Map errorMap = errorResponse.getErrors(); - assertThat(errorMap.get("url")).isEqualTo("must be a valid URL"); - assertThat(errorMap.get("name")).isEqualTo("must not be null"); + assertThat(errorResponse.get("url")).isEqualTo("must be a valid URL"); + assertThat(errorResponse.get("name")).isEqualTo("must not be null"); }); try { @@ -1224,9 +1217,8 @@ void callAsVoid_extractError() { assertEquals(422, httpResponse.statusCode()); final ErrorResponse errorResponse = e.bean(ErrorResponse.class); - final Map errorMap = errorResponse.getErrors(); - assertThat(errorMap.get("url")).isEqualTo("must be a valid URL"); - assertThat(errorMap.get("name")).isEqualTo("must not be null"); + assertThat(errorResponse.get("url")).isEqualTo("must be a valid URL"); + assertThat(errorResponse.get("name")).isEqualTo("must not be null"); } } @@ -1249,9 +1241,8 @@ void postForm_asBytes_validation_expect_badRequest_extractError() { assertEquals(422, httpResponse.statusCode()); final ErrorResponse errorResponse = e.bean(ErrorResponse.class); - final Map errorMap = errorResponse.getErrors(); - assertThat(errorMap.get("url")).isEqualTo("must be a valid URL"); - assertThat(errorMap.get("name")).isEqualTo("must not be null"); + assertThat(errorResponse.get("url")).isEqualTo("must be a valid URL"); + assertThat(errorResponse.get("name")).isEqualTo("must not be null"); String rawBody = e.bodyAsString(); assertThat(rawBody).contains("must be a valid URL"); diff --git a/http-client/src/test/java/org/example/github/RepoJsonAdapter.java b/http-client/src/test/java/org/example/github/RepoJsonAdapter.java index f6e87a548..788b9e752 100644 --- a/http-client/src/test/java/org/example/github/RepoJsonAdapter.java +++ b/http-client/src/test/java/org/example/github/RepoJsonAdapter.java @@ -10,7 +10,7 @@ import java.lang.invoke.MethodHandle; -public class RepoJsonAdapter extends JsonAdapter implements ViewBuilderAware { +public class RepoJsonAdapter implements JsonAdapter, ViewBuilderAware { // naming convention Match // id [long] name:id publicField diff --git a/http-client/src/test/java/org/example/webserver/ErrorResponse.java b/http-client/src/test/java/org/example/webserver/ErrorResponse.java index cf6a26845..b9714c757 100644 --- a/http-client/src/test/java/org/example/webserver/ErrorResponse.java +++ b/http-client/src/test/java/org/example/webserver/ErrorResponse.java @@ -1,13 +1,14 @@ package org.example.webserver; -import java.util.LinkedHashMap; -import java.util.Map; +import io.avaje.http.api.ValidationException; + +import java.util.*; public class ErrorResponse { private String message; - private Map errors = new LinkedHashMap<>(); + private List errors = new ArrayList<>(); public String getMessage() { return message; @@ -17,11 +18,25 @@ public void setMessage(String message) { this.message = message; } - public Map getErrors() { + public List getErrors() { return errors; } - public void setErrors(Map errors) { + public void setErrors(List errors) { this.errors = errors; } + + public String get(String field) { + return errorForField(field) + .map(ValidationException.Error::getMessage) + .orElseThrow(); + } + public Optional errorForField(String field) { + for (ValidationException.Error error : errors) { + if (field.equals(error.getField())) { + return Optional.of(error); + } + } + return Optional.empty(); + } } diff --git a/http-hibernate-validator/pom.xml b/http-hibernate-validator/pom.xml index 4a01e79f7..a8fc4ef92 100644 --- a/http-hibernate-validator/pom.xml +++ b/http-hibernate-validator/pom.xml @@ -5,12 +5,12 @@ io.avaje avaje-http-hibernate-validator - 3.3 + 3.5-RC1 org.avaje java11-oss - 3.9 + 3.10 @@ -36,7 +36,7 @@ io.avaje avaje-http-api - 1.45-SNAPSHOT + 2.0-RC1 provided diff --git a/http-hibernate-validator/src/main/java/io/avaje/http/hibernate/validator/BeanValidator.java b/http-hibernate-validator/src/main/java/io/avaje/http/hibernate/validator/BeanValidator.java index 5eca15e54..e93f88089 100644 --- a/http-hibernate-validator/src/main/java/io/avaje/http/hibernate/validator/BeanValidator.java +++ b/http-hibernate-validator/src/main/java/io/avaje/http/hibernate/validator/BeanValidator.java @@ -1,12 +1,11 @@ package io.avaje.http.hibernate.validator; -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.Set; +import java.util.*; import io.avaje.http.api.ValidationException; import io.avaje.http.api.Validator; import jakarta.validation.ConstraintViolation; +import jakarta.validation.ConstraintViolationException; import jakarta.validation.Validation; import jakarta.validation.ValidatorFactory; @@ -23,13 +22,25 @@ public void validate(Object bean, String acceptLanguage, Class... groups) thr } private void throwExceptionWith(Set> violations) { - final Map errors = new LinkedHashMap<>(); + List errors = new ArrayList<>(); + for (final ConstraintViolation violation : violations) { - final var path = violation.getPropertyPath(); + final var path = violation.getPropertyPath().toString(); + final var field = pathToField(path); final var message = violation.getMessage(); - errors.put(path.toString(), message); + errors.add(new ValidationException.Error(path, field, message)); } - throw new ValidationException(422, "Request failed validation", errors); + var cause = new ConstraintViolationException(violations); + throw new ValidationException(422, "Request failed validation", cause, errors); + } + + private String pathToField(String path) { + int pos = path.lastIndexOf('.'); + if (pos == -1) { + return path; + } else { + return path.substring(pos + 1); + } } } diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 9fc5b2a01..76d5b3aa8 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -53,7 +53,7 @@ io.avaje avaje-http-hibernate-validator - 3.3 + 3.5-RC1 diff --git a/tests/test-javalin-jsonb/src/test/java/org/example/myapp/ErrorResponse.java b/tests/test-javalin-jsonb/src/test/java/org/example/myapp/ErrorResponse.java index 75eadc95b..8c33487df 100644 --- a/tests/test-javalin-jsonb/src/test/java/org/example/myapp/ErrorResponse.java +++ b/tests/test-javalin-jsonb/src/test/java/org/example/myapp/ErrorResponse.java @@ -1,13 +1,14 @@ package org.example.myapp; -import java.util.LinkedHashMap; -import java.util.Map; +import io.avaje.http.api.ValidationException; + +import java.util.*; public class ErrorResponse { private String message; - private Map errors = new LinkedHashMap<>(); + private List errors = new ArrayList<>(); public String getMessage() { return message; @@ -17,11 +18,25 @@ public void setMessage(String message) { this.message = message; } - public Map getErrors() { + public List getErrors() { return errors; } - public void setErrors(Map errors) { + public void setErrors(List errors) { this.errors = errors; } + + public String get(String field) { + return errorForField(field) + .map(ValidationException.Error::getMessage) + .orElseThrow(); + } + public Optional errorForField(String field) { + for (ValidationException.Error error : errors) { + if (field.equals(error.getField())) { + return Optional.of(error); + } + } + return Optional.empty(); + } } diff --git a/tests/test-javalin-jsonb/src/test/java/org/example/myapp/HelloControllerTest.java b/tests/test-javalin-jsonb/src/test/java/org/example/myapp/HelloControllerTest.java index e0eabef84..37bb0d875 100644 --- a/tests/test-javalin-jsonb/src/test/java/org/example/myapp/HelloControllerTest.java +++ b/tests/test-javalin-jsonb/src/test/java/org/example/myapp/HelloControllerTest.java @@ -208,9 +208,8 @@ void postForm_validation_expect_badRequest() { assertNotNull(res); assertThat(res.getMessage()).contains("failed validation"); - final Map errors = res.getErrors(); - assertThat(errors.get("url")).isEqualTo("must be a valid URL"); - assertThat(errors.get("name")).isEqualTo("must not be null"); + assertThat(res.get("url")).isEqualTo("must be a valid URL"); + assertThat(res.get("name")).isEqualTo("must not be null"); try { client.request() @@ -228,11 +227,8 @@ void postForm_validation_expect_badRequest() { assertEquals(422, httpResponse.statusCode()); final ErrorResponse errorResponse = e.bean(ErrorResponse.class); - - final Map errorMap = errorResponse.getErrors(); - assertThat(errorMap.get("url")).isEqualTo("must be a valid URL"); - assertThat(errorMap.get("name")).isEqualTo("must not be null"); - + assertThat(errorResponse.get("url")).isEqualTo("must be a valid URL"); + assertThat(errorResponse.get("name")).isEqualTo("must not be null"); } } diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 6c22fc6b1..d5cc6a50b 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -58,7 +58,7 @@ io.avaje avaje-http-hibernate-validator - 3.3 + 3.5-RC1 diff --git a/tests/test-javalin/src/test/java/org/example/myapp/ErrorResponse.java b/tests/test-javalin/src/test/java/org/example/myapp/ErrorResponse.java index 75eadc95b..8c33487df 100644 --- a/tests/test-javalin/src/test/java/org/example/myapp/ErrorResponse.java +++ b/tests/test-javalin/src/test/java/org/example/myapp/ErrorResponse.java @@ -1,13 +1,14 @@ package org.example.myapp; -import java.util.LinkedHashMap; -import java.util.Map; +import io.avaje.http.api.ValidationException; + +import java.util.*; public class ErrorResponse { private String message; - private Map errors = new LinkedHashMap<>(); + private List errors = new ArrayList<>(); public String getMessage() { return message; @@ -17,11 +18,25 @@ public void setMessage(String message) { this.message = message; } - public Map getErrors() { + public List getErrors() { return errors; } - public void setErrors(Map errors) { + public void setErrors(List errors) { this.errors = errors; } + + public String get(String field) { + return errorForField(field) + .map(ValidationException.Error::getMessage) + .orElseThrow(); + } + public Optional errorForField(String field) { + for (ValidationException.Error error : errors) { + if (field.equals(error.getField())) { + return Optional.of(error); + } + } + return Optional.empty(); + } } diff --git a/tests/test-javalin/src/test/java/org/example/myapp/HelloControllerTest.java b/tests/test-javalin/src/test/java/org/example/myapp/HelloControllerTest.java index acc8b7309..a1d38a1ea 100644 --- a/tests/test-javalin/src/test/java/org/example/myapp/HelloControllerTest.java +++ b/tests/test-javalin/src/test/java/org/example/myapp/HelloControllerTest.java @@ -210,9 +210,8 @@ void postForm_validation_expect_badRequest() { assertNotNull(res); assertThat(res.getMessage()).contains("failed validation"); - final Map errors = res.getErrors(); - assertThat(errors.get("url")).isEqualTo("must be a valid URL"); - assertThat(errors.get("name")).isEqualTo("must not be null"); + assertThat(res.get("url")).isEqualTo("must be a valid URL"); + assertThat(res.get("name")).isEqualTo("must not be null"); try { client.request() @@ -230,11 +229,8 @@ void postForm_validation_expect_badRequest() { assertEquals(422, httpResponse.statusCode()); final ErrorResponse errorResponse = e.bean(ErrorResponse.class); - - final Map errorMap = errorResponse.getErrors(); - assertThat(errorMap.get("url")).isEqualTo("must be a valid URL"); - assertThat(errorMap.get("name")).isEqualTo("must not be null"); - + assertThat(errorResponse.get("url")).isEqualTo("must be a valid URL"); + assertThat(errorResponse.get("name")).isEqualTo("must not be null"); } } diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 0eaac75f9..e09730e76 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -57,7 +57,7 @@ io.avaje avaje-http-hibernate-validator - 3.3 + 3.5-RC1 diff --git a/tests/test-jex/src/test/java/org/example/web/ErrorResponse.java b/tests/test-jex/src/test/java/org/example/web/ErrorResponse.java index f59f2ee3f..f1399a9cc 100644 --- a/tests/test-jex/src/test/java/org/example/web/ErrorResponse.java +++ b/tests/test-jex/src/test/java/org/example/web/ErrorResponse.java @@ -1,13 +1,14 @@ package org.example.web; -import java.util.LinkedHashMap; -import java.util.Map; +import io.avaje.http.api.ValidationException; + +import java.util.*; public class ErrorResponse { private String message; - private Map errors = new LinkedHashMap<>(); + private List errors = new ArrayList<>(); public String getMessage() { return message; @@ -17,11 +18,25 @@ public void setMessage(String message) { this.message = message; } - public Map getErrors() { + public List getErrors() { return errors; } - public void setErrors(Map errors) { + public void setErrors(List errors) { this.errors = errors; } + + public String get(String field) { + return errorForField(field) + .map(ValidationException.Error::getMessage) + .orElseThrow(); + } + public Optional errorForField(String field) { + for (ValidationException.Error error : errors) { + if (field.equals(error.getField())) { + return Optional.of(error); + } + } + return Optional.empty(); + } } diff --git a/tests/test-jex/src/test/java/org/example/web/HelloControllerTest.java b/tests/test-jex/src/test/java/org/example/web/HelloControllerTest.java index 9bba2f034..2493abbf5 100644 --- a/tests/test-jex/src/test/java/org/example/web/HelloControllerTest.java +++ b/tests/test-jex/src/test/java/org/example/web/HelloControllerTest.java @@ -63,7 +63,7 @@ void validation() { .PUT().asString(); assertThat(hres.statusCode()).isEqualTo(422); - assertThat(hres.body()).contains("{\"name\":\"must not be null\"}"); + assertThat(hres.body()).contains("{\"path\":\"name\",\"field\":\"name\",\"message\":\"must not be null\"}"); } @Test @@ -79,6 +79,6 @@ void validation_expect_HttpException() { assertThat(ex.statusCode()).isEqualTo(422); final ErrorResponse errBean = ex.bean(ErrorResponse.class); - assertThat(errBean.getErrors().get("name")).isEqualTo("must not be null"); + assertThat(errBean.get("name")).isEqualTo("must not be null"); } } From 4c30b6aca612c3ea864480e4431599216bc59d13 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Thu, 27 Jul 2023 09:20:41 +1200 Subject: [PATCH 0818/1323] Change ValidationException.Error -> ViolationMessage --- .../io/avaje/http/api/ValidationException.java | 16 ++++++++-------- http-client/pom.xml | 2 +- .../org/example/webserver/ErrorResponse.java | 12 ++++++------ http-hibernate-validator/pom.xml | 2 +- .../http/hibernate/validator/BeanValidator.java | 5 +++-- tests/test-javalin-jsonb/pom.xml | 2 +- .../java/org/example/myapp/ErrorResponse.java | 12 ++++++------ tests/test-javalin/pom.xml | 2 +- .../java/org/example/myapp/ErrorResponse.java | 12 ++++++------ tests/test-jex/pom.xml | 2 +- .../test/java/org/example/web/ErrorResponse.java | 12 ++++++------ 11 files changed, 40 insertions(+), 39 deletions(-) diff --git a/http-api/src/main/java/io/avaje/http/api/ValidationException.java b/http-api/src/main/java/io/avaje/http/api/ValidationException.java index ec5707705..137fe1622 100644 --- a/http-api/src/main/java/io/avaje/http/api/ValidationException.java +++ b/http-api/src/main/java/io/avaje/http/api/ValidationException.java @@ -17,7 +17,7 @@ public class ValidationException extends IllegalArgumentException { private int status = 422; - private List errors; + private List errors; /** Create with a message. */ public ValidationException(String message) { @@ -33,14 +33,14 @@ public ValidationException(int status, String message) { } /** Create with a status message and errors. */ - public ValidationException(int status, String message, List errors) { + public ValidationException(int status, String message, List errors) { super(message); this.status = status; this.errors = errors; } /** Create with a status message and errors. */ - public ValidationException(int status, String message, Throwable cause, List errors) { + public ValidationException(int status, String message, Throwable cause, List errors) { super(message, cause); this.status = status; this.errors = errors; @@ -57,29 +57,29 @@ public void setStatus(int status) { } /** Return the errors typically as a map of field to error message. */ - public List getErrors() { + public List getErrors() { return errors; } /** Set the errors. */ - public void setErrors(List errors) { + public void setErrors(List errors) { this.errors = errors; } /** Error details including the field, error message and path */ - public static class Error { + public static class ViolationMessage { protected String path; protected String field; protected String message; - public Error(String path, String field, String message) { + public ViolationMessage(String path, String field, String message) { this.path = path; this.field = field; this.message = message; } - public Error() { + public ViolationMessage() { } /** Return the path of this error message. */ diff --git a/http-client/pom.xml b/http-client/pom.xml index 7e5f1f58c..e30929289 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -80,7 +80,7 @@ io.avaje avaje-http-hibernate-validator - 3.5-RC1 + 3.5-RC2 test diff --git a/http-client/src/test/java/org/example/webserver/ErrorResponse.java b/http-client/src/test/java/org/example/webserver/ErrorResponse.java index b9714c757..6714c89a5 100644 --- a/http-client/src/test/java/org/example/webserver/ErrorResponse.java +++ b/http-client/src/test/java/org/example/webserver/ErrorResponse.java @@ -8,7 +8,7 @@ public class ErrorResponse { private String message; - private List errors = new ArrayList<>(); + private List errors = new ArrayList<>(); public String getMessage() { return message; @@ -18,21 +18,21 @@ public void setMessage(String message) { this.message = message; } - public List getErrors() { + public List getErrors() { return errors; } - public void setErrors(List errors) { + public void setErrors(List errors) { this.errors = errors; } public String get(String field) { return errorForField(field) - .map(ValidationException.Error::getMessage) + .map(ValidationException.ViolationMessage::getMessage) .orElseThrow(); } - public Optional errorForField(String field) { - for (ValidationException.Error error : errors) { + public Optional errorForField(String field) { + for (ValidationException.ViolationMessage error : errors) { if (field.equals(error.getField())) { return Optional.of(error); } diff --git a/http-hibernate-validator/pom.xml b/http-hibernate-validator/pom.xml index a8fc4ef92..c7f8c9cbb 100644 --- a/http-hibernate-validator/pom.xml +++ b/http-hibernate-validator/pom.xml @@ -5,7 +5,7 @@ io.avaje avaje-http-hibernate-validator - 3.5-RC1 + 3.5-RC2 org.avaje diff --git a/http-hibernate-validator/src/main/java/io/avaje/http/hibernate/validator/BeanValidator.java b/http-hibernate-validator/src/main/java/io/avaje/http/hibernate/validator/BeanValidator.java index e93f88089..4b7016ae9 100644 --- a/http-hibernate-validator/src/main/java/io/avaje/http/hibernate/validator/BeanValidator.java +++ b/http-hibernate-validator/src/main/java/io/avaje/http/hibernate/validator/BeanValidator.java @@ -3,6 +3,7 @@ import java.util.*; import io.avaje.http.api.ValidationException; +import io.avaje.http.api.ValidationException.ViolationMessage; import io.avaje.http.api.Validator; import jakarta.validation.ConstraintViolation; import jakarta.validation.ConstraintViolationException; @@ -22,13 +23,13 @@ public void validate(Object bean, String acceptLanguage, Class... groups) thr } private void throwExceptionWith(Set> violations) { - List errors = new ArrayList<>(); + List errors = new ArrayList<>(); for (final ConstraintViolation violation : violations) { final var path = violation.getPropertyPath().toString(); final var field = pathToField(path); final var message = violation.getMessage(); - errors.add(new ValidationException.Error(path, field, message)); + errors.add(new ViolationMessage(path, field, message)); } var cause = new ConstraintViolationException(violations); diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 76d5b3aa8..bb1b8f19d 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -53,7 +53,7 @@ io.avaje avaje-http-hibernate-validator - 3.5-RC1 + 3.5-RC2 diff --git a/tests/test-javalin-jsonb/src/test/java/org/example/myapp/ErrorResponse.java b/tests/test-javalin-jsonb/src/test/java/org/example/myapp/ErrorResponse.java index 8c33487df..e86ed8851 100644 --- a/tests/test-javalin-jsonb/src/test/java/org/example/myapp/ErrorResponse.java +++ b/tests/test-javalin-jsonb/src/test/java/org/example/myapp/ErrorResponse.java @@ -8,7 +8,7 @@ public class ErrorResponse { private String message; - private List errors = new ArrayList<>(); + private List errors = new ArrayList<>(); public String getMessage() { return message; @@ -18,21 +18,21 @@ public void setMessage(String message) { this.message = message; } - public List getErrors() { + public List getErrors() { return errors; } - public void setErrors(List errors) { + public void setErrors(List errors) { this.errors = errors; } public String get(String field) { return errorForField(field) - .map(ValidationException.Error::getMessage) + .map(ValidationException.ViolationMessage::getMessage) .orElseThrow(); } - public Optional errorForField(String field) { - for (ValidationException.Error error : errors) { + public Optional errorForField(String field) { + for (ValidationException.ViolationMessage error : errors) { if (field.equals(error.getField())) { return Optional.of(error); } diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index d5cc6a50b..0e85256f0 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -58,7 +58,7 @@ io.avaje avaje-http-hibernate-validator - 3.5-RC1 + 3.5-RC2 diff --git a/tests/test-javalin/src/test/java/org/example/myapp/ErrorResponse.java b/tests/test-javalin/src/test/java/org/example/myapp/ErrorResponse.java index 8c33487df..e86ed8851 100644 --- a/tests/test-javalin/src/test/java/org/example/myapp/ErrorResponse.java +++ b/tests/test-javalin/src/test/java/org/example/myapp/ErrorResponse.java @@ -8,7 +8,7 @@ public class ErrorResponse { private String message; - private List errors = new ArrayList<>(); + private List errors = new ArrayList<>(); public String getMessage() { return message; @@ -18,21 +18,21 @@ public void setMessage(String message) { this.message = message; } - public List getErrors() { + public List getErrors() { return errors; } - public void setErrors(List errors) { + public void setErrors(List errors) { this.errors = errors; } public String get(String field) { return errorForField(field) - .map(ValidationException.Error::getMessage) + .map(ValidationException.ViolationMessage::getMessage) .orElseThrow(); } - public Optional errorForField(String field) { - for (ValidationException.Error error : errors) { + public Optional errorForField(String field) { + for (ValidationException.ViolationMessage error : errors) { if (field.equals(error.getField())) { return Optional.of(error); } diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index e09730e76..25d40715e 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -57,7 +57,7 @@ io.avaje avaje-http-hibernate-validator - 3.5-RC1 + 3.5-RC2 diff --git a/tests/test-jex/src/test/java/org/example/web/ErrorResponse.java b/tests/test-jex/src/test/java/org/example/web/ErrorResponse.java index f1399a9cc..4d0d2b7ad 100644 --- a/tests/test-jex/src/test/java/org/example/web/ErrorResponse.java +++ b/tests/test-jex/src/test/java/org/example/web/ErrorResponse.java @@ -8,7 +8,7 @@ public class ErrorResponse { private String message; - private List errors = new ArrayList<>(); + private List errors = new ArrayList<>(); public String getMessage() { return message; @@ -18,21 +18,21 @@ public void setMessage(String message) { this.message = message; } - public List getErrors() { + public List getErrors() { return errors; } - public void setErrors(List errors) { + public void setErrors(List errors) { this.errors = errors; } public String get(String field) { return errorForField(field) - .map(ValidationException.Error::getMessage) + .map(ValidationException.ViolationMessage::getMessage) .orElseThrow(); } - public Optional errorForField(String field) { - for (ValidationException.Error error : errors) { + public Optional errorForField(String field) { + for (ValidationException.ViolationMessage error : errors) { if (field.equals(error.getField())) { return Optional.of(error); } From 0b7da75d3e9696fd43548483f05fb0ef183fcb93 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Thu, 27 Jul 2023 10:20:09 +1200 Subject: [PATCH 0819/1323] Rename ValidationException ViolationMessage -> Violation --- .../io/avaje/http/api/ValidationException.java | 16 ++++++++-------- http-client/pom.xml | 2 +- .../org/example/webserver/ErrorResponse.java | 12 ++++++------ http-hibernate-validator/pom.xml | 2 +- .../http/hibernate/validator/BeanValidator.java | 6 +++--- tests/test-javalin-jsonb/pom.xml | 2 +- .../java/org/example/myapp/ErrorResponse.java | 12 ++++++------ tests/test-javalin/pom.xml | 2 +- .../java/org/example/myapp/ErrorResponse.java | 12 ++++++------ tests/test-jex/pom.xml | 2 +- .../test/java/org/example/web/ErrorResponse.java | 12 ++++++------ 11 files changed, 40 insertions(+), 40 deletions(-) diff --git a/http-api/src/main/java/io/avaje/http/api/ValidationException.java b/http-api/src/main/java/io/avaje/http/api/ValidationException.java index 137fe1622..6da976a53 100644 --- a/http-api/src/main/java/io/avaje/http/api/ValidationException.java +++ b/http-api/src/main/java/io/avaje/http/api/ValidationException.java @@ -17,7 +17,7 @@ public class ValidationException extends IllegalArgumentException { private int status = 422; - private List errors; + private List errors; /** Create with a message. */ public ValidationException(String message) { @@ -33,14 +33,14 @@ public ValidationException(int status, String message) { } /** Create with a status message and errors. */ - public ValidationException(int status, String message, List errors) { + public ValidationException(int status, String message, List errors) { super(message); this.status = status; this.errors = errors; } /** Create with a status message and errors. */ - public ValidationException(int status, String message, Throwable cause, List errors) { + public ValidationException(int status, String message, Throwable cause, List errors) { super(message, cause); this.status = status; this.errors = errors; @@ -57,29 +57,29 @@ public void setStatus(int status) { } /** Return the errors typically as a map of field to error message. */ - public List getErrors() { + public List getErrors() { return errors; } /** Set the errors. */ - public void setErrors(List errors) { + public void setErrors(List errors) { this.errors = errors; } /** Error details including the field, error message and path */ - public static class ViolationMessage { + public static class Violation { protected String path; protected String field; protected String message; - public ViolationMessage(String path, String field, String message) { + public Violation(String path, String field, String message) { this.path = path; this.field = field; this.message = message; } - public ViolationMessage() { + public Violation() { } /** Return the path of this error message. */ diff --git a/http-client/pom.xml b/http-client/pom.xml index e30929289..fa44331fb 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -80,7 +80,7 @@ io.avaje avaje-http-hibernate-validator - 3.5-RC2 + 3.5-RC3 test diff --git a/http-client/src/test/java/org/example/webserver/ErrorResponse.java b/http-client/src/test/java/org/example/webserver/ErrorResponse.java index 6714c89a5..02a22ec6e 100644 --- a/http-client/src/test/java/org/example/webserver/ErrorResponse.java +++ b/http-client/src/test/java/org/example/webserver/ErrorResponse.java @@ -8,7 +8,7 @@ public class ErrorResponse { private String message; - private List errors = new ArrayList<>(); + private List errors = new ArrayList<>(); public String getMessage() { return message; @@ -18,21 +18,21 @@ public void setMessage(String message) { this.message = message; } - public List getErrors() { + public List getErrors() { return errors; } - public void setErrors(List errors) { + public void setErrors(List errors) { this.errors = errors; } public String get(String field) { return errorForField(field) - .map(ValidationException.ViolationMessage::getMessage) + .map(ValidationException.Violation::getMessage) .orElseThrow(); } - public Optional errorForField(String field) { - for (ValidationException.ViolationMessage error : errors) { + public Optional errorForField(String field) { + for (ValidationException.Violation error : errors) { if (field.equals(error.getField())) { return Optional.of(error); } diff --git a/http-hibernate-validator/pom.xml b/http-hibernate-validator/pom.xml index c7f8c9cbb..2990065c8 100644 --- a/http-hibernate-validator/pom.xml +++ b/http-hibernate-validator/pom.xml @@ -5,7 +5,7 @@ io.avaje avaje-http-hibernate-validator - 3.5-RC2 + 3.5-RC3 org.avaje diff --git a/http-hibernate-validator/src/main/java/io/avaje/http/hibernate/validator/BeanValidator.java b/http-hibernate-validator/src/main/java/io/avaje/http/hibernate/validator/BeanValidator.java index 4b7016ae9..9a5ffa620 100644 --- a/http-hibernate-validator/src/main/java/io/avaje/http/hibernate/validator/BeanValidator.java +++ b/http-hibernate-validator/src/main/java/io/avaje/http/hibernate/validator/BeanValidator.java @@ -3,7 +3,7 @@ import java.util.*; import io.avaje.http.api.ValidationException; -import io.avaje.http.api.ValidationException.ViolationMessage; +import io.avaje.http.api.ValidationException.Violation; import io.avaje.http.api.Validator; import jakarta.validation.ConstraintViolation; import jakarta.validation.ConstraintViolationException; @@ -23,13 +23,13 @@ public void validate(Object bean, String acceptLanguage, Class... groups) thr } private void throwExceptionWith(Set> violations) { - List errors = new ArrayList<>(); + List errors = new ArrayList<>(); for (final ConstraintViolation violation : violations) { final var path = violation.getPropertyPath().toString(); final var field = pathToField(path); final var message = violation.getMessage(); - errors.add(new ViolationMessage(path, field, message)); + errors.add(new Violation(path, field, message)); } var cause = new ConstraintViolationException(violations); diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index bb1b8f19d..17a5c0609 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -53,7 +53,7 @@ io.avaje avaje-http-hibernate-validator - 3.5-RC2 + 3.5-RC3 diff --git a/tests/test-javalin-jsonb/src/test/java/org/example/myapp/ErrorResponse.java b/tests/test-javalin-jsonb/src/test/java/org/example/myapp/ErrorResponse.java index e86ed8851..3a5ebbea7 100644 --- a/tests/test-javalin-jsonb/src/test/java/org/example/myapp/ErrorResponse.java +++ b/tests/test-javalin-jsonb/src/test/java/org/example/myapp/ErrorResponse.java @@ -8,7 +8,7 @@ public class ErrorResponse { private String message; - private List errors = new ArrayList<>(); + private List errors = new ArrayList<>(); public String getMessage() { return message; @@ -18,21 +18,21 @@ public void setMessage(String message) { this.message = message; } - public List getErrors() { + public List getErrors() { return errors; } - public void setErrors(List errors) { + public void setErrors(List errors) { this.errors = errors; } public String get(String field) { return errorForField(field) - .map(ValidationException.ViolationMessage::getMessage) + .map(ValidationException.Violation::getMessage) .orElseThrow(); } - public Optional errorForField(String field) { - for (ValidationException.ViolationMessage error : errors) { + public Optional errorForField(String field) { + for (ValidationException.Violation error : errors) { if (field.equals(error.getField())) { return Optional.of(error); } diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 0e85256f0..20fe3d95d 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -58,7 +58,7 @@ io.avaje avaje-http-hibernate-validator - 3.5-RC2 + 3.5-RC3 diff --git a/tests/test-javalin/src/test/java/org/example/myapp/ErrorResponse.java b/tests/test-javalin/src/test/java/org/example/myapp/ErrorResponse.java index e86ed8851..3a5ebbea7 100644 --- a/tests/test-javalin/src/test/java/org/example/myapp/ErrorResponse.java +++ b/tests/test-javalin/src/test/java/org/example/myapp/ErrorResponse.java @@ -8,7 +8,7 @@ public class ErrorResponse { private String message; - private List errors = new ArrayList<>(); + private List errors = new ArrayList<>(); public String getMessage() { return message; @@ -18,21 +18,21 @@ public void setMessage(String message) { this.message = message; } - public List getErrors() { + public List getErrors() { return errors; } - public void setErrors(List errors) { + public void setErrors(List errors) { this.errors = errors; } public String get(String field) { return errorForField(field) - .map(ValidationException.ViolationMessage::getMessage) + .map(ValidationException.Violation::getMessage) .orElseThrow(); } - public Optional errorForField(String field) { - for (ValidationException.ViolationMessage error : errors) { + public Optional errorForField(String field) { + for (ValidationException.Violation error : errors) { if (field.equals(error.getField())) { return Optional.of(error); } diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 25d40715e..d80b9441b 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -57,7 +57,7 @@ io.avaje avaje-http-hibernate-validator - 3.5-RC2 + 3.5-RC3 diff --git a/tests/test-jex/src/test/java/org/example/web/ErrorResponse.java b/tests/test-jex/src/test/java/org/example/web/ErrorResponse.java index 4d0d2b7ad..97f70e8d7 100644 --- a/tests/test-jex/src/test/java/org/example/web/ErrorResponse.java +++ b/tests/test-jex/src/test/java/org/example/web/ErrorResponse.java @@ -8,7 +8,7 @@ public class ErrorResponse { private String message; - private List errors = new ArrayList<>(); + private List errors = new ArrayList<>(); public String getMessage() { return message; @@ -18,21 +18,21 @@ public void setMessage(String message) { this.message = message; } - public List getErrors() { + public List getErrors() { return errors; } - public void setErrors(List errors) { + public void setErrors(List errors) { this.errors = errors; } public String get(String field) { return errorForField(field) - .map(ValidationException.ViolationMessage::getMessage) + .map(ValidationException.Violation::getMessage) .orElseThrow(); } - public Optional errorForField(String field) { - for (ValidationException.ViolationMessage error : errors) { + public Optional errorForField(String field) { + for (ValidationException.Violation error : errors) { if (field.equals(error.getField())) { return Optional.of(error); } From e4fa17db747d482b9bd12f2794965d3452dc2803 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Thu, 27 Jul 2023 12:34:23 +1200 Subject: [PATCH 0820/1323] Version 2.0-RC2 --- http-api/pom.xml | 2 +- .../src/main/java/io/avaje/http/api/ValidationException.java | 2 ++ http-client-gson-adapter/pom.xml | 4 ++-- http-client/pom.xml | 2 +- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 2 +- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-inject-plugin/pom.xml | 2 +- pom.xml | 2 +- tests/pom.xml | 2 +- tests/test-client-generation/pom.xml | 2 +- tests/test-client/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- 19 files changed, 21 insertions(+), 19 deletions(-) diff --git a/http-api/pom.xml b/http-api/pom.xml index 20750789d..66f7bcc71 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC1 + 2.0-RC2 .. diff --git a/http-api/src/main/java/io/avaje/http/api/ValidationException.java b/http-api/src/main/java/io/avaje/http/api/ValidationException.java index 6da976a53..9a41de3e1 100644 --- a/http-api/src/main/java/io/avaje/http/api/ValidationException.java +++ b/http-api/src/main/java/io/avaje/http/api/ValidationException.java @@ -73,12 +73,14 @@ public static class Violation { protected String field; protected String message; + /** Create with path, field and message */ public Violation(String path, String field, String message) { this.path = path; this.field = field; this.message = message; } + /** Default constructor just to help Jackson if it is used. */ public Violation() { } diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index 6c97bc449..3b42beba6 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC1 + 2.0-RC2 avaje-http-client-gson @@ -20,7 +20,7 @@ io.avaje avaje-http-client - 2.0-RC1 + 2.0-RC2 provided diff --git a/http-client/pom.xml b/http-client/pom.xml index fa44331fb..ad405d388 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC1 + 2.0-RC2 avaje-http-client diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index caa827f6c..8af743164 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC1 + 2.0-RC2 avaje-http-client-generator diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 3fc8d7b12..9888296d0 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC1 + 2.0-RC2 avaje-http-generator-core diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index f7be6bef1..c561bfd9f 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.0-RC1 + 2.0-RC2 avaje-http-helidon-generator diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index 706959d19..f05885e46 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC1 + 2.0-RC2 avaje-http-javalin-generator diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index ca47c886c..386a1b8a4 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC1 + 2.0-RC2 avaje-http-jex-generator diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index 16246b28d..e6ba0ea62 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC1 + 2.0-RC2 .. diff --git a/pom.xml b/pom.xml index eddd479a0..0ff4d9595 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-parent - 2.0-RC1 + 2.0-RC2 pom diff --git a/tests/pom.xml b/tests/pom.xml index e12f789ae..53b52e07b 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.0-RC1 + 2.0-RC2 tests diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index b234ca7d1..fb3deb260 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.0-RC1 + 2.0-RC2 test-client-generation diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index a5bcedc7f..9ba9ca09e 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.0-RC1 + 2.0-RC2 test-client diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 17a5c0609..cef517356 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 2.0-RC1 + 2.0-RC2 test-javalin-jsonb diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 20fe3d95d..e0e8fb671 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.0-RC1 + 2.0-RC2 test-javalin diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index d80b9441b..e9dd780e5 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.0-RC1 + 2.0-RC2 test-jex diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 5d9674e1a..d76e2f3fe 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.0-RC1 + 2.0-RC2 test-nima-jsonb diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index 494bca7e7..b1d67572d 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.0-RC1 + 2.0-RC2 test-nima From f97fcdd6724552c81afd53fe8cc31cc068ade0e3 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Thu, 27 Jul 2023 22:22:20 +1200 Subject: [PATCH 0821/1323] ValidationException List -> List --- .../java/io/avaje/http/api/ValidationException.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/http-api/src/main/java/io/avaje/http/api/ValidationException.java b/http-api/src/main/java/io/avaje/http/api/ValidationException.java index 9a41de3e1..dbf352006 100644 --- a/http-api/src/main/java/io/avaje/http/api/ValidationException.java +++ b/http-api/src/main/java/io/avaje/http/api/ValidationException.java @@ -17,7 +17,7 @@ public class ValidationException extends IllegalArgumentException { private int status = 422; - private List errors; + private List errors; /** Create with a message. */ public ValidationException(String message) { @@ -33,14 +33,14 @@ public ValidationException(int status, String message) { } /** Create with a status message and errors. */ - public ValidationException(int status, String message, List errors) { + public ValidationException(int status, String message, List errors) { super(message); this.status = status; this.errors = errors; } /** Create with a status message and errors. */ - public ValidationException(int status, String message, Throwable cause, List errors) { + public ValidationException(int status, String message, Throwable cause, List errors) { super(message, cause); this.status = status; this.errors = errors; @@ -57,12 +57,12 @@ public void setStatus(int status) { } /** Return the errors typically as a map of field to error message. */ - public List getErrors() { + public List getErrors() { return errors; } /** Set the errors. */ - public void setErrors(List errors) { + public void setErrors(List errors) { this.errors = errors; } From f737df2dce0aed2abb97d69ceb771816cc545f75 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sat, 29 Jul 2023 01:34:35 -0400 Subject: [PATCH 0822/1323] use javalin plugins --- .../java/io/avaje/http/api/WebRoutes.java | 15 --- http-client/pom.xml | 2 +- .../test/java/org/example/webserver/App.java | 89 +++++++++-------- .../webserver/HelloController$Route.java | 83 ++++++++-------- .../javalin/ControllerMethodWriter.java | 2 +- .../generator/javalin/ControllerWriter.java | 12 +-- .../src/main/java/org/example/myapp/Main.java | 43 +++++---- .../src/main/java/org/example/myapp/Main.java | 95 ++++++++++--------- 8 files changed, 171 insertions(+), 170 deletions(-) delete mode 100644 http-api/src/main/java/io/avaje/http/api/WebRoutes.java diff --git a/http-api/src/main/java/io/avaje/http/api/WebRoutes.java b/http-api/src/main/java/io/avaje/http/api/WebRoutes.java deleted file mode 100644 index b497044a3..000000000 --- a/http-api/src/main/java/io/avaje/http/api/WebRoutes.java +++ /dev/null @@ -1,15 +0,0 @@ -package io.avaje.http.api; - -/** - * Registers routes to a web framework. - *

- * Implementations can be generated by APT processing adapting web route requests - * to controller methods. - */ -public interface WebRoutes { - - /** - * Register routes. - */ - void registerRoutes(); -} diff --git a/http-client/pom.xml b/http-client/pom.xml index ad405d388..38552c34a 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -66,7 +66,7 @@ io.javalin javalin - 5.2.0 + 5.6.1 test diff --git a/http-client/src/test/java/org/example/webserver/App.java b/http-client/src/test/java/org/example/webserver/App.java index 5517f7e28..2c4972e9d 100644 --- a/http-client/src/test/java/org/example/webserver/App.java +++ b/http-client/src/test/java/org/example/webserver/App.java @@ -20,41 +20,50 @@ public static void main(String[] args) { } public static Javalin start(int port) { - - Javalin app = Javalin.create(config -> { - config.showJavalinBanner = false; - config.accessManager((handler, ctx, permittedRoles) -> { - log.debug("allow access ..."); - handler.handle(ctx); - }); - }); - - app.exception(ValidationException.class, (exception, ctx) -> { - - Map map = new LinkedHashMap<>(); - map.put("message", exception.getMessage()); - map.put("errors", exception.getErrors()); - ctx.status(exception.getStatus()); - ctx.json(map); - }); - - app.exception(InvalidTypeArgumentException.class, (exception, ctx) -> { - - Map map = new LinkedHashMap<>(); - map.put("path", ctx.path()); - map.put("message", "invalid type argument"); - ctx.status(400); - ctx.json(map); - }); - - app.exception(InvalidPathArgumentException.class, (exception, ctx) -> { - - Map map = new LinkedHashMap<>(); - map.put("path", ctx.path()); - map.put("message", "invalid path argument"); - ctx.status(404); - ctx.json(map); - }); + HelloController$Route bean = + new HelloController$Route(new HelloController(), new BeanValidator()); + + Javalin app = + Javalin.create( + config -> { + config.showJavalinBanner = false; + config.accessManager( + (handler, ctx, permittedRoles) -> { + log.debug("allow access ..."); + handler.handle(ctx); + }); + config.plugins.register(bean); + }); + + app.exception( + ValidationException.class, + (exception, ctx) -> { + Map map = new LinkedHashMap<>(); + map.put("message", exception.getMessage()); + map.put("errors", exception.getErrors()); + ctx.status(exception.getStatus()); + ctx.json(map); + }); + + app.exception( + InvalidTypeArgumentException.class, + (exception, ctx) -> { + Map map = new LinkedHashMap<>(); + map.put("path", ctx.path()); + map.put("message", "invalid type argument"); + ctx.status(400); + ctx.json(map); + }); + + app.exception( + InvalidPathArgumentException.class, + (exception, ctx) -> { + Map map = new LinkedHashMap<>(); + map.put("path", ctx.path()); + map.put("message", "invalid path argument"); + ctx.status(404); + ctx.json(map); + }); app.get("/", ctx -> ctx.result("Hello World")); app.head("/head", ctx -> ctx.result("head")); @@ -62,16 +71,14 @@ public static Javalin start(int port) { app.post("/post", ctx -> ctx.result("post")); app.put("/put", ctx -> ctx.result("put")); app.patch("/patch", ctx -> ctx.result("patch")); - //app.tra("/patch", ctx -> ctx.result("patch")); + // app.tra("/patch", ctx -> ctx.result("patch")); app.delete("/delete", ctx -> ctx.result("delete body[" + ctx.body().trim() + "]")); -// // All WebRoutes / Controllers ... from DI Context -// List webRoutes = context.getBeans(WebRoutes.class); -// app.routes(() -> webRoutes.forEach(WebRoutes::registerRoutes)); + // // All WebRoutes / Controllers ... from DI Context + // List webRoutes = context.getBeans(WebRoutes.class); + // app.routes(() -> webRoutes.forEach(WebRoutes::registerRoutes)); // programmatically create http endpoints - HelloController$Route bean = new HelloController$Route(new HelloController(), new BeanValidator()); - app.routes(bean::registerRoutes); app.start(port); return app; diff --git a/http-client/src/test/java/org/example/webserver/HelloController$Route.java b/http-client/src/test/java/org/example/webserver/HelloController$Route.java index 729682f05..673b1e71a 100644 --- a/http-client/src/test/java/org/example/webserver/HelloController$Route.java +++ b/http-client/src/test/java/org/example/webserver/HelloController$Route.java @@ -1,19 +1,18 @@ package org.example.webserver; -import io.avaje.http.api.PathSegment; -import io.avaje.http.api.Validator; -import io.avaje.http.api.WebRoutes; -import io.javalin.apibuilder.ApiBuilder; - -import jakarta.inject.Singleton; -import java.time.LocalDate; - import static io.avaje.http.api.PathTypeConversion.asInt; import static io.avaje.http.api.PathTypeConversion.asLocalDate; import static io.avaje.http.api.PathTypeConversion.toLocalDate; +import java.time.LocalDate; + +import io.avaje.http.api.PathSegment; +import io.avaje.http.api.Validator; +import io.javalin.Javalin; +import io.javalin.plugin.Plugin; + //@Singleton -public class HelloController$Route implements WebRoutes { +public class HelloController$Route implements Plugin{ private final HelloController controller; private final Validator validator; @@ -24,52 +23,52 @@ public class HelloController$Route implements WebRoutes { } @Override - public void registerRoutes() { + public void apply(Javalin cfg) { - ApiBuilder.get("/hello/message", ctx -> { + cfg.get("/hello/message", ctx -> { ctx.status(200); ctx.contentType("text/plain").result(controller.getPlainMessage()); }); - ApiBuilder.get("/hello/retry", ctx -> { + cfg.get("/hello/retry", ctx -> { ctx.status(200); ctx.contentType("text/plain").result(controller.retry()); }); - ApiBuilder.get("/hello/basicAuth", ctx -> { + cfg.get("/hello/basicAuth", ctx -> { ctx.status(200); final String authorization = ctx.header("Authorization"); ctx.result(controller.basicAuth(authorization)); }); - ApiBuilder.get("/hello/stream", ctx -> { + cfg.get("/hello/stream", ctx -> { ctx.status(200); controller.stream(ctx); }); - ApiBuilder.get("/hello/{id}/{date}", ctx -> { + cfg.get("/hello/{id}/{date}", ctx -> { ctx.status(200); - int id = asInt(ctx.pathParam("id")); - LocalDate date = asLocalDate(ctx.pathParam("date")); - String otherParam = ctx.queryParam("otherParam"); + final int id = asInt(ctx.pathParam("id")); + final LocalDate date = asLocalDate(ctx.pathParam("date")); + final String otherParam = ctx.queryParam("otherParam"); ctx.json(controller.hello(id, date, otherParam)); }); - ApiBuilder.get("/hello/findbyname/{name}", ctx -> { + cfg.get("/hello/findbyname/{name}", ctx -> { ctx.status(200); - String name = ctx.pathParam("name"); - String otherParam = ctx.queryParam("otherParam"); + final String name = ctx.pathParam("name"); + final String otherParam = ctx.queryParam("otherParam"); ctx.json(controller.findByName(name, otherParam)); }); - ApiBuilder.post("/hello", ctx -> { + cfg.post("/hello", ctx -> { ctx.status(201); final HelloDto dto = ctx.bodyAsClass(HelloDto.class); validator.validate(dto, "en-us"); ctx.json(controller.post(dto)); }); - ApiBuilder.post("/hello/savebean/{foo}", ctx -> { + cfg.post("/hello/savebean/{foo}", ctx -> { ctx.status(201); final String foo = ctx.pathParam("foo"); final HelloDto dto = ctx.bodyAsClass(HelloDto.class); @@ -77,9 +76,9 @@ public void registerRoutes() { controller.saveBean(foo, dto, ctx); }); - ApiBuilder.post("/hello/saveform", ctx -> { + cfg.post("/hello/saveform", ctx -> { ctx.status(201); - HelloForm helloForm = new HelloForm( + final HelloForm helloForm = new HelloForm( ctx.formParam("name"), ctx.formParam("email") ); @@ -90,17 +89,17 @@ public void registerRoutes() { controller.saveForm(helloForm); }); - ApiBuilder.post("/hello/saveform2", ctx -> { + cfg.post("/hello/saveform2", ctx -> { ctx.status(201); - String name = ctx.formParam("name"); - String email = ctx.formParam("email"); - String url = ctx.formParam("url"); + final String name = ctx.formParam("name"); + final String email = ctx.formParam("email"); + final String url = ctx.formParam("url"); controller.saveForm2(name, email, url); }); - ApiBuilder.post("/hello/saveform3", ctx -> { + cfg.post("/hello/saveform3", ctx -> { ctx.status(201); - HelloForm helloForm = new HelloForm( + final HelloForm helloForm = new HelloForm( ctx.formParam("name"), ctx.formParam("email") ); @@ -111,26 +110,26 @@ public void registerRoutes() { ctx.json(controller.saveForm3(helloForm)); }); - ApiBuilder.get("/hello", ctx -> { + cfg.get("/hello", ctx -> { ctx.status(200); ctx.json(controller.getAll()); }); - ApiBuilder.delete("/hello/{id}", ctx -> { + cfg.delete("/hello/{id}", ctx -> { ctx.status(204); - int id = asInt(ctx.pathParam("id")); + final int id = asInt(ctx.pathParam("id")); controller.deleteById(id); }); - ApiBuilder.get("/hello/withMatrix/{year_segment}/{other}", ctx -> { + cfg.get("/hello/withMatrix/{year_segment}/{other}", ctx -> { ctx.status(200); - PathSegment year_segment = PathSegment.of(ctx.pathParam("year_segment")); - int year = asInt(year_segment.val()); - String author = year_segment.matrix("author"); - String country = year_segment.matrix("country"); - String zone = year_segment.matrix("zone"); - String other = ctx.pathParam("other"); - String extra = ctx.queryParam("extra"); + final PathSegment year_segment = PathSegment.of(ctx.pathParam("year_segment")); + final int year = asInt(year_segment.val()); + final String author = year_segment.matrix("author"); + final String country = year_segment.matrix("country"); + final String zone = year_segment.matrix("zone"); + final String other = ctx.pathParam("other"); + final String extra = ctx.queryParam("extra"); ctx.contentType("text/plain").result(controller.getWithMatrixParam(year, author, country, zone, other, extra)); }); diff --git a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java index ea23b782a..b60efba2e 100644 --- a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java +++ b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java @@ -34,7 +34,7 @@ void write(boolean requestScoped) { final var segments = method.pathSegments(); final var fullPath = segments.fullPath(); - writer.append(" ApiBuilder.%s(\"%s\", ctx -> {", webMethod.name().toLowerCase(), fullPath).eol(); + writer.append(" app.%s(\"%s\", ctx -> {", webMethod.name().toLowerCase(), fullPath).eol(); writer.append(" ctx.status(%s);", method.statusCode()).eol(); final var matrixSegments = segments.matrixSegments(); diff --git a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java index a88ccbef5..bc8d96c47 100644 --- a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java +++ b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java @@ -19,7 +19,6 @@ class ControllerWriter extends BaseControllerWriter { private static final String AT_GENERATED = "@Generated(\"avaje-javalin-generator\")"; - private static final String API_BUILDER = "io.javalin.apibuilder.ApiBuilder"; private final boolean useJsonB; private final Map jsonTypes; @@ -32,13 +31,12 @@ class ControllerWriter extends BaseControllerWriter { reader.addImportType("io.avaje.jsonb.JsonType"); reader.addImportType("io.avaje.jsonb.Types"); this.jsonTypes = JsonBUtil.jsonTypes(reader); - jsonTypes.values().stream() - .map(UType::importTypes) - .forEach(reader::addImportTypes); + jsonTypes.values().stream().map(UType::importTypes).forEach(reader::addImportTypes); } else { this.jsonTypes = Map.of(); } - reader.addImportType(API_BUILDER); + reader.addImportType("io.javalin.plugin.Plugin"); + reader.addImportType("io.javalin.Javalin"); } void write() { @@ -51,7 +49,7 @@ void write() { private void writeAddRoutes() { writer.append(" @Override").eol(); - writer.append(" public void registerRoutes() {").eol().eol(); + writer.append(" public void apply(Javalin app) {").eol().eol(); for (final MethodReader method : reader.methods()) { if (method.isWebMethod()) { writeForMethod(method); @@ -73,7 +71,7 @@ private void writeClassStart() { writer .append("public class ") .append(shortName) - .append("$Route implements WebRoutes {") + .append("$Route implements Plugin {") .eol() .eol(); diff --git a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/Main.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/Main.java index ad68865e3..1bbbd6f41 100644 --- a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/Main.java +++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/Main.java @@ -1,24 +1,26 @@ package org.example.myapp; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import io.avaje.http.api.InvalidPathArgumentException; import io.avaje.http.api.InvalidTypeArgumentException; import io.avaje.http.api.ValidationException; import io.avaje.http.api.Validator; -import io.avaje.http.api.WebRoutes; import io.avaje.inject.BeanScope; import io.avaje.inject.InjectModule; import io.javalin.Javalin; import io.javalin.http.staticfiles.Location; +import io.javalin.plugin.Plugin; import io.swagger.v3.oas.annotations.OpenAPIDefinition; import io.swagger.v3.oas.annotations.enums.SecuritySchemeIn; import io.swagger.v3.oas.annotations.enums.SecuritySchemeType; import io.swagger.v3.oas.annotations.info.Info; import io.swagger.v3.oas.annotations.security.SecurityScheme; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; @InjectModule(name = "app", requires = Validator.class) @OpenAPIDefinition(info = @Info(title = "Example service", description = "Example Javalin controllers with Java and Maven")) @@ -33,14 +35,22 @@ public static void main(String[] args) { public static Javalin start(int port) { - final var app = Javalin.create(config -> { - config.showJavalinBanner = false; - config.staticFiles.add("public", Location.CLASSPATH); - config.accessManager((handler, ctx, permittedRoles) -> { - log.debug("allow access ..."); - handler.handle(ctx); - }); - }); + // All WebRoutes / Controllers ... from DI Context + final var beanScope = BeanScope.builder().build(); + final List webRoutes = beanScope.list(Plugin.class); + + final var app = + Javalin.create( + config -> { + config.showJavalinBanner = false; + config.staticFiles.add("public", Location.CLASSPATH); + config.accessManager( + (handler, ctx, permittedRoles) -> { + log.debug("allow access ..."); + handler.handle(ctx); + }); + webRoutes.forEach(config.plugins::register); + }); app.exception(ValidationException.class, (exception, ctx) -> { @@ -74,11 +84,6 @@ public static Javalin start(int port) { ctx.result("Hello World"); }); - // All WebRoutes / Controllers ... from DI Context - final var beanScope = BeanScope.builder().build(); - final List webRoutes = beanScope.list(WebRoutes.class); - app.routes(() -> webRoutes.forEach(WebRoutes::registerRoutes)); - app.start(port); return app; } diff --git a/tests/test-javalin/src/main/java/org/example/myapp/Main.java b/tests/test-javalin/src/main/java/org/example/myapp/Main.java index f788ac2c6..d6958ec0d 100644 --- a/tests/test-javalin/src/main/java/org/example/myapp/Main.java +++ b/tests/test-javalin/src/main/java/org/example/myapp/Main.java @@ -11,11 +11,11 @@ import io.avaje.http.api.InvalidTypeArgumentException; import io.avaje.http.api.ValidationException; import io.avaje.http.api.Validator; -import io.avaje.http.api.WebRoutes; import io.avaje.inject.BeanScope; import io.avaje.inject.InjectModule; import io.javalin.Javalin; import io.javalin.http.staticfiles.Location; +import io.javalin.plugin.Plugin; import io.swagger.v3.oas.annotations.OpenAPIDefinition; import io.swagger.v3.oas.annotations.info.Info; @@ -31,51 +31,58 @@ public static void main(String[] args) { public static Javalin start(int port) { - final var app = Javalin.create(config -> { - config.showJavalinBanner = false; - config.staticFiles.add("public", Location.CLASSPATH); - config.accessManager((handler, ctx, permittedRoles) -> { - log.debug("allow access ..."); - handler.handle(ctx); - }); - }); - - app.exception(ValidationException.class, (exception, ctx) -> { - - final Map map = new LinkedHashMap<>(); - map.put("message", exception.getMessage()); - map.put("errors", exception.getErrors()); - ctx.json(map); - ctx.status(exception.getStatus()); - }); - - app.exception(InvalidTypeArgumentException.class, (exception, ctx) -> { - - final Map map = new LinkedHashMap<>(); - map.put("path", ctx.path()); - map.put("message", "invalid type argument"); - ctx.json(map); - ctx.status(400); - }); - - app.exception(InvalidPathArgumentException.class, (exception, ctx) -> { - - final Map map = new LinkedHashMap<>(); - map.put("path", ctx.path()); - map.put("message", "invalid path argument"); - ctx.json(map); - ctx.status(404); - }); - - - app.get("/", ctx -> { - ctx.result("Hello World"); - }); - // All WebRoutes / Controllers ... from DI Context final var beanScope = BeanScope.builder().build(); - final List webRoutes = beanScope.list(WebRoutes.class); - app.routes(() -> webRoutes.forEach(WebRoutes::registerRoutes)); + final List webRoutes = beanScope.list(Plugin.class); + + final var app = + Javalin.create( + config -> { + config.showJavalinBanner = false; + config.staticFiles.add("public", Location.CLASSPATH); + config.accessManager( + (handler, ctx, permittedRoles) -> { + log.debug("allow access ..."); + handler.handle(ctx); + }); + webRoutes.forEach(config.plugins::register); + }); + + app.exception( + ValidationException.class, + (exception, ctx) -> { + final Map map = new LinkedHashMap<>(); + map.put("message", exception.getMessage()); + map.put("errors", exception.getErrors()); + ctx.json(map); + ctx.status(exception.getStatus()); + }); + + app.exception( + InvalidTypeArgumentException.class, + (exception, ctx) -> { + final Map map = new LinkedHashMap<>(); + map.put("path", ctx.path()); + map.put("message", "invalid type argument"); + ctx.json(map); + ctx.status(400); + }); + + app.exception( + InvalidPathArgumentException.class, + (exception, ctx) -> { + final Map map = new LinkedHashMap<>(); + map.put("path", ctx.path()); + map.put("message", "invalid path argument"); + ctx.json(map); + ctx.status(404); + }); + + app.get( + "/", + ctx -> { + ctx.result("Hello World"); + }); app.start(port); return app; From 2935d448214951ef81ad0fc614d34e66269f73d2 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sat, 29 Jul 2023 12:20:54 -0400 Subject: [PATCH 0823/1323] Update pom.xml --- http-generator-helidon/pom.xml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index c561bfd9f..578742b54 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -33,10 +33,9 @@ maven-compiler-plugin 3.10.1 - 20 - 20 -proc:none + 20 From 55bb6d7c35b8ffb7b7bf34f18ee5807399cc3e27 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sat, 29 Jul 2023 14:25:07 -0400 Subject: [PATCH 0824/1323] use HTTP Feature --- .../generator/helidon/nima/ControllerMethodWriter.java | 2 +- .../http/generator/helidon/nima/ControllerWriter.java | 7 +++---- tests/test-nima-jsonb/src/main/java/org/example/Main.java | 7 +++---- .../src/test/java/org/example/TestPair.java | 7 +++++-- 4 files changed, 12 insertions(+), 11 deletions(-) diff --git a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java index 4ee726117..822898ee8 100644 --- a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java +++ b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java @@ -37,7 +37,7 @@ class ControllerMethodWriter { } void writeRule() { - writer.append(" rules.%s(\"%s\", this::_%s);", + writer.append(" routing.%s(\"%s\", this::_%s);", webMethod.name().toLowerCase(), method.fullPath(), method.simpleName()) .eol(); } diff --git a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java index f9714633c..7150923d6 100644 --- a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java +++ b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java @@ -41,11 +41,10 @@ class ControllerWriter extends BaseControllerWriter { } reader.addImportType("io.helidon.common.http.HttpMediaType"); reader.addImportType("io.helidon.common.parameters.Parameters"); - reader.addImportType("io.helidon.nima.webserver.http.HttpRules"); reader.addImportType("io.helidon.nima.webserver.http.HttpRouting"); reader.addImportType("io.helidon.nima.webserver.http.ServerRequest"); reader.addImportType("io.helidon.nima.webserver.http.ServerResponse"); - reader.addImportType("io.helidon.nima.webserver.http.HttpService"); + reader.addImportType("io.helidon.nima.webserver.http.HttpFeature"); reader.addImportType("io.helidon.common.http.Http.Header"); if (reader.isIncludeValidator()) { reader.addImportType("io.helidon.common.http.Http"); @@ -77,7 +76,7 @@ private void writeAddRoutes() { private void writeRoutes(List methods) { writer.append(" @Override").eol(); - writer.append(" public void routing(HttpRules rules) {").eol(); + writer.append(" public void setup(HttpRouting.Builder routing) {").eol(); for (final ControllerMethodWriter methodWriter : methods) { methodWriter.writeRule(); @@ -91,7 +90,7 @@ private void writeRoutes(List methods) { private void writeClassStart() { writer.append(AT_GENERATED).eol(); writer.append(diAnnotation()).eol(); - writer.append("public class %s$Route implements HttpService {", shortName).eol().eol(); + writer.append("public class %s$Route implements HttpFeature {", shortName).eol().eol(); var controllerName = "controller"; var controllerType = shortName; diff --git a/tests/test-nima-jsonb/src/main/java/org/example/Main.java b/tests/test-nima-jsonb/src/main/java/org/example/Main.java index 4a5455322..e6bf5b499 100644 --- a/tests/test-nima-jsonb/src/main/java/org/example/Main.java +++ b/tests/test-nima-jsonb/src/main/java/org/example/Main.java @@ -5,6 +5,7 @@ import io.avaje.inject.BeanScope; import io.avaje.jsonb.Jsonb; import io.helidon.nima.webserver.WebServer; +import io.helidon.nima.webserver.http.HttpFeature; import io.helidon.nima.webserver.http.HttpRouting; import io.helidon.nima.webserver.http.HttpService; @@ -13,11 +14,9 @@ public class Main { public static void main(String[] args) { final var scope = BeanScope.builder().beans(Jsonb.builder().build()).build(); - final List list = scope.list(HttpService.class); + final List list = scope.list(HttpFeature.class); final var builder = HttpRouting.builder(); - for (final HttpService httpService : list) { - httpService.routing(builder); - } + list.forEach(builder::addFeature); final var httpRouting = builder.build(); WebServer.builder() diff --git a/tests/test-nima-jsonb/src/test/java/org/example/TestPair.java b/tests/test-nima-jsonb/src/test/java/org/example/TestPair.java index 93021abb0..ec9590e0a 100644 --- a/tests/test-nima-jsonb/src/test/java/org/example/TestPair.java +++ b/tests/test-nima-jsonb/src/test/java/org/example/TestPair.java @@ -42,12 +42,15 @@ private static HttpRouting.Builder routing() { var hc = new HelloController(); var hello = new HelloController$Route(hc, beanValidator, jsonb); - hello.routing(routing); + + routing.addFeature(hello); + hello.setup(routing); var cr = new ThreadLocalRequestContextResolver(); var tc = new TestController(); TestController$Route tcr = new TestController$Route(tc, jsonb, cr); - tcr.routing(routing); + + routing.addFeature(tcr); return routing; } } From a656f0883ce406b649afc6b52a2d589ad370db6e Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sun, 30 Jul 2023 00:00:39 -0400 Subject: [PATCH 0825/1323] Javalin Exception Handling --- .../java/io/avaje/http/api/BeanParam.java | 8 +- .../io/avaje/http/api/DefaultException.java | 3 + .../io/avaje/http/api/ExceptionHandler.java | 40 ++++++++++ .../avaje/http/generator/core/JsonBUtil.java | 6 +- .../http/generator/core/MethodReader.java | 78 ++++++++++++++----- .../avaje/http/generator/core/WebMethod.java | 3 +- .../http/generator/core/package-info.java | 1 + .../javalin/ControllerMethodWriter.java | 41 +++++++--- .../myapp/web/test/TestController2.java | 17 ++++ 9 files changed, 158 insertions(+), 39 deletions(-) create mode 100644 http-api/src/main/java/io/avaje/http/api/DefaultException.java create mode 100644 http-api/src/main/java/io/avaje/http/api/ExceptionHandler.java diff --git a/http-api/src/main/java/io/avaje/http/api/BeanParam.java b/http-api/src/main/java/io/avaje/http/api/BeanParam.java index 2e06fc7a3..b6a3ef127 100644 --- a/http-api/src/main/java/io/avaje/http/api/BeanParam.java +++ b/http-api/src/main/java/io/avaje/http/api/BeanParam.java @@ -47,8 +47,6 @@ * * }

*/ -@Target(value={PARAMETER,METHOD}) -@Retention(value=RUNTIME) -public @interface BeanParam { - -} +@Target({PARAMETER,METHOD}) +@Retention(RUNTIME) +public @interface BeanParam {} diff --git a/http-api/src/main/java/io/avaje/http/api/DefaultException.java b/http-api/src/main/java/io/avaje/http/api/DefaultException.java new file mode 100644 index 000000000..03c70b666 --- /dev/null +++ b/http-api/src/main/java/io/avaje/http/api/DefaultException.java @@ -0,0 +1,3 @@ +package io.avaje.http.api; + +class DefaultException extends Exception {} diff --git a/http-api/src/main/java/io/avaje/http/api/ExceptionHandler.java b/http-api/src/main/java/io/avaje/http/api/ExceptionHandler.java new file mode 100644 index 000000000..8f7e798a7 --- /dev/null +++ b/http-api/src/main/java/io/avaje/http/api/ExceptionHandler.java @@ -0,0 +1,40 @@ +package io.avaje.http.api; + +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.RetentionPolicy.SOURCE; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +/** + * Annotation for handling exceptions in controller classes and/or handler methods. + * + *

Handler methods which are annotated with this annotation are allowed to have very flexible + * signatures. They may have parameters of the following types: + * + *

    + *
  1. An exception argument: declared as a general Exception or as a more specific exception. + * This also serves as a mapping hint if the annotation itself does not narrow the exception + * types through its {@link #value()}. + *
  2. Request and/or response objects (typically from the microframework). You may choose any + * specific request/response type, e.g. Javalin's {@link io.javalin.Context} or Helidon's + * Request/ServerResponse. + *
+ * + *

Handler methods may be void or return an object for serialization. + * + *

You may combine the {@code ExceptionHandler} annotation with {@link Produces @Produces} for a + * specific HTTP error status and media type. + */ +@Documented +@Target(METHOD) +@Retention(SOURCE) +public @interface ExceptionHandler { + + /** + * Exception handled by the annotated method. If empty, will default to any exception listed in + * the method argument list. + */ + Class value() default DefaultException.class; +} diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java index f6332ba34..d1f2d144c 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java @@ -1,5 +1,7 @@ package io.avaje.http.generator.core; +import static java.util.function.Predicate.not; + import java.util.LinkedHashMap; import java.util.Map; import java.util.function.Consumer; @@ -19,7 +21,9 @@ public static Map jsonTypes(ControllerReader reader) { .filter(m -> m.produces() == null || m.produces().toLowerCase().contains("json")) .forEach( methodReader -> { - addJsonBodyType(methodReader, addToMap); + if (!methodReader.isErrorMethod()) { + addJsonBodyType(methodReader, addToMap); + } if (!methodReader.isVoid()) { var uType = UType.parse(methodReader.returnType()); diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java index eaf019493..d6a719abe 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java @@ -1,6 +1,6 @@ package io.avaje.http.generator.core; -import static io.avaje.http.generator.core.ProcessingContext.doc; +import static io.avaje.http.generator.core.ProcessingContext.*; import static io.avaje.http.generator.core.ProcessingContext.docComment; import static io.avaje.http.generator.core.ProcessingContext.platform; import static io.avaje.http.generator.core.ProcessingContext.superMethods; @@ -33,10 +33,9 @@ public class MethodReader { private final boolean isVoid; private final List params = new ArrayList<>(); private final Javadoc javadoc; - /** - * Holds enum Roles that are required for the method. - */ + /** Holds enum Roles that are required for the method. */ private final List methodRoles; + private final Optional producesAnnotation; private final Optional consumesAnnotation; private final List securityRequirements; @@ -53,6 +52,7 @@ public class MethodReader { private boolean formMarker; private final boolean instrumentContext; private final boolean hasThrows; + private String exceptionShortName; MethodReader(ControllerReader bean, ExecutableElement element, ExecutableType actualExecutable) { this.bean = bean; @@ -70,7 +70,8 @@ public class MethodReader { initWebMethodViaAnnotation(); - this.superMethods = superMethods(element.getEnclosingElement(), element.getSimpleName().toString()); + this.superMethods = + superMethods(element.getEnclosingElement(), element.getSimpleName().toString()); superMethods.forEach(m -> methodRoles.addAll(Util.findRoles(m))); this.hasThrows = !element.getThrownTypes().isEmpty(); this.securityRequirements = readSecurityRequirements(); @@ -157,6 +158,9 @@ private void initWebMethodViaAnnotation() { .ifPresent(patch -> initSetWebMethod(WebMethod.PATCH, patch.value())); findAnnotation(DeletePrism::getOptionalOn) .ifPresent(delete -> initSetWebMethod(WebMethod.DELETE, delete.value())); + + findAnnotation(ExceptionHandlerPrism::getOptionalOn) + .ifPresent(error -> initSetWebMethod(WebMethod.ERROR, error.value())); } private void initSetWebMethod(WebMethod webMethod, String value) { @@ -164,6 +168,29 @@ private void initSetWebMethod(WebMethod webMethod, String value) { this.webMethodPath = value; } + private void initSetWebMethod(WebMethod webMethod, TypeMirror value) { + this.webMethod = webMethod; + var exType = value.toString(); + if ("io.avaje.http.api.DefaultException".equals(exType)) { + exType = + element.getParameters().stream() + .map(VariableElement::asType) + .map(UType::parse) + .map(UType::mainType) + .filter(t -> isAssignable2Interface(t, "java.lang.Throwable")) + .findAny() + .orElseGet( + () -> { + logError( + element, + "Must define a parameter that extends Throwable or define the exception type in the ExceptionHandler annotation"); + return ""; + }); + } + this.exceptionShortName = Util.shortName(exType); + bean.addImportType(exType); + } + public Javadoc javadoc() { return javadoc; } @@ -173,27 +200,28 @@ private List readSecurityRequirements() { readSecurityRequirements(element, list); for (final ExecutableElement superMethod : superMethods) { - readSecurityRequirements(superMethod, list); + readSecurityRequirements(superMethod, list); } readSecurityRequirements(bean.beanType(), list); final var map = new HashMap(); for (final SecurityRequirementPrism p : list) { - if (!map.containsKey(p.name())) { - map.put(p.name(), p); - } + if (!map.containsKey(p.name())) { + map.put(p.name(), p); + } } return List.copyOf(map.values()); } private void readSecurityRequirements(Element element, List list) { - final Consumer f = e -> { - Optional.ofNullable(SecurityRequirementsPrism.getInstanceOn(e)) - .map(SecurityRequirementsPrism::value) - .ifPresent(list::addAll); - Optional.ofNullable(SecurityRequirementPrism.getAllInstancesOn(e)) - .ifPresent(list::addAll); - }; + final Consumer f = + e -> { + Optional.ofNullable(SecurityRequirementsPrism.getInstanceOn(e)) + .map(SecurityRequirementsPrism::value) + .ifPresent(list::addAll); + Optional.ofNullable(SecurityRequirementPrism.getAllInstancesOn(e)) + .ifPresent(list::addAll); + }; f.accept(element); for (final AnnotationMirror annotationMirror : element.getAnnotationMirrors()) { @@ -221,7 +249,8 @@ private List buildApiResponses() { .flatMap(List::stream), OpenAPIResponsePrism.getAllInstancesOn(method).stream())); - final var responses = Stream.concat(methodResponses, superMethodResponses).collect(Collectors.toList()); + final var responses = + Stream.concat(methodResponses, superMethodResponses).collect(Collectors.toList()); responses.addAll(bean.openApiResponses()); return responses; } @@ -230,7 +259,8 @@ public Optional findAnnotation(Function> prismFunc) return findAnnotation(prismFunc, element); } - public Optional findAnnotation(Function> prismFunc, ExecutableElement elem) { + public Optional findAnnotation( + Function> prismFunc, ExecutableElement elem) { return prismFunc.apply(elem).or(() -> bean.findMethodAnnotation(prismFunc, elem)); } @@ -284,9 +314,7 @@ public void buildApiDoc() { buildApiDocumentation(); } - /** - * Build the OpenAPI documentation for the method / operation. - */ + /** Build the OpenAPI documentation for the method / operation. */ public void buildApiDocumentation() { new MethodDocBuilder(this, doc()).build(); } @@ -301,6 +329,10 @@ public boolean isWebMethod() { return webMethod != null; } + public boolean isErrorMethod() { + return webMethod == WebMethod.ERROR; + } + public WebMethod webMethod() { return webMethod; } @@ -421,4 +453,8 @@ public void writeContext(Append writer, String reqName, String resName) { public ExecutableElement element() { return element; } + + public String exceptionShortName() { + return exceptionShortName; + } } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/WebMethod.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/WebMethod.java index f37800811..15014e656 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/WebMethod.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/WebMethod.java @@ -5,7 +5,8 @@ public enum WebMethod { POST(201), PUT(200, 204), PATCH(200, 204), - DELETE(200, 204); + DELETE(200, 204), + ERROR(500); private int statusCode; private int voidStatusCode; diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/package-info.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/package-info.java index 2fb3aa273..4708f3313 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/package-info.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/package-info.java @@ -21,6 +21,7 @@ @GeneratePrism(value = io.avaje.http.api.Consumes.class, publicAccess = true) @GeneratePrism(value = io.avaje.http.api.Put.class, publicAccess = true) @GeneratePrism(value = io.avaje.http.api.InstrumentServerContext.class) +@GeneratePrism(value = io.avaje.http.api.ExceptionHandler.class) @GeneratePrism(value = io.swagger.v3.oas.annotations.OpenAPIDefinition.class, publicAccess = true) @GeneratePrism(value = io.swagger.v3.oas.annotations.tags.Tag.class, publicAccess = true) @GeneratePrism(value = io.swagger.v3.oas.annotations.tags.Tags.class, publicAccess = true) diff --git a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java index b60efba2e..6d07f4871 100644 --- a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java +++ b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java @@ -11,9 +11,7 @@ import io.avaje.http.generator.core.WebMethod; import io.avaje.http.generator.core.openapi.MediaType; -/** - * Write code to register Web route for a given controller method. - */ +/** Write code to register Web route for a given controller method. */ class ControllerMethodWriter { private final MethodReader method; @@ -34,7 +32,15 @@ void write(boolean requestScoped) { final var segments = method.pathSegments(); final var fullPath = segments.fullPath(); - writer.append(" app.%s(\"%s\", ctx -> {", webMethod.name().toLowerCase(), fullPath).eol(); + if (method.isErrorMethod()) { + writer + .append(" app.exception(%s.class, (ex, ctx) -> {", method.exceptionShortName()) + .eol(); + + } else { + writer.append(" app.%s(\"%s\", ctx -> {", webMethod.name().toLowerCase(), fullPath).eol(); + } + writer.append(" ctx.status(%s);", method.statusCode()).eol(); final var matrixSegments = segments.matrixSegments(); @@ -44,6 +50,9 @@ void write(boolean requestScoped) { final var params = method.params(); for (final MethodParam param : params) { + if (isAssignable2Interface(param.utype().mainType(), "java.lang.Exception")) { + continue; + } param.writeCtxGet(writer, segments); } if (method.includeValidate()) { @@ -70,7 +79,12 @@ void write(boolean requestScoped) { if (i > 0) { writer.append(", "); } - params.get(i).buildParamName(writer); + final var param = params.get(i); + if (isAssignable2Interface(param.utype().mainType(), "java.lang.Exception")) { + writer.append("ex"); + } else { + param.buildParamName(writer); + } } if (instrumentContext) { @@ -110,7 +124,8 @@ private void writeContextReturn() { final UType type = UType.parse(method.returnType()); if ("java.util.concurrent.CompletableFuture".equals(type.mainType())) { if (!type.isGeneric()) { - throw new IllegalStateException("CompletableFuture must be generic type (e.g. CompletableFuture, CompletableFuture)."); + throw new IllegalStateException( + "CompletableFuture must be generic type (e.g. CompletableFuture, CompletableFuture)."); } final String futureResultVariableName = "futureResult"; @@ -134,14 +149,18 @@ private void writeContextReturn(final String resultVariableName) { if (useJsonB) { var uType = UType.parse(method.returnType()); final boolean isfuture = "java.util.concurrent.CompletableFuture".equals(uType.mainType()); - if (isfuture) { - uType = uType.paramRaw(); + if (isfuture || method.isErrorMethod()) { + if (isfuture) { + uType = uType.paramRaw(); + } writer.append(" try {"); } - writer.append(" %sJsonType.toJson(%s, ctx.contentType(\"application/json\").res().getOutputStream());", + writer.append( + " %sJsonType.toJson(%s, ctx.contentType(\"application/json\").res().getOutputStream());", uType.shortName(), resultVariableName); - if (isfuture) { - writer.append(" } catch (java.io.IOException e) { throw new java.io.UncheckedIOException(e); }"); + if (isfuture || method.isErrorMethod()) { + writer.append( + " } catch (java.io.IOException e) { throw new java.io.UncheckedIOException(e); }"); } } else { writer.append(" ctx.json(%s);", resultVariableName); diff --git a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController2.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController2.java index dbc5ad2ef..5ec354362 100644 --- a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController2.java +++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController2.java @@ -62,4 +62,21 @@ String bytes(byte[] array) { String strBody(@BodyString String body) { return body; } + + @ExceptionHandler + String exception(Exception ex) { + + return ""; + } + + @ExceptionHandler + String exceptionCtx(Exception ex, Context ctx) { + + return ""; + } + + @ExceptionHandler(RuntimeException.class) + void exceptionVoid(Context ctx) { + System.err.println("do nothing lmao"); + } } From 457d7734fe6f09534a2b1070731828fed4c101df Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sun, 30 Jul 2023 00:25:01 -0400 Subject: [PATCH 0826/1323] Helidon Exception Handler --- .../http/generator/core/MethodReader.java | 5 ++- .../helidon/nima/ControllerMethodWriter.java | 45 ++++++++++++++++--- tests/test-nima-jsonb/pom.xml | 3 -- .../main/java/org/example/TestController.java | 22 ++++++++- 4 files changed, 62 insertions(+), 13 deletions(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java index d6a719abe..936c2f04a 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java @@ -316,7 +316,10 @@ public void buildApiDoc() { /** Build the OpenAPI documentation for the method / operation. */ public void buildApiDocumentation() { - new MethodDocBuilder(this, doc()).build(); + + if (!isErrorMethod()) { + new MethodDocBuilder(this, doc()).build(); + } } public List roles() { diff --git a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java index 822898ee8..bc3fb1c7d 100644 --- a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java +++ b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java @@ -1,7 +1,6 @@ package io.avaje.http.generator.helidon.nima; import static io.avaje.http.generator.core.ProcessingContext.*; -import static io.avaje.http.generator.core.ProcessingContext.platform; import java.util.List; import java.util.Optional; @@ -37,15 +36,39 @@ class ControllerMethodWriter { } void writeRule() { - writer.append(" routing.%s(\"%s\", this::_%s);", - webMethod.name().toLowerCase(), method.fullPath(), method.simpleName()) - .eol(); + + if (method.isErrorMethod()) { + writer + .append( + " routing.error(%s.class, this::_%s);", + method.exceptionShortName(), method.simpleName()) + .eol(); + } else { + writer + .append( + " routing.%s(\"%s\", this::_%s);", + webMethod.name().toLowerCase(), method.fullPath(), method.simpleName()) + .eol(); + } } void writeHandler(boolean requestScoped) { - writer.append(" private void _%s(ServerRequest req, ServerResponse res) throws Exception {", method.simpleName()).eol(); + + if (method.isErrorMethod()) { + writer + .append( + " private void _%s(ServerRequest req, ServerResponse res, %s ex) {", + method.simpleName(), method.exceptionShortName()) + .eol(); + } else { + writer + .append( + " private void _%s(ServerRequest req, ServerResponse res) throws Exception {", + method.simpleName()) + .eol(); + } final var bodyType = method.bodyType(); - if (bodyType != null) { + if (bodyType != null && !method.isErrorMethod()) { if ("InputStream".equals(bodyType)) { writer.append(" var %s = req.content().inputStream();", method.bodyName()).eol(); } else if ("String".equals(bodyType)) { @@ -71,6 +94,9 @@ void writeHandler(boolean requestScoped) { final var params = method.params(); for (final MethodParam param : params) { + if (isAssignable2Interface(param.utype().mainType(), "java.lang.Exception")) { + continue; + } param.writeCtxGet(writer, segments); } @@ -101,7 +127,12 @@ void writeHandler(boolean requestScoped) { if (i > 0) { writer.append(", "); } - params.get(i).buildParamName(writer); + final var param = params.get(i); + if (isAssignable2Interface(param.utype().mainType(), "java.lang.Exception")) { + writer.append("ex"); + } else { + param.buildParamName(writer); + } } if (instrumentContext) { writer.append(")"); diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index d76e2f3fe..64926a8f4 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -73,7 +73,6 @@ org.apache.maven.plugins maven-compiler-plugin - 3.10.1 true 20 @@ -94,8 +93,6 @@ 1.6-RC6 - 19 - 19 diff --git a/tests/test-nima-jsonb/src/main/java/org/example/TestController.java b/tests/test-nima-jsonb/src/main/java/org/example/TestController.java index f1be700c4..3ee903eed 100644 --- a/tests/test-nima-jsonb/src/main/java/org/example/TestController.java +++ b/tests/test-nima-jsonb/src/main/java/org/example/TestController.java @@ -5,6 +5,8 @@ import java.util.Set; import io.avaje.http.api.*; +import io.helidon.nima.webserver.http.ServerRequest; +import io.helidon.nima.webserver.http.ServerResponse; @Path("test") @Controller @@ -53,14 +55,30 @@ String enumQueryImplied(String s, @QueryParam ServerType type) { } @InstrumentServerContext - @Get(value = "/inputStream") + @Get(value = "/inputStream") InputStream stream(InputStream stream) throws Exception { return stream; } - @Post("/strBody") String strBody(@BodyString String body) { return body; } + + @ExceptionHandler + String exception(Exception ex) { + + return ""; + } + + @ExceptionHandler + Person exceptionCtx(Exception ex, ServerRequest req, ServerResponse res) { + + return new Person(0, null); + } + + @ExceptionHandler(RuntimeException.class) + void exceptionVoid(ServerResponse res) { + System.err.println("do nothing lmao"); + } } From f02971a16170002008c5a770bcad5e4258ce1f4b Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Mon, 31 Jul 2023 03:56:35 -0400 Subject: [PATCH 0827/1323] Add Javalin `@Before`/`@After` and Helidon `@Filter` (#255) * start * Javalin Before/After * Helidon Filter * Update pom.xml * fuse AbstractPrisms * Move filter to http-api --- .../main/java/io/avaje/http/api/Filter.java | 14 ++++ .../java/io/avaje/http/api/HttpMethod.java | 13 ++- http-generator-client/pom.xml | 16 ++-- http-generator-core/pom.xml | 5 +- .../http/generator/core/CoreWebMethod.java | 30 +++++++ .../http/generator/core/CustomWebMethod.java | 10 +++ .../avaje/http/generator/core/JsonBUtil.java | 4 +- .../http/generator/core/MethodReader.java | 38 ++++----- .../http/generator/core/PlatformAdapter.java | 40 ++++------ .../avaje/http/generator/core/WebMethod.java | 25 +----- .../core/openapi/MethodDocBuilder.java | 3 +- .../http/generator/core/package-info.java | 2 +- http-generator-helidon/pom.xml | 4 +- .../helidon/nima/ControllerMethodWriter.java | 31 +++++-- .../helidon/nima/ControllerWriter.java | 8 ++ .../helidon/nima/NimaPlatformAdapter.java | 13 ++- .../generator/helidon/nima/NimaProcessor.java | 6 +- .../src/main/java/module-info.java | 4 +- http-generator-javalin/pom.xml | 19 +++-- .../javalin/AbstractCustomMethodPrism.java | 17 ++++ .../javalin/ControllerMethodWriter.java | 80 ++++++++++++------- .../generator/javalin/JavalinAdapter.java | 13 +++ .../generator/javalin/JavalinProcessor.java | 11 ++- .../generator/javalin/JavalinWebMethod.java | 19 +++++ .../java/io/avaje/http/javalin/After.java | 21 +++++ .../java/io/avaje/http/javalin/Before.java | 21 +++++ .../src/main/java/module-info.java | 1 + pom.xml | 2 +- .../myapp/web/test/TestController2.java | 16 ++++ tests/test-nima-jsonb/pom.xml | 37 +++++---- .../main/java/org/example/TestController.java | 21 ++++- 31 files changed, 384 insertions(+), 160 deletions(-) create mode 100644 http-api/src/main/java/io/avaje/http/api/Filter.java create mode 100644 http-generator-core/src/main/java/io/avaje/http/generator/core/CoreWebMethod.java create mode 100644 http-generator-core/src/main/java/io/avaje/http/generator/core/CustomWebMethod.java create mode 100644 http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/AbstractCustomMethodPrism.java create mode 100644 http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinWebMethod.java create mode 100644 http-generator-javalin/src/main/java/io/avaje/http/javalin/After.java create mode 100644 http-generator-javalin/src/main/java/io/avaje/http/javalin/Before.java diff --git a/http-api/src/main/java/io/avaje/http/api/Filter.java b/http-api/src/main/java/io/avaje/http/api/Filter.java new file mode 100644 index 000000000..ea84bbe7a --- /dev/null +++ b/http-api/src/main/java/io/avaje/http/api/Filter.java @@ -0,0 +1,14 @@ +package io.avaje.http.api; + +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.RetentionPolicy.SOURCE; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +/** + * Marks a method as a Filter + */ +@Target(METHOD) +@Retention(SOURCE) +public @interface Filter {} diff --git a/http-api/src/main/java/io/avaje/http/api/HttpMethod.java b/http-api/src/main/java/io/avaje/http/api/HttpMethod.java index 8493f8f08..063cd48d1 100644 --- a/http-api/src/main/java/io/avaje/http/api/HttpMethod.java +++ b/http-api/src/main/java/io/avaje/http/api/HttpMethod.java @@ -1,15 +1,14 @@ package io.avaje.http.api; -import java.lang.annotation.ElementType; +import static java.lang.annotation.ElementType.ANNOTATION_TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; -/** - * Base for Http verb based annotations. - */ -@Target(value= ElementType.ANNOTATION_TYPE) -@Retention(value= RetentionPolicy.RUNTIME) +/** Base for Http verb based annotations. */ +@Target(ANNOTATION_TYPE) +@Retention(RUNTIME) public @interface HttpMethod { String value(); diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index 8af743164..647a918db 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -11,16 +11,8 @@ 11 - 1.9 - - io.avaje - avaje-prisms - ${avaje.prisms.version} - true - provided - io.avaje avaje-http-generator-core @@ -41,6 +33,14 @@ provided + + io.avaje + avaje-prisms + ${avaje.prisms.version} + provided + true + + diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 9888296d0..861967752 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -9,16 +9,13 @@ avaje-http-generator-core - - 1.10 - io.avaje avaje-prisms ${avaje.prisms.version} - true provided + true diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/CoreWebMethod.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/CoreWebMethod.java new file mode 100644 index 000000000..ff41b6f9d --- /dev/null +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/CoreWebMethod.java @@ -0,0 +1,30 @@ +package io.avaje.http.generator.core; + +public enum CoreWebMethod implements WebMethod { + GET(200), + POST(201), + PUT(200, 204), + PATCH(200, 204), + DELETE(200, 204), + ERROR(500), + FILTER(0), + OTHER(0, 0); + + private int statusCode; + private int voidStatusCode; + + CoreWebMethod(int statusCode, int voidStatusCode) { + this.statusCode = statusCode; + this.voidStatusCode = voidStatusCode; + } + + CoreWebMethod(int statusCode) { + this.statusCode = statusCode; + this.voidStatusCode = statusCode; + } + + @Override + public int statusCode(boolean isVoid) { + return isVoid ? voidStatusCode : statusCode; + } +} diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/CustomWebMethod.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/CustomWebMethod.java new file mode 100644 index 000000000..a874ab97f --- /dev/null +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/CustomWebMethod.java @@ -0,0 +1,10 @@ +package io.avaje.http.generator.core; + +public interface CustomWebMethod { + + WebMethod webMethod(); + + default String value() { + return ""; + } +} diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java index d1f2d144c..a47923feb 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java @@ -1,7 +1,5 @@ package io.avaje.http.generator.core; -import static java.util.function.Predicate.not; - import java.util.LinkedHashMap; import java.util.Map; import java.util.function.Consumer; @@ -17,6 +15,8 @@ public static Map jsonTypes(ControllerReader reader) { reader.methods().stream() .filter(MethodReader::isWebMethod) + .filter(m -> m.webMethod() instanceof CoreWebMethod) + .filter(m -> m.webMethod() != CoreWebMethod.FILTER) .filter(m -> !"byte[]".equals(m.returnType().toString())) .filter(m -> m.produces() == null || m.produces().toLowerCase().contains("json")) .forEach( diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java index 936c2f04a..adf464ecf 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java @@ -101,17 +101,7 @@ private boolean initResolver() { } private boolean hasInstrument(Element e) { - - if (InstrumentServerContextPrism.getOptionalOn(e).isPresent()) { - return true; - } - - for (final var a : e.getAnnotationMirrors()) { - if (HttpMethodPrism.isPresent(a.getAnnotationType().asElement())) { - return a.getElementValues().values().stream().anyMatch(v -> v.getValue().equals(true)); - } - } - return false; + return InstrumentServerContextPrism.getOptionalOn(e).isPresent(); } private Javadoc buildJavadoc(ExecutableElement element) { @@ -146,21 +136,29 @@ private void initWebMethodViaAnnotation() { } findAnnotation(GetPrism::getOptionalOn) - .ifPresent(get -> initSetWebMethod(WebMethod.GET, get.value())); + .ifPresent(get -> initSetWebMethod(CoreWebMethod.GET, get.value())); findAnnotation(PutPrism::getOptionalOn) - .ifPresent(put -> initSetWebMethod(WebMethod.PUT, put.value())); + .ifPresent(put -> initSetWebMethod(CoreWebMethod.PUT, put.value())); findAnnotation(PostPrism::getOptionalOn) - .ifPresent(post -> initSetWebMethod(WebMethod.POST, post.value())); + .ifPresent(post -> initSetWebMethod(CoreWebMethod.POST, post.value())); findAnnotation(PatchPrism::getOptionalOn) - .ifPresent(patch -> initSetWebMethod(WebMethod.PATCH, patch.value())); + .ifPresent(patch -> initSetWebMethod(CoreWebMethod.PATCH, patch.value())); + findAnnotation(DeletePrism::getOptionalOn) - .ifPresent(delete -> initSetWebMethod(WebMethod.DELETE, delete.value())); + .ifPresent(delete -> initSetWebMethod(CoreWebMethod.DELETE, delete.value())); findAnnotation(ExceptionHandlerPrism::getOptionalOn) - .ifPresent(error -> initSetWebMethod(WebMethod.ERROR, error.value())); + .ifPresent(error -> initSetWebMethod(CoreWebMethod.ERROR, error.value())); + + findAnnotation(FilterPrism::getOptionalOn) + .ifPresent(filter -> initSetWebMethod(CoreWebMethod.FILTER, "")); + + platform() + .customHandlers() + .forEach(f -> findAnnotation(f).ifPresent(m -> initSetWebMethod(m.webMethod(), m.value()))); } private void initSetWebMethod(WebMethod webMethod, String value) { @@ -317,7 +315,9 @@ public void buildApiDoc() { /** Build the OpenAPI documentation for the method / operation. */ public void buildApiDocumentation() { - if (!isErrorMethod()) { + if (!isErrorMethod() + && webMethod instanceof CoreWebMethod + && webMethod != CoreWebMethod.FILTER) { new MethodDocBuilder(this, doc()).build(); } } @@ -333,7 +333,7 @@ public boolean isWebMethod() { } public boolean isErrorMethod() { - return webMethod == WebMethod.ERROR; + return webMethod == CoreWebMethod.ERROR; } public WebMethod webMethod() { diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/PlatformAdapter.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/PlatformAdapter.java index 4087af9bc..7bddea839 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/PlatformAdapter.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/PlatformAdapter.java @@ -1,46 +1,36 @@ package io.avaje.http.generator.core; import java.util.List; +import java.util.Optional; +import java.util.function.Function; -/** - * Adapter to specific platforms like Javalin and Helidon. - */ +import javax.lang.model.element.Element; + +/** Adapter to specific platforms like Javalin and Helidon. */ public interface PlatformAdapter { /** - * Return true if this type is the platform specific request, response or context type. - * For example Javalin Context, Helidon ServerRequest or ServerResponse type). + * Return true if this type is the platform specific request, response or context type. For + * example Javalin Context, Helidon ServerRequest or ServerResponse type). */ boolean isContextType(String rawType); - /** - * Return the platform specific parameter (request, response or context). - */ + /** Return the platform specific parameter (request, response or context). */ String platformVariable(String rawType); - /** - * Return platform specific code to return the body content. - */ + /** Return platform specific code to return the body content. */ String bodyAsClass(UType type); - /** - * Return true if body is passed as a method parameter. - */ + /** Return true if body is passed as a method parameter. */ boolean isBodyMethodParam(); - /** - * Return whitespace indent for setting parameter values. - */ + /** Return whitespace indent for setting parameter values. */ String indent(); - /** - * Handle controller level roles. - */ + /** Handle controller level roles. */ void controllerRoles(List roles, ControllerReader controller); - /** - * Handle method level roles. - */ + /** Handle method level roles. */ void methodRoles(List roles, ControllerReader controller); void writeReadParameter(Append writer, ParamType paramType, String paramName); @@ -62,4 +52,8 @@ default void writeReadCollectionParameter( Append writer, ParamType paramType, String paramName, List paramDefault) { throw new UnsupportedOperationException("Unsupported MultiValue Parameter"); } + + default List>> customHandlers() { + return List.of(); + } } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/WebMethod.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/WebMethod.java index 15014e656..9996f1bfe 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/WebMethod.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/WebMethod.java @@ -1,27 +1,8 @@ package io.avaje.http.generator.core; -public enum WebMethod { - GET(200), - POST(201), - PUT(200, 204), - PATCH(200, 204), - DELETE(200, 204), - ERROR(500); +public interface WebMethod { - private int statusCode; - private int voidStatusCode; + int statusCode(boolean isVoid); - WebMethod(int statusCode, int voidStatusCode) { - this.statusCode = statusCode; - this.voidStatusCode = voidStatusCode; - } - - WebMethod(int statusCode) { - this.statusCode = statusCode; - this.voidStatusCode = statusCode; - } - - int statusCode(boolean isVoid) { - return isVoid ? voidStatusCode : statusCode; - } + String name(); } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/MethodDocBuilder.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/MethodDocBuilder.java index 105fb646a..4f3a75ace 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/MethodDocBuilder.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/MethodDocBuilder.java @@ -3,6 +3,7 @@ import java.util.Optional; import io.avaje.http.generator.core.ConsumesPrism; +import io.avaje.http.generator.core.CoreWebMethod; import io.avaje.http.generator.core.HiddenPrism; import io.avaje.http.generator.core.MethodParam; import io.avaje.http.generator.core.MethodReader; @@ -49,7 +50,7 @@ public void build() { } PathItem pathItem = ctx.pathItem(methodReader.fullPath()); - switch (methodReader.webMethod()) { + switch ((CoreWebMethod) methodReader.webMethod()) { case GET: pathItem.setGet(operation); break; diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/package-info.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/package-info.java index 4708f3313..534aad879 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/package-info.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/package-info.java @@ -12,7 +12,6 @@ @GeneratePrism(value = io.avaje.http.api.FormParam.class, publicAccess = true) @GeneratePrism(value = io.avaje.http.api.Get.class, publicAccess = true) @GeneratePrism(value = io.avaje.http.api.Header.class, publicAccess = true) -@GeneratePrism(value = io.avaje.http.api.HttpMethod.class, publicAccess = true) @GeneratePrism(value = io.avaje.http.api.MatrixParam.class, publicAccess = true) @GeneratePrism(value = io.avaje.http.api.Patch.class, publicAccess = true) @GeneratePrism(value = io.avaje.http.api.Path.class, publicAccess = true) @@ -20,6 +19,7 @@ @GeneratePrism(value = io.avaje.http.api.Produces.class, publicAccess = true) @GeneratePrism(value = io.avaje.http.api.Consumes.class, publicAccess = true) @GeneratePrism(value = io.avaje.http.api.Put.class, publicAccess = true) +@GeneratePrism(value = io.avaje.http.api.Filter.class) @GeneratePrism(value = io.avaje.http.api.InstrumentServerContext.class) @GeneratePrism(value = io.avaje.http.api.ExceptionHandler.class) @GeneratePrism(value = io.swagger.v3.oas.annotations.OpenAPIDefinition.class, publicAccess = true) diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index 578742b54..9f82895e4 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -23,7 +23,6 @@ avaje-http-generator-core ${project.version} - @@ -33,9 +32,8 @@ maven-compiler-plugin 3.10.1 - + 20 -proc:none - 20 diff --git a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java index bc3fb1c7d..9d5889963 100644 --- a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java +++ b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java @@ -6,6 +6,7 @@ import java.util.Optional; import io.avaje.http.generator.core.Append; +import io.avaje.http.generator.core.CoreWebMethod; import io.avaje.http.generator.core.MethodParam; import io.avaje.http.generator.core.MethodReader; import io.avaje.http.generator.core.ParamType; @@ -26,6 +27,7 @@ class ControllerMethodWriter { private final WebMethod webMethod; private final boolean useJsonB; private final boolean instrumentContext; + private final boolean isFilter; ControllerMethodWriter(MethodReader method, Append writer, boolean useJsonB) { this.method = method; @@ -33,6 +35,12 @@ class ControllerMethodWriter { this.webMethod = method.webMethod(); this.useJsonB = useJsonB; this.instrumentContext = method.instrumentContext(); + this.isFilter = webMethod == CoreWebMethod.FILTER; + if (isFilter + && method.params().stream().map(MethodParam::shortType).noneMatch("FilterChain"::equals)) { + + logError(method.element(), "Filters must contain a FilterChain Parameter"); + } } void writeRule() { @@ -43,6 +51,8 @@ void writeRule() { " routing.error(%s.class, this::_%s);", method.exceptionShortName(), method.simpleName()) .eol(); + } else if (isFilter) { + writer.append(" routing.addFilter(this::_%s);", method.simpleName()).eol(); } else { writer .append( @@ -60,6 +70,12 @@ void writeHandler(boolean requestScoped) { " private void _%s(ServerRequest req, ServerResponse res, %s ex) {", method.simpleName(), method.exceptionShortName()) .eol(); + } else if (isFilter) { + writer + .append( + " private void _%s(FilterChain chain, RoutingRequest req, RoutingResponse res) {", + method.simpleName()) + .eol(); } else { writer .append( @@ -68,7 +84,7 @@ void writeHandler(boolean requestScoped) { .eol(); } final var bodyType = method.bodyType(); - if (bodyType != null && !method.isErrorMethod()) { + if (bodyType != null && !method.isErrorMethod() && !isFilter) { if ("InputStream".equals(bodyType)) { writer.append(" var %s = req.content().inputStream();", method.bodyName()).eol(); } else if ("String".equals(bodyType)) { @@ -94,7 +110,8 @@ void writeHandler(boolean requestScoped) { final var params = method.params(); for (final MethodParam param : params) { - if (isAssignable2Interface(param.utype().mainType(), "java.lang.Exception")) { + if (isAssignable2Interface(param.utype().mainType(), "java.lang.Exception") + || "FilterChain".equals(param.shortType())) { continue; } param.writeCtxGet(writer, segments); @@ -110,7 +127,7 @@ void writeHandler(boolean requestScoped) { if (!method.isVoid()) { writer.append("var result = "); } else if (missingServerResponse(params)) { - throw new IllegalStateException("Void controller methods must have a ServerResponse parameter"); + logError(method.element(), "Void controller methods must have a ServerResponse parameter"); } if (instrumentContext) { @@ -130,6 +147,8 @@ void writeHandler(boolean requestScoped) { final var param = params.get(i); if (isAssignable2Interface(param.utype().mainType(), "java.lang.Exception")) { writer.append("ex"); + } else if ("FilterChain".equals(param.shortType())) { + writer.append("chain"); } else { param.buildParamName(writer); } @@ -139,7 +158,7 @@ void writeHandler(boolean requestScoped) { } writer.append(");").eol(); - if (!method.isVoid()) { + if (!method.isVoid() && !isFilter) { writeContextReturn(); if (isInputStream(method.returnType())) { final var uType = UType.parse(method.returnType()); @@ -200,7 +219,9 @@ private boolean returnTypeString() { } private boolean missingServerResponse(List params) { - return method.isVoid() && params.stream().noneMatch(p -> "ServerResponse".equals(p.shortType())); + return method.isVoid() + && !isFilter + && params.stream().noneMatch(p -> "ServerResponse".equals(p.shortType())); } private boolean usesFormParams() { diff --git a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java index 7150923d6..432e3d430 100644 --- a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java +++ b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java @@ -10,6 +10,7 @@ import io.avaje.http.generator.core.BaseControllerWriter; import io.avaje.http.generator.core.Constants; import io.avaje.http.generator.core.ControllerReader; +import io.avaje.http.generator.core.CoreWebMethod; import io.avaje.http.generator.core.JsonBUtil; import io.avaje.http.generator.core.MethodReader; import io.avaje.http.generator.core.PrimitiveUtil; @@ -49,6 +50,13 @@ class ControllerWriter extends BaseControllerWriter { if (reader.isIncludeValidator()) { reader.addImportType("io.helidon.common.http.Http"); } + if (reader.methods().stream() + .map(MethodReader::webMethod) + .anyMatch(w -> CoreWebMethod.FILTER == w)) { + reader.addImportType("io.helidon.nima.webserver.http.FilterChain"); + reader.addImportType("io.helidon.nima.webserver.http.RoutingRequest"); + reader.addImportType("io.helidon.nima.webserver.http.RoutingResponse"); + } } void write() { diff --git a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/NimaPlatformAdapter.java b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/NimaPlatformAdapter.java index 08bf8173f..3d3ec64cf 100644 --- a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/NimaPlatformAdapter.java +++ b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/NimaPlatformAdapter.java @@ -1,8 +1,17 @@ package io.avaje.http.generator.helidon.nima; -import io.avaje.http.generator.core.*; - import java.util.List; +import java.util.Optional; +import java.util.function.Function; + +import javax.lang.model.element.Element; + +import io.avaje.http.generator.core.Append; +import io.avaje.http.generator.core.ControllerReader; +import io.avaje.http.generator.core.CustomWebMethod; +import io.avaje.http.generator.core.ParamType; +import io.avaje.http.generator.core.PlatformAdapter; +import io.avaje.http.generator.core.UType; class NimaPlatformAdapter implements PlatformAdapter { diff --git a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/NimaProcessor.java b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/NimaProcessor.java index ff815ad8b..3adc17a19 100644 --- a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/NimaProcessor.java +++ b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/NimaProcessor.java @@ -1,9 +1,11 @@ package io.avaje.http.generator.helidon.nima; -import io.avaje.http.generator.core.*; - import java.io.IOException; +import io.avaje.http.generator.core.BaseProcessor; +import io.avaje.http.generator.core.ControllerReader; +import io.avaje.http.generator.core.PlatformAdapter; + public class NimaProcessor extends BaseProcessor { @Override diff --git a/http-generator-helidon/src/main/java/module-info.java b/http-generator-helidon/src/main/java/module-info.java index 166a3303a..7ef1e46c5 100644 --- a/http-generator-helidon/src/main/java/module-info.java +++ b/http-generator-helidon/src/main/java/module-info.java @@ -1,10 +1,10 @@ module io.avaje.http.nima.generator { - provides javax.annotation.processing.Processor with io.avaje.http.generator.helidon.nima.NimaProcessor; - requires java.compiler; requires java.sql; + provides javax.annotation.processing.Processor with io.avaje.http.generator.helidon.nima.NimaProcessor; + // SHADED: All content after this line will be removed at package time requires transitive io.avaje.http.generator.core; } diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index f05885e46..517ac1a62 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -17,6 +17,13 @@ ${project.version} + + io.avaje + avaje-prisms + ${avaje.prisms.version} + provided + + @@ -25,12 +32,14 @@ org.apache.maven.plugins maven-compiler-plugin - 3.10.1 - 11 - 11 - - -proc:none + + + io.avaje + avaje-prisms + ${avaje.prisms.version} + + diff --git a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/AbstractCustomMethodPrism.java b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/AbstractCustomMethodPrism.java new file mode 100644 index 000000000..05b5430f1 --- /dev/null +++ b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/AbstractCustomMethodPrism.java @@ -0,0 +1,17 @@ +package io.avaje.http.generator.javalin; + +import io.avaje.http.generator.core.CustomWebMethod; +import io.avaje.http.generator.core.WebMethod; + +public abstract class AbstractCustomMethodPrism implements CustomWebMethod { + + @Override + public WebMethod webMethod() { + + if (this instanceof AfterPrism) { + return JavalinWebMethod.AFTER; + } else { + return JavalinWebMethod.BEFORE; + } + } +} diff --git a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java index 6d07f4871..f117af3d4 100644 --- a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java +++ b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java @@ -2,7 +2,10 @@ import static io.avaje.http.generator.core.ProcessingContext.*; +import java.util.List; + import io.avaje.http.generator.core.Append; +import io.avaje.http.generator.core.CoreWebMethod; import io.avaje.http.generator.core.MethodParam; import io.avaje.http.generator.core.MethodReader; import io.avaje.http.generator.core.PathSegments; @@ -19,49 +22,27 @@ class ControllerMethodWriter { private final WebMethod webMethod; private final boolean useJsonB; private final boolean instrumentContext; + private final boolean customMethod; ControllerMethodWriter(MethodReader method, Append writer, boolean useJsonB) { this.method = method; this.writer = writer; - this.webMethod = method.webMethod(); + final var webM = method.webMethod(); + this.webMethod = webM == CoreWebMethod.FILTER ? JavalinWebMethod.BEFORE : webM; this.useJsonB = useJsonB && !disabledDirectWrites(); this.instrumentContext = method.instrumentContext(); + customMethod = !(webMethod instanceof CoreWebMethod); } void write(boolean requestScoped) { final var segments = method.pathSegments(); final var fullPath = segments.fullPath(); - if (method.isErrorMethod()) { - writer - .append(" app.exception(%s.class, (ex, ctx) -> {", method.exceptionShortName()) - .eol(); - - } else { - writer.append(" app.%s(\"%s\", ctx -> {", webMethod.name().toLowerCase(), fullPath).eol(); - } - - writer.append(" ctx.status(%s);", method.statusCode()).eol(); - - final var matrixSegments = segments.matrixSegments(); - for (final PathSegments.Segment matrixSegment : matrixSegments) { - matrixSegment.writeCreateSegment(writer, platform()); - } + writeMethod(fullPath); - final var params = method.params(); - for (final MethodParam param : params) { - if (isAssignable2Interface(param.utype().mainType(), "java.lang.Exception")) { - continue; - } - param.writeCtxGet(writer, segments); - } - if (method.includeValidate()) { - for (final MethodParam param : params) { - param.writeValidate(writer); - } - } + final var params = writeParams(segments); writer.append(" "); - if (!method.isVoid()) { + if (!method.isVoid() && !customMethod) { writer.append("var result = "); } @@ -74,6 +55,7 @@ void write(boolean requestScoped) { } else { writer.append("controller."); } + writer.append(method.simpleName()).append("("); for (var i = 0; i < params.size(); i++) { if (i > 0) { @@ -92,7 +74,7 @@ void write(boolean requestScoped) { } writer.append(");").eol(); - if (!method.isVoid()) { + if (!method.isVoid() && !customMethod) { writeContextReturn(); writer.eol(); } @@ -100,7 +82,7 @@ void write(boolean requestScoped) { writer.append(" }"); final var roles = method.roles(); - if (!roles.isEmpty()) { + if (!roles.isEmpty() && !customMethod) { writer.append(", "); for (var i = 0; i < roles.size(); i++) { if (i > 0) { @@ -112,6 +94,42 @@ void write(boolean requestScoped) { writer.append(");").eol().eol(); } + private void writeMethod(final String fullPath) { + if (method.isErrorMethod()) { + writer + .append(" app.exception(%s.class, (ex, ctx) -> {", method.exceptionShortName()) + .eol(); + + } else { + writer.append(" app.%s(\"%s\", ctx -> {", webMethod.name().toLowerCase(), fullPath).eol(); + } + + if (!customMethod) { + writer.append(" ctx.status(%s);", method.statusCode()).eol(); + } + } + + private List writeParams(final PathSegments segments) { + final var matrixSegments = segments.matrixSegments(); + for (final PathSegments.Segment matrixSegment : matrixSegments) { + matrixSegment.writeCreateSegment(writer, platform()); + } + + final var params = method.params(); + for (final MethodParam param : params) { + if (isAssignable2Interface(param.utype().mainType(), "java.lang.Exception")) { + continue; + } + param.writeCtxGet(writer, segments); + } + if (method.includeValidate()) { + for (final MethodParam param : params) { + param.writeValidate(writer); + } + } + return params; + } + private void writeContextReturn() { if (instrumentContext) { diff --git a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinAdapter.java b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinAdapter.java index f9abb089f..784297cf2 100644 --- a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinAdapter.java +++ b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinAdapter.java @@ -1,10 +1,15 @@ package io.avaje.http.generator.javalin; import java.util.List; +import java.util.Optional; +import java.util.function.Function; + +import javax.lang.model.element.Element; import io.avaje.http.generator.core.Append; import io.avaje.http.generator.core.Constants; import io.avaje.http.generator.core.ControllerReader; +import io.avaje.http.generator.core.CustomWebMethod; import io.avaje.http.generator.core.ParamType; import io.avaje.http.generator.core.PlatformAdapter; import io.avaje.http.generator.core.UType; @@ -114,4 +119,12 @@ public void writeReadCollectionParameter( public void writeAcceptLanguage(Append writer) { writer.append("ctx.header(\"%s\")", Constants.ACCEPT_LANGUAGE); } + + @Override + public List>> customHandlers() { + final Function f = AfterPrism::getInstanceOn; + final Function f2 = BeforePrism::getInstanceOn; + + return List.of(f.andThen(Optional::ofNullable), f2.andThen(Optional::ofNullable)); + } } diff --git a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinProcessor.java b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinProcessor.java index 7d40e02c1..5e613a879 100644 --- a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinProcessor.java +++ b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinProcessor.java @@ -1,9 +1,16 @@ package io.avaje.http.generator.javalin; -import io.avaje.http.generator.core.*; - import java.io.IOException; +import io.avaje.http.generator.core.BaseProcessor; +import io.avaje.http.generator.core.ControllerReader; +import io.avaje.http.generator.core.PlatformAdapter; +import io.avaje.http.javalin.After; +import io.avaje.http.javalin.Before; +import io.avaje.prism.GeneratePrism; + +@GeneratePrism(value = After.class, superClass = AbstractCustomMethodPrism.class) +@GeneratePrism(value = Before.class, superClass = AbstractCustomMethodPrism.class) public class JavalinProcessor extends BaseProcessor { @Override diff --git a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinWebMethod.java b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinWebMethod.java new file mode 100644 index 000000000..77e4aafb1 --- /dev/null +++ b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinWebMethod.java @@ -0,0 +1,19 @@ +package io.avaje.http.generator.javalin; + +import io.avaje.http.generator.core.WebMethod; + +public enum JavalinWebMethod implements WebMethod { + BEFORE(0), + AFTER(0); + + private int statusCode; + + JavalinWebMethod(int statusCode) { + this.statusCode = statusCode; + } + + @Override + public int statusCode(boolean isVoid) { + return statusCode; + } +} diff --git a/http-generator-javalin/src/main/java/io/avaje/http/javalin/After.java b/http-generator-javalin/src/main/java/io/avaje/http/javalin/After.java new file mode 100644 index 000000000..f4353790b --- /dev/null +++ b/http-generator-javalin/src/main/java/io/avaje/http/javalin/After.java @@ -0,0 +1,21 @@ +package io.avaje.http.javalin; + +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.RetentionPolicy.SOURCE; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +/** + * Marks a method that handles Javalin after requests. + * + *

{@code
+ *
+ *  @After
+ *  void save(Customer customer) {
+ * ...
+ *  }
+ */
+@Target(METHOD)
+@Retention(SOURCE)
+public @interface After {}
diff --git a/http-generator-javalin/src/main/java/io/avaje/http/javalin/Before.java b/http-generator-javalin/src/main/java/io/avaje/http/javalin/Before.java
new file mode 100644
index 000000000..967ee502e
--- /dev/null
+++ b/http-generator-javalin/src/main/java/io/avaje/http/javalin/Before.java
@@ -0,0 +1,21 @@
+package io.avaje.http.javalin;
+
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.RetentionPolicy.SOURCE;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+/**
+ * Marks a method that handles Javalin before requests.
+ *
+ * 
{@code
+ *
+ *  @Before
+ *  void save(Customer customer) {
+ * ...
+ *  }
+ */
+@Target(METHOD)
+@Retention(SOURCE)
+public @interface Before {}
diff --git a/http-generator-javalin/src/main/java/module-info.java b/http-generator-javalin/src/main/java/module-info.java
index 9d5f69e8c..557a7633e 100644
--- a/http-generator-javalin/src/main/java/module-info.java
+++ b/http-generator-javalin/src/main/java/module-info.java
@@ -7,4 +7,5 @@
 
   // SHADED: All content after this line will be removed at package time
   requires transitive io.avaje.http.generator.core;
+  requires static io.avaje.prism;
 }
diff --git a/pom.xml b/pom.xml
index 0ff4d9595..ce4e7a7d3 100644
--- a/pom.xml
+++ b/pom.xml
@@ -21,7 +21,7 @@
     true
     2.2.8
     2.14.2
-    1.9
+    1.10
     ${project.build.directory}${file.separator}module-info.shade
   
 
diff --git a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController2.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController2.java
index 5ec354362..c0b0e9406 100644
--- a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController2.java
+++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController2.java
@@ -7,6 +7,8 @@
 import org.example.myapp.web.ServerType;
 
 import io.avaje.http.api.*;
+import io.avaje.http.javalin.After;
+import io.avaje.http.javalin.Before;
 import io.javalin.http.Context;
 
 @Path("test/")
@@ -79,4 +81,18 @@ String exceptionCtx(Exception ex, Context ctx) {
   void exceptionVoid(Context ctx) {
     System.err.println("do nothing lmao");
   }
+
+  @After
+  void after(String s, ServerType type, Context ctx) {
+    ctx.result(s);
+  }
+
+  @Before
+  void before(String s, ServerType type, Context ctx) {
+    ctx.result(s);
+  }
+
+  @Filter
+  void filter(Context ctx) {
+  }
 }
diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml
index 64926a8f4..b5bac85e6 100644
--- a/tests/test-nima-jsonb/pom.xml
+++ b/tests/test-nima-jsonb/pom.xml
@@ -1,5 +1,7 @@
 
-
+
   4.0.0
   
     io.avaje
@@ -54,12 +56,26 @@
       avaje-http-client
       ${project.version}
     
+
+    
+      io.avaje
+      avaje-inject-generator
+      ${avaje-inject.version}
+      provided
+    
+    
+      io.avaje
+      avaje-jsonb-generator
+      1.6-RC6
+      provided
+    
     
       io.avaje
       avaje-http-helidon-generator
       ${project.version}
-      test
+      provided
     
+    
     
       io.avaje
       junit
@@ -76,23 +92,6 @@
         
           true
           20
-          
-            
-              io.avaje
-              avaje-http-helidon-generator
-              ${project.version}
-            
-            
-              io.avaje
-              avaje-inject-generator
-              ${avaje-inject.version}
-            
-            
-              io.avaje
-              avaje-jsonb-generator
-              1.6-RC6
-            
-          
         
       
       
diff --git a/tests/test-nima-jsonb/src/main/java/org/example/TestController.java b/tests/test-nima-jsonb/src/main/java/org/example/TestController.java
index 3ee903eed..49c9c7d1f 100644
--- a/tests/test-nima-jsonb/src/main/java/org/example/TestController.java
+++ b/tests/test-nima-jsonb/src/main/java/org/example/TestController.java
@@ -4,7 +4,21 @@
 import java.util.List;
 import java.util.Set;
 
-import io.avaje.http.api.*;
+import io.avaje.http.api.BodyString;
+import io.avaje.http.api.Controller;
+import io.avaje.http.api.Default;
+import io.avaje.http.api.ExceptionHandler;
+import io.avaje.http.api.Filter;
+import io.avaje.http.api.Form;
+import io.avaje.http.api.FormParam;
+import io.avaje.http.api.Get;
+import io.avaje.http.api.InstrumentServerContext;
+import io.avaje.http.api.Path;
+import io.avaje.http.api.Post;
+import io.avaje.http.api.Produces;
+import io.avaje.http.api.QueryParam;
+import io.helidon.nima.webserver.http.FilterChain;
+import io.helidon.nima.webserver.http.RoutingResponse;
 import io.helidon.nima.webserver.http.ServerRequest;
 import io.helidon.nima.webserver.http.ServerResponse;
 
@@ -81,4 +95,9 @@ Person exceptionCtx(Exception ex, ServerRequest req, ServerResponse res) {
   void exceptionVoid(ServerResponse res) {
     System.err.println("do nothing lmao");
   }
+
+  @Filter
+  void filter(FilterChain chain, RoutingResponse res) {
+    System.err.println("do nothing lmao");
+  }
 }

From 758a308626417d3da6922ee71f59e0538c145ac7 Mon Sep 17 00:00:00 2001
From: Rob Bygrave 
Date: Mon, 31 Jul 2023 20:11:35 +1200
Subject: [PATCH 0828/1323] No effective change - format and extract helper
 methods

---
 .../helidon/nima/ControllerMethodWriter.java  | 51 +++++++------------
 .../javalin/AbstractCustomMethodPrism.java    |  1 -
 .../javalin/ControllerMethodWriter.java       | 23 +++------
 3 files changed, 24 insertions(+), 51 deletions(-)

diff --git a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java
index 9d5889963..ffea9c39b 100644
--- a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java
+++ b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java
@@ -36,52 +36,34 @@ class ControllerMethodWriter {
     this.useJsonB = useJsonB;
     this.instrumentContext = method.instrumentContext();
     this.isFilter = webMethod == CoreWebMethod.FILTER;
-    if (isFilter
-        && method.params().stream().map(MethodParam::shortType).noneMatch("FilterChain"::equals)) {
+    if (isFilter) {
+      validateMethod();
+    }
+  }
 
+  private void validateMethod() {
+    if (method.params().stream().map(MethodParam::shortType).noneMatch("FilterChain"::equals)) {
       logError(method.element(), "Filters must contain a FilterChain Parameter");
     }
   }
 
   void writeRule() {
-
     if (method.isErrorMethod()) {
-      writer
-          .append(
-              "    routing.error(%s.class, this::_%s);",
-              method.exceptionShortName(), method.simpleName())
-          .eol();
+      writer.append("    routing.error(%s.class, this::_%s);", method.exceptionShortName(), method.simpleName()).eol();
     } else if (isFilter) {
       writer.append("    routing.addFilter(this::_%s);", method.simpleName()).eol();
     } else {
-      writer
-          .append(
-              "    routing.%s(\"%s\", this::_%s);",
-              webMethod.name().toLowerCase(), method.fullPath(), method.simpleName())
-          .eol();
+      writer.append("    routing.%s(\"%s\", this::_%s);", webMethod.name().toLowerCase(), method.fullPath(), method.simpleName()).eol();
     }
   }
 
   void writeHandler(boolean requestScoped) {
-
     if (method.isErrorMethod()) {
-      writer
-          .append(
-              "  private void _%s(ServerRequest req, ServerResponse res, %s ex) {",
-              method.simpleName(), method.exceptionShortName())
-          .eol();
+      writer.append("  private void _%s(ServerRequest req, ServerResponse res, %s ex) {", method.simpleName(), method.exceptionShortName()).eol();
     } else if (isFilter) {
-      writer
-          .append(
-              "  private void _%s(FilterChain chain, RoutingRequest req, RoutingResponse res) {",
-              method.simpleName())
-          .eol();
+      writer.append("  private void _%s(FilterChain chain, RoutingRequest req, RoutingResponse res) {", method.simpleName()).eol();
     } else {
-      writer
-          .append(
-              "  private void _%s(ServerRequest req, ServerResponse res) throws Exception {",
-              method.simpleName())
-          .eol();
+      writer.append("  private void _%s(ServerRequest req, ServerResponse res) throws Exception {", method.simpleName()).eol();
     }
     final var bodyType = method.bodyType();
     if (bodyType != null && !method.isErrorMethod() && !isFilter) {
@@ -110,11 +92,9 @@ void writeHandler(boolean requestScoped) {
 
     final var params = method.params();
     for (final MethodParam param : params) {
-      if (isAssignable2Interface(param.utype().mainType(), "java.lang.Exception")
-          || "FilterChain".equals(param.shortType())) {
-        continue;
+      if (!isExceptionOrFilterChain(param)) {
+        param.writeCtxGet(writer, segments);
       }
-      param.writeCtxGet(writer, segments);
     }
 
     if (method.includeValidate()) {
@@ -177,6 +157,11 @@ void writeHandler(boolean requestScoped) {
     writer.append("  }").eol().eol();
   }
 
+  private static boolean isExceptionOrFilterChain(MethodParam param) {
+    return isAssignable2Interface(param.utype().mainType(), "java.lang.Exception")
+      || "FilterChain".equals(param.shortType());
+  }
+
   private boolean isInputStream(TypeMirror type) {
     return isAssignable2Interface(type.toString(), "java.io.InputStream");
   }
diff --git a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/AbstractCustomMethodPrism.java b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/AbstractCustomMethodPrism.java
index 05b5430f1..ea8afbc09 100644
--- a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/AbstractCustomMethodPrism.java
+++ b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/AbstractCustomMethodPrism.java
@@ -7,7 +7,6 @@ public abstract class AbstractCustomMethodPrism implements CustomWebMethod {
 
   @Override
   public WebMethod webMethod() {
-
     if (this instanceof AfterPrism) {
       return JavalinWebMethod.AFTER;
     } else {
diff --git a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java
index f117af3d4..f336556ce 100644
--- a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java
+++ b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java
@@ -96,14 +96,10 @@ void write(boolean requestScoped) {
 
   private void writeMethod(final String fullPath) {
     if (method.isErrorMethod()) {
-      writer
-          .append("    app.exception(%s.class, (ex, ctx) -> {", method.exceptionShortName())
-          .eol();
-
+      writer.append("    app.exception(%s.class, (ex, ctx) -> {", method.exceptionShortName()).eol();
     } else {
       writer.append("    app.%s(\"%s\", ctx -> {", webMethod.name().toLowerCase(), fullPath).eol();
     }
-
     if (!customMethod) {
       writer.append("      ctx.status(%s);", method.statusCode()).eol();
     }
@@ -117,10 +113,9 @@ private List writeParams(final PathSegments segments) {
 
     final var params = method.params();
     for (final MethodParam param : params) {
-      if (isAssignable2Interface(param.utype().mainType(), "java.lang.Exception")) {
-        continue;
+      if (!isAssignable2Interface(param.utype().mainType(), "java.lang.Exception")) {
+        param.writeCtxGet(writer, segments);
       }
-      param.writeCtxGet(writer, segments);
     }
     if (method.includeValidate()) {
       for (final MethodParam param : params) {
@@ -131,11 +126,8 @@ private List writeParams(final PathSegments segments) {
   }
 
   private void writeContextReturn() {
-
     if (instrumentContext) {
-      writer
-          .append("      if (ctx.resultInputStream() != null || ctx.res().isCommitted()) return;")
-          .eol();
+      writer.append("      if (ctx.resultInputStream() != null || ctx.res().isCommitted()) return;").eol();
     }
 
     // Support for CompletableFuture's.
@@ -173,12 +165,9 @@ private void writeContextReturn(final String resultVariableName) {
           }
           writer.append("      try {");
         }
-        writer.append(
-            "      %sJsonType.toJson(%s, ctx.contentType(\"application/json\").res().getOutputStream());",
-            uType.shortName(), resultVariableName);
+        writer.append("      %sJsonType.toJson(%s, ctx.contentType(\"application/json\").res().getOutputStream());", uType.shortName(), resultVariableName);
         if (isfuture || method.isErrorMethod()) {
-          writer.append(
-              "      } catch (java.io.IOException e) { throw new java.io.UncheckedIOException(e); }");
+          writer.append("      } catch (java.io.IOException e) { throw new java.io.UncheckedIOException(e); }");
         }
       } else {
         writer.append("      ctx.json(%s);", resultVariableName);

From f788c428df4e384b30d801dd22abad3b2dc8b701 Mon Sep 17 00:00:00 2001
From: Rob Bygrave <130515035+rob-bygrave@users.noreply.github.com>
Date: Wed, 2 Aug 2023 16:22:24 +1200
Subject: [PATCH 0829/1323] Add to nima tests, a @Controller that only has
 @ExceptionHandler methods (#256)

---
 tests/test-nima-jsonb/pom.xml                 | 38 +++++++++----------
 .../java/org/example/ErrorController.java     | 21 ++++++++++
 .../main/java/org/example/TestController.java |  6 +++
 3 files changed, 45 insertions(+), 20 deletions(-)
 create mode 100644 tests/test-nima-jsonb/src/main/java/org/example/ErrorController.java

diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml
index b5bac85e6..b865cede9 100644
--- a/tests/test-nima-jsonb/pom.xml
+++ b/tests/test-nima-jsonb/pom.xml
@@ -34,7 +34,7 @@
     
       io.avaje
       avaje-jsonb
-      1.6-RC6
+      1.7-RC1
     
     
       io.avaje
@@ -57,25 +57,6 @@
       ${project.version}
     
 
-    
-      io.avaje
-      avaje-inject-generator
-      ${avaje-inject.version}
-      provided
-    
-    
-      io.avaje
-      avaje-jsonb-generator
-      1.6-RC6
-      provided
-    
-    
-      io.avaje
-      avaje-http-helidon-generator
-      ${project.version}
-      provided
-    
-    
     
       io.avaje
       junit
@@ -92,6 +73,23 @@
         
           true
           20
+          
+            
+              io.avaje
+              avaje-http-helidon-generator
+              ${project.version}
+            
+            
+              io.avaje
+              avaje-inject-generator
+              ${avaje-inject.version}
+            
+            
+              io.avaje
+              avaje-jsonb-generator
+              1.7-RC1
+            
+          
         
       
       
diff --git a/tests/test-nima-jsonb/src/main/java/org/example/ErrorController.java b/tests/test-nima-jsonb/src/main/java/org/example/ErrorController.java
new file mode 100644
index 000000000..c4ae54404
--- /dev/null
+++ b/tests/test-nima-jsonb/src/main/java/org/example/ErrorController.java
@@ -0,0 +1,21 @@
+package org.example;
+
+import io.avaje.http.api.Controller;
+import io.avaje.http.api.ExceptionHandler;
+import io.helidon.nima.webserver.http.ServerRequest;
+import io.helidon.nima.webserver.http.ServerResponse;
+
+import java.util.Map;
+
+/**
+ * Controller with only ExceptionHandler methods.
+ */
+@Controller
+final class ErrorController {
+
+  @ExceptionHandler
+  Map runEx(RuntimeException ex, ServerRequest req, ServerResponse res) {
+    return Map.of("err", "" + ex);
+  }
+
+}
diff --git a/tests/test-nima-jsonb/src/main/java/org/example/TestController.java b/tests/test-nima-jsonb/src/main/java/org/example/TestController.java
index 49c9c7d1f..f20a41090 100644
--- a/tests/test-nima-jsonb/src/main/java/org/example/TestController.java
+++ b/tests/test-nima-jsonb/src/main/java/org/example/TestController.java
@@ -2,6 +2,7 @@
 
 import java.io.InputStream;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
 import io.avaje.http.api.BodyString;
@@ -79,6 +80,11 @@ String strBody(@BodyString String body) {
     return body;
   }
 
+  @Post("/blah")
+  Map strBody2() {
+    return Map.of("hi", "yo", "level", 42L);
+  }
+
   @ExceptionHandler
   String exception(Exception ex) {
 

From 679d3d1ce98a796d720e953ce85e6d5a56609fc8 Mon Sep 17 00:00:00 2001
From: Rob Bygrave 
Date: Wed, 2 Aug 2023 16:30:19 +1200
Subject: [PATCH 0830/1323] Version 2.0-RC3

---
 http-api/pom.xml                     | 2 +-
 http-client-gson-adapter/pom.xml     | 4 ++--
 http-client/pom.xml                  | 2 +-
 http-generator-client/pom.xml        | 2 +-
 http-generator-core/pom.xml          | 2 +-
 http-generator-helidon/pom.xml       | 2 +-
 http-generator-javalin/pom.xml       | 2 +-
 http-generator-jex/pom.xml           | 2 +-
 http-inject-plugin/pom.xml           | 2 +-
 pom.xml                              | 2 +-
 tests/pom.xml                        | 2 +-
 tests/test-client-generation/pom.xml | 2 +-
 tests/test-client/pom.xml            | 2 +-
 tests/test-javalin-jsonb/pom.xml     | 2 +-
 tests/test-javalin/pom.xml           | 2 +-
 tests/test-jex/pom.xml               | 2 +-
 tests/test-nima-jsonb/pom.xml        | 2 +-
 tests/test-nima/pom.xml              | 2 +-
 18 files changed, 19 insertions(+), 19 deletions(-)

diff --git a/http-api/pom.xml b/http-api/pom.xml
index 66f7bcc71..5792f91a9 100644
--- a/http-api/pom.xml
+++ b/http-api/pom.xml
@@ -4,7 +4,7 @@
   
     io.avaje
     avaje-http-parent
-    2.0-RC2
+    2.0-RC3
     ..
   
 
diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml
index 3b42beba6..fd907dc5b 100644
--- a/http-client-gson-adapter/pom.xml
+++ b/http-client-gson-adapter/pom.xml
@@ -4,7 +4,7 @@
   
     io.avaje
     avaje-http-parent
-    2.0-RC2
+    2.0-RC3
   
 
   avaje-http-client-gson
@@ -20,7 +20,7 @@
     
       io.avaje
       avaje-http-client
-      2.0-RC2
+      2.0-RC3
       provided
     
 
diff --git a/http-client/pom.xml b/http-client/pom.xml
index 38552c34a..7b8970597 100644
--- a/http-client/pom.xml
+++ b/http-client/pom.xml
@@ -4,7 +4,7 @@
   
     io.avaje
     avaje-http-parent
-    2.0-RC2
+    2.0-RC3
   
 
   avaje-http-client
diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml
index 647a918db..85b7acae8 100644
--- a/http-generator-client/pom.xml
+++ b/http-generator-client/pom.xml
@@ -4,7 +4,7 @@
   
     io.avaje
     avaje-http-parent
-    2.0-RC2
+    2.0-RC3
   
 
   avaje-http-client-generator
diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml
index 861967752..6ddf88521 100644
--- a/http-generator-core/pom.xml
+++ b/http-generator-core/pom.xml
@@ -4,7 +4,7 @@
   
     io.avaje
     avaje-http-parent
-    2.0-RC2
+    2.0-RC3
   
 
   avaje-http-generator-core
diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml
index 9f82895e4..2825f79ac 100644
--- a/http-generator-helidon/pom.xml
+++ b/http-generator-helidon/pom.xml
@@ -4,7 +4,7 @@
   
     avaje-http-parent
     io.avaje
-    2.0-RC2
+    2.0-RC3
   
 
   avaje-http-helidon-generator
diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml
index 517ac1a62..5a8edfa8f 100644
--- a/http-generator-javalin/pom.xml
+++ b/http-generator-javalin/pom.xml
@@ -4,7 +4,7 @@
   
     io.avaje
     avaje-http-parent
-    2.0-RC2
+    2.0-RC3
   
 
   avaje-http-javalin-generator
diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml
index 386a1b8a4..a89f4812a 100644
--- a/http-generator-jex/pom.xml
+++ b/http-generator-jex/pom.xml
@@ -4,7 +4,7 @@
   
     io.avaje
     avaje-http-parent
-    2.0-RC2
+    2.0-RC3
   
 
   avaje-http-jex-generator
diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml
index e6ba0ea62..f441b34cb 100644
--- a/http-inject-plugin/pom.xml
+++ b/http-inject-plugin/pom.xml
@@ -4,7 +4,7 @@
   
     io.avaje
     avaje-http-parent
-    2.0-RC2
+    2.0-RC3
     ..
   
 
diff --git a/pom.xml b/pom.xml
index ce4e7a7d3..ace58e970 100644
--- a/pom.xml
+++ b/pom.xml
@@ -9,7 +9,7 @@
 
   io.avaje
   avaje-http-parent
-  2.0-RC2
+  2.0-RC3
   pom
 
   
diff --git a/tests/pom.xml b/tests/pom.xml
index 53b52e07b..5440479c2 100644
--- a/tests/pom.xml
+++ b/tests/pom.xml
@@ -4,7 +4,7 @@
   
     avaje-http-parent
     io.avaje
-    2.0-RC2
+    2.0-RC3
   
 
   tests
diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml
index fb3deb260..02b0ce073 100644
--- a/tests/test-client-generation/pom.xml
+++ b/tests/test-client-generation/pom.xml
@@ -4,7 +4,7 @@
   
     io.avaje
     tests
-    2.0-RC2
+    2.0-RC3
   
 
   test-client-generation
diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml
index 9ba9ca09e..26d61b522 100644
--- a/tests/test-client/pom.xml
+++ b/tests/test-client/pom.xml
@@ -6,7 +6,7 @@
   
     io.avaje
     tests
-    2.0-RC2
+    2.0-RC3
   
 
   test-client
diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml
index cef517356..4fd387c81 100644
--- a/tests/test-javalin-jsonb/pom.xml
+++ b/tests/test-javalin-jsonb/pom.xml
@@ -5,7 +5,7 @@
   
     io.avaje
     tests
-    2.0-RC2
+    2.0-RC3
   
 
   test-javalin-jsonb
diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml
index e0e8fb671..9c60e0de6 100644
--- a/tests/test-javalin/pom.xml
+++ b/tests/test-javalin/pom.xml
@@ -4,7 +4,7 @@
   
     io.avaje
     tests
-    2.0-RC2
+    2.0-RC3
   
 
   test-javalin
diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml
index e9dd780e5..62fd2cc94 100644
--- a/tests/test-jex/pom.xml
+++ b/tests/test-jex/pom.xml
@@ -4,7 +4,7 @@
   
     io.avaje
     tests
-    2.0-RC2
+    2.0-RC3
   
 
   test-jex
diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml
index b865cede9..4260c1877 100644
--- a/tests/test-nima-jsonb/pom.xml
+++ b/tests/test-nima-jsonb/pom.xml
@@ -6,7 +6,7 @@
   
     io.avaje
     tests
-    2.0-RC2
+    2.0-RC3
   
 
   test-nima-jsonb
diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml
index b1d67572d..529580e7f 100644
--- a/tests/test-nima/pom.xml
+++ b/tests/test-nima/pom.xml
@@ -6,7 +6,7 @@
   
     io.avaje
     tests
-    2.0-RC2
+    2.0-RC3
   
 
   test-nima

From f99dc1bff3ad7a8e665c7ed550ec06c006b9371e Mon Sep 17 00:00:00 2001
From: Rob Bygrave 
Date: Wed, 2 Aug 2023 16:53:24 +1200
Subject: [PATCH 0831/1323] Javadoc and serialVersionUID

---
 .../src/main/java/io/avaje/http/api/DefaultException.java   | 6 +++++-
 .../src/main/java/io/avaje/http/api/ExceptionHandler.java   | 4 ++--
 .../io/avaje/http/api/InvalidPathArgumentException.java     | 2 ++
 .../io/avaje/http/api/InvalidTypeArgumentException.java     | 2 ++
 .../src/main/java/io/avaje/http/api/PathTypeConversion.java | 1 +
 http-api/src/main/java/io/avaje/http/api/Post.java          | 3 ++-
 .../java/io/avaje/http/api/RequiredArgumentException.java   | 2 ++
 .../main/java/io/avaje/http/api/ValidationException.java    | 5 ++++-
 .../java/io/avaje/http/generator/core/PathSegments.java     | 2 +-
 .../src/main/java/io/avaje/http/javalin/After.java          | 4 +++-
 .../src/main/java/io/avaje/http/javalin/Before.java         | 4 +++-
 11 files changed, 27 insertions(+), 8 deletions(-)

diff --git a/http-api/src/main/java/io/avaje/http/api/DefaultException.java b/http-api/src/main/java/io/avaje/http/api/DefaultException.java
index 03c70b666..34ec0367e 100644
--- a/http-api/src/main/java/io/avaje/http/api/DefaultException.java
+++ b/http-api/src/main/java/io/avaje/http/api/DefaultException.java
@@ -1,3 +1,7 @@
 package io.avaje.http.api;
 
-class DefaultException extends Exception {}
+class DefaultException extends Exception {
+
+  private static final long serialVersionUID = 1;
+
+}
diff --git a/http-api/src/main/java/io/avaje/http/api/ExceptionHandler.java b/http-api/src/main/java/io/avaje/http/api/ExceptionHandler.java
index 8f7e798a7..8a18e40ce 100644
--- a/http-api/src/main/java/io/avaje/http/api/ExceptionHandler.java
+++ b/http-api/src/main/java/io/avaje/http/api/ExceptionHandler.java
@@ -18,8 +18,8 @@
  *       This also serves as a mapping hint if the annotation itself does not narrow the exception
  *       types through its {@link #value()}.
  *   
  • Request and/or response objects (typically from the microframework). You may choose any - * specific request/response type, e.g. Javalin's {@link io.javalin.Context} or Helidon's - * Request/ServerResponse. + * specific request/response type, e.g. Javalin's {@code io.javalin.Context} or Helidon's + * ServerRequest/ServerResponse. * * *

    Handler methods may be void or return an object for serialization. diff --git a/http-api/src/main/java/io/avaje/http/api/InvalidPathArgumentException.java b/http-api/src/main/java/io/avaje/http/api/InvalidPathArgumentException.java index 71e5f2d24..473e96e3a 100644 --- a/http-api/src/main/java/io/avaje/http/api/InvalidPathArgumentException.java +++ b/http-api/src/main/java/io/avaje/http/api/InvalidPathArgumentException.java @@ -5,6 +5,8 @@ */ public class InvalidPathArgumentException extends InvalidTypeArgumentException { + private static final long serialVersionUID = 1; + /** * Construct with a message. */ diff --git a/http-api/src/main/java/io/avaje/http/api/InvalidTypeArgumentException.java b/http-api/src/main/java/io/avaje/http/api/InvalidTypeArgumentException.java index 1e289acd8..40f3dccb7 100644 --- a/http-api/src/main/java/io/avaje/http/api/InvalidTypeArgumentException.java +++ b/http-api/src/main/java/io/avaje/http/api/InvalidTypeArgumentException.java @@ -5,6 +5,8 @@ */ public class InvalidTypeArgumentException extends IllegalArgumentException { + private static final long serialVersionUID = 1; + /** * Construct with a message. */ diff --git a/http-api/src/main/java/io/avaje/http/api/PathTypeConversion.java b/http-api/src/main/java/io/avaje/http/api/PathTypeConversion.java index 15680c916..49fb16192 100644 --- a/http-api/src/main/java/io/avaje/http/api/PathTypeConversion.java +++ b/http-api/src/main/java/io/avaje/http/api/PathTypeConversion.java @@ -70,6 +70,7 @@ public static int asInt(String value) { } /** Convert to enum. */ + @SuppressWarnings({"unchecked", "rawtypes"}) public static Enum asEnum(Class clazz, String value) { checkNull(value); try { diff --git a/http-api/src/main/java/io/avaje/http/api/Post.java b/http-api/src/main/java/io/avaje/http/api/Post.java index 7f94c8102..cf852bbc2 100644 --- a/http-api/src/main/java/io/avaje/http/api/Post.java +++ b/http-api/src/main/java/io/avaje/http/api/Post.java @@ -13,8 +13,9 @@ * * @Post * void save(Customer customer) { - ... + * ... * } + * }

  • */ @Target(METHOD) @Retention(RUNTIME) diff --git a/http-api/src/main/java/io/avaje/http/api/RequiredArgumentException.java b/http-api/src/main/java/io/avaje/http/api/RequiredArgumentException.java index 49c13ca17..57df013f8 100644 --- a/http-api/src/main/java/io/avaje/http/api/RequiredArgumentException.java +++ b/http-api/src/main/java/io/avaje/http/api/RequiredArgumentException.java @@ -9,6 +9,8 @@ */ public class RequiredArgumentException extends IllegalArgumentException { + private static final long serialVersionUID = 1; + private String property; /** diff --git a/http-api/src/main/java/io/avaje/http/api/ValidationException.java b/http-api/src/main/java/io/avaje/http/api/ValidationException.java index dbf352006..473dcee5b 100644 --- a/http-api/src/main/java/io/avaje/http/api/ValidationException.java +++ b/http-api/src/main/java/io/avaje/http/api/ValidationException.java @@ -1,5 +1,6 @@ package io.avaje.http.api; +import java.io.Serializable; import java.util.ArrayList; import java.util.List; @@ -67,7 +68,9 @@ public void setErrors(List errors) { } /** Error details including the field, error message and path */ - public static class Violation { + public static class Violation implements Serializable { + + private static final long serialVersionUID = 1; protected String path; protected String field; diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/PathSegments.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/PathSegments.java index 4e945a310..05c25c2ce 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/PathSegments.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/PathSegments.java @@ -106,7 +106,7 @@ public Segment segment(String varName) { } /** - * Return full path with {}{} for named path params. */ public String fullPath() { return fullPath("{", "}"); diff --git a/http-generator-javalin/src/main/java/io/avaje/http/javalin/After.java b/http-generator-javalin/src/main/java/io/avaje/http/javalin/After.java index f4353790b..655118002 100644 --- a/http-generator-javalin/src/main/java/io/avaje/http/javalin/After.java +++ b/http-generator-javalin/src/main/java/io/avaje/http/javalin/After.java @@ -13,8 +13,10 @@ * * @After * void save(Customer customer) { - * ... + * ... * } + * + * }
    */ @Target(METHOD) @Retention(SOURCE) diff --git a/http-generator-javalin/src/main/java/io/avaje/http/javalin/Before.java b/http-generator-javalin/src/main/java/io/avaje/http/javalin/Before.java index 967ee502e..5fae5ab4f 100644 --- a/http-generator-javalin/src/main/java/io/avaje/http/javalin/Before.java +++ b/http-generator-javalin/src/main/java/io/avaje/http/javalin/Before.java @@ -13,8 +13,10 @@ * * @Before * void save(Customer customer) { - * ... + * ... * } + * + * }
    */ @Target(METHOD) @Retention(SOURCE) From 256bf8bba6d7ceebc9c1cdb6268603ff1c62af1f Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Wed, 2 Aug 2023 16:57:18 +1200 Subject: [PATCH 0832/1323] Tidy DefaultException back to what it was --- .../src/main/java/io/avaje/http/api/DefaultException.java | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/http-api/src/main/java/io/avaje/http/api/DefaultException.java b/http-api/src/main/java/io/avaje/http/api/DefaultException.java index 34ec0367e..03c70b666 100644 --- a/http-api/src/main/java/io/avaje/http/api/DefaultException.java +++ b/http-api/src/main/java/io/avaje/http/api/DefaultException.java @@ -1,7 +1,3 @@ package io.avaje.http.api; -class DefaultException extends Exception { - - private static final long serialVersionUID = 1; - -} +class DefaultException extends Exception {} From 21f856fc76989ed2de4289a2349c575ed898a2ff Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Thu, 3 Aug 2023 00:34:05 -0400 Subject: [PATCH 0833/1323] http client varargs --- .../generator/client/ClientProcessorTest.java | 3 +++ .../avaje/http/generator/client/clients/Body.java | 3 +++ .../http/generator/client/clients/UserClient.java | 3 +++ .../http/generator/core/ControllerReader.java | 15 ++++++++++++++- .../avaje/http/generator/core/ElementReader.java | 1 - .../io/avaje/http/generator/core/MethodParam.java | 5 +++++ 6 files changed, 28 insertions(+), 2 deletions(-) create mode 100644 http-generator-client/src/test/java/io/avaje/http/generator/client/clients/Body.java diff --git a/http-generator-client/src/test/java/io/avaje/http/generator/client/ClientProcessorTest.java b/http-generator-client/src/test/java/io/avaje/http/generator/client/ClientProcessorTest.java index 645198b29..7ba558b8b 100644 --- a/http-generator-client/src/test/java/io/avaje/http/generator/client/ClientProcessorTest.java +++ b/http-generator-client/src/test/java/io/avaje/http/generator/client/ClientProcessorTest.java @@ -25,6 +25,8 @@ import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; +import io.avaje.http.client.HttpClient; + class ClientProcessorTest { @AfterEach @@ -38,6 +40,7 @@ void deleteGeneratedFiles() throws IOException { .sorted(Comparator.reverseOrder()) .map(Path::toFile) .forEach(File::delete); + } catch (final Exception e) { } } diff --git a/http-generator-client/src/test/java/io/avaje/http/generator/client/clients/Body.java b/http-generator-client/src/test/java/io/avaje/http/generator/client/clients/Body.java new file mode 100644 index 000000000..19a92a908 --- /dev/null +++ b/http-generator-client/src/test/java/io/avaje/http/generator/client/clients/Body.java @@ -0,0 +1,3 @@ +package io.avaje.http.generator.client.clients; + +public class Body {} diff --git a/http-generator-client/src/test/java/io/avaje/http/generator/client/clients/UserClient.java b/http-generator-client/src/test/java/io/avaje/http/generator/client/clients/UserClient.java index f81886c1f..7e532957a 100644 --- a/http-generator-client/src/test/java/io/avaje/http/generator/client/clients/UserClient.java +++ b/http-generator-client/src/test/java/io/avaje/http/generator/client/clients/UserClient.java @@ -11,6 +11,9 @@ public interface UserClient { @Post("/users") String createUser(@BodyString String body); + @Post("/body") + String bodies(Body... bodies); + @Get("/users/{userId}") String getUserById(String userId); } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java index 9a5f21f8a..f6c1667f3 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java @@ -328,7 +328,7 @@ public String path() { public void addImportType(String rawType) { if (rawType.indexOf('.') > 0) { - importTypes.add(rawType); + importTypes.add(sanitizeImports(rawType)); } } @@ -353,4 +353,17 @@ public Set importTypes() { public boolean hasInstrument() { return hasInstrument; } + + public static String sanitizeImports(String type) { + final int pos = type.indexOf("@"); + if (pos == -1) { + return trimArrayBrackets(type); + } + final var start = pos == 0 ? type.substring(0, pos) : ""; + return start + trimArrayBrackets(type.substring(type.lastIndexOf(' ') + 1)); + } + + private static String trimArrayBrackets(String type) { + return type.replaceAll("[^\\n\\r\\t $;\\w.]", ""); + } } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java index b43e17d31..eda7dd5ed 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java @@ -3,7 +3,6 @@ import static io.avaje.http.generator.core.ParamType.RESPONSE_HANDLER; import static io.avaje.http.generator.core.ProcessingContext.platform; import static io.avaje.http.generator.core.ProcessingContext.typeElement; -import static java.util.function.Predicate.not; import java.util.ArrayList; import java.util.HashSet; diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodParam.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodParam.java index c348c045f..7c87d0dd4 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodParam.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodParam.java @@ -83,4 +83,9 @@ public UType utype() { public void setResponseHandler() { elementParam.setResponseHandler(); } + + @Override + public String toString() { + return elementParam.toString(); + } } From ec4a6da9544b98ef72aae0e4dcfdf83605c2b3d2 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Thu, 3 Aug 2023 00:37:40 -0400 Subject: [PATCH 0834/1323] Update ClientProcessorTest.java --- .../io/avaje/http/generator/client/ClientProcessorTest.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/http-generator-client/src/test/java/io/avaje/http/generator/client/ClientProcessorTest.java b/http-generator-client/src/test/java/io/avaje/http/generator/client/ClientProcessorTest.java index 7ba558b8b..df788114e 100644 --- a/http-generator-client/src/test/java/io/avaje/http/generator/client/ClientProcessorTest.java +++ b/http-generator-client/src/test/java/io/avaje/http/generator/client/ClientProcessorTest.java @@ -18,15 +18,12 @@ import javax.tools.JavaCompiler.CompilationTask; import javax.tools.JavaFileObject; import javax.tools.JavaFileObject.Kind; -import javax.tools.StandardJavaFileManager; import javax.tools.StandardLocation; import javax.tools.ToolProvider; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; -import io.avaje.http.client.HttpClient; - class ClientProcessorTest { @AfterEach From 07861fb93d35964201d00abd981394f1d970b4e8 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Thu, 3 Aug 2023 08:48:23 -0400 Subject: [PATCH 0835/1323] Update README.md --- README.md | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index b3c66d190..8366ac892 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,7 @@ Use source code generation to adapt annotated REST controllers `@Path, @Get, @Po ``` -## Define a Controller (These APT processors work with both Java and Kotlin.) +## Define a Controller (These APT processors work with Java and Kotlin.) ```java package org.example.hello; @@ -74,7 +74,7 @@ public class WidgetController { } ``` ## DI Usage -The annotation processor will generate controller adapters that can register routes to Javalin/Helidon. The natural way to use the generated adapters is to get a DI library to find and wire them. This is what the below examples do and they use [Avaje-Inject](https://avaje.io/inject/) to do this. The AP will automatically detect the presence of avaje-inject and generate the class to use avaje-inject's `@Component` as the DI annotation. +The annotation processor will generate controller adapters to register routes to Javalin/Helidon. The natural way to use the generated adapters is to get a DI library to find and wire them. This is what the examples below do; they use [Avaje-Inject](https://avaje.io/inject/) to do this. The AP will automatically detect the presence of avaje-inject and generate the class to use avaje-inject's `@Component` as the DI annotation. There isn't a hard requirement to use Avaje for dependency injection. In the absence of avaje-inject, the generated class will use `@jakarta.inject.Singleton` or `@javax.inject.Singleton` depending on what's on the classpath. Any DI library that can find and wire the generated @Singleton beans can be used. You can even use Dagger2 or Guice to wire the controllers if you so desire. @@ -93,15 +93,13 @@ To force the AP to generate with `@javax.inject.Singleton`(in the case where you ### Usage with Javalin -The annotation processor will generate controller classes implementing the WebRoutes interface, which means we can +The annotation processor will generate controller classes implementing the Javalin `Plugin` interface, which means we can get all the WebRoutes and register them with Javalin using: ```java -List routes = BeanScope.builder().build().list(WebRoutes.class); +List routes = BeanScope.builder().build().list(Plugin.class); -Javalin.create() - .routes(() -> routes.forEach(WebRoutes::registerRoutes)) - .start(); +Javalin.create(cfg -> routes.forEach(cfg.plugins::register)); ``` ### Usage with Helidon Nima @@ -110,12 +108,10 @@ The annotation processor will generate controller classes implementing the Helid get all the services and register them with the Helidon `HttpRouting`. ```java -List routes = BeanScope.builder().build().list(HttpService.class); +List routes = BeanScope.builder().build().list(HttpFeature.class); final var builder = HttpRouting.builder(); -for (final HttpService httpService : routes) { - httpService.routing(builder); -} +routes.forEach(builder::register); WebServer.builder() .addRouting(builder.build()) From b15b4f300e88d0cc87ca01f22344411a05e61e41 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Thu, 3 Aug 2023 08:53:24 -0400 Subject: [PATCH 0836/1323] Update README.md --- README.md | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 8366ac892..9012234ae 100644 --- a/README.md +++ b/README.md @@ -125,7 +125,7 @@ WebServer.builder() ```java @Generated("avaje-javalin-generator") @Singleton -public class WidgetController$Route implements WebRoutes { +public class WidgetController$Route implements Plugin { private final WidgetController controller; @@ -134,16 +134,16 @@ public class WidgetController$Route implements WebRoutes { } @Override - public void registerRoutes() { + public void apply(Javalin app) { - ApiBuilder.get("/widgets/{id}", ctx -> { + app.get("/widgets/{id}", ctx -> { ctx.status(200); var id = asInt(ctx.pathParam("id")); var result = controller.getById(id); ctx.json(result); }); - ApiBuilder.get("/widgets", ctx -> { + app.get("/widgets", ctx -> { ctx.status(200); var result = controller.getAll(); ctx.json(result); @@ -158,7 +158,7 @@ public class WidgetController$Route implements WebRoutes { ```java @Generated("avaje-helidon-nima-generator") @Singleton -public class WidgetController$Route implements HttpService { +public class WidgetController$Route implements HttpFeature { private final WidgetController controller; public WidgetController$Route(WidgetController controller) { @@ -166,9 +166,9 @@ public class WidgetController$Route implements HttpService { } @Override - public void routing(HttpRules rules) throws Exception { - rules.get("/widgets/{id}", this::_getById); - rules.get("/widgets", this::_getAll); + public void setup(HttpRouting.Builder routing) { + routing.get("/widgets/{id}", this::_getById); + routing.get("/widgets", this::_getAll); } private void _getById(ServerRequest req, ServerResponse res) throws Exception { @@ -193,7 +193,7 @@ If [Avaje-Jsonb](https://github.com/avaje/avaje-jsonb) is detected, http generat ```java @Generated("avaje-javalin-generator") @Component -public class WidgetController$Route implements WebRoutes { +public class WidgetController$Route implements Plugin { private final WidgetController controller; private final JsonType> listWidgetJsonType; @@ -206,16 +206,16 @@ public class WidgetController$Route implements WebRoutes { } @Override - public void registerRoutes() { + public void apply(Javalin app) { - ApiBuilder.get("/widgets/{id}", ctx -> { + app.get("/widgets/{id}", ctx -> { ctx.status(200); var id = asInt(ctx.pathParam("id")); var result = controller.getById(id); widgetJsonType.toJson(result, ctx.contentType("application/json").outputStream()); }); - ApiBuilder.get("/widgets", ctx -> { + app.get("/widgets", ctx -> { ctx.status(200); var result = controller.getAll(); listWidgetJsonType.toJson(result, ctx.contentType("application/json").outputStream()); @@ -230,8 +230,7 @@ public class WidgetController$Route implements WebRoutes { ```java @Generated("avaje-helidon-nima-generator") @Component -public class WidgetController$Route implements HttpService { - +public class WidgetController$Route implements HttpFeature { private final WidgetController controller; private final JsonType widgetJsonType; @@ -244,9 +243,9 @@ public class WidgetController$Route implements HttpService { } @Override - public void routing(HttpRules rules) { - rules.get("/widgets/{id}", this::_getById); - rules.get("/widgets", this::_getAll); + public void setup(HttpRouting.Builder routing) { + routing.get("/widgets/{id}", this::_getById); + routing.get("/widgets", this::_getAll); } private void _getById(ServerRequest req, ServerResponse res) throws Exception { From bf6133f26678b1ed27c554aead426e8e19246d0d Mon Sep 17 00:00:00 2001 From: "robin.bygrave" Date: Mon, 7 Aug 2023 16:11:45 +1200 Subject: [PATCH 0837/1323] Add maven test profile as activeByDefault does not work in this scenario --- .github/workflows/build.yml | 2 +- .github/workflows/jdk-ea.yml | 2 +- pom.xml | 6 ++---- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e8bba21d3..79f2dfe63 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -33,4 +33,4 @@ jobs: env: JAVA_VERSION: ${{ matrix.java_version }} run: | - mvn clean package + mvn clean package -Ptest diff --git a/.github/workflows/jdk-ea.yml b/.github/workflows/jdk-ea.yml index 71a9bdf27..136a846cb 100644 --- a/.github/workflows/jdk-ea.yml +++ b/.github/workflows/jdk-ea.yml @@ -37,5 +37,5 @@ jobs: - name: Maven version run: mvn --version - name: Build with Maven - run: mvn clean verify package + run: mvn clean verify package -Ptest diff --git a/pom.xml b/pom.xml index ace58e970..51289ceb4 100644 --- a/pom.xml +++ b/pom.xml @@ -44,6 +44,7 @@ http-generator-javalin http-generator-jex http-generator-client + tests @@ -51,10 +52,7 @@ central - default - - true - + test tests From 120f670d89fabd2a5caf9e09507409e02b7f0f68 Mon Sep 17 00:00:00 2001 From: "robin.bygrave" Date: Mon, 7 Aug 2023 16:13:34 +1200 Subject: [PATCH 0838/1323] Fix Nima tests, filter chain must proceed() --- tests/test-nima-jsonb/pom.xml | 7 +++++++ .../src/main/java/org/example/TestController.java | 6 +++--- .../src/test/java/org/example/TestPair.java | 2 -- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 4260c1877..db96f2349 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -63,6 +63,13 @@ 1.1 test + + + io.avaje + avaje-http-helidon-generator + ${project.version} + test + diff --git a/tests/test-nima-jsonb/src/main/java/org/example/TestController.java b/tests/test-nima-jsonb/src/main/java/org/example/TestController.java index f20a41090..a16091687 100644 --- a/tests/test-nima-jsonb/src/main/java/org/example/TestController.java +++ b/tests/test-nima-jsonb/src/main/java/org/example/TestController.java @@ -86,9 +86,8 @@ Map strBody2() { } @ExceptionHandler - String exception(Exception ex) { - - return ""; + String exception(IllegalArgumentException ex) { + return "Err: " + ex; } @ExceptionHandler @@ -105,5 +104,6 @@ void exceptionVoid(ServerResponse res) { @Filter void filter(FilterChain chain, RoutingResponse res) { System.err.println("do nothing lmao"); + chain.proceed(); } } diff --git a/tests/test-nima-jsonb/src/test/java/org/example/TestPair.java b/tests/test-nima-jsonb/src/test/java/org/example/TestPair.java index ec9590e0a..9f06d9164 100644 --- a/tests/test-nima-jsonb/src/test/java/org/example/TestPair.java +++ b/tests/test-nima-jsonb/src/test/java/org/example/TestPair.java @@ -42,9 +42,7 @@ private static HttpRouting.Builder routing() { var hc = new HelloController(); var hello = new HelloController$Route(hc, beanValidator, jsonb); - routing.addFeature(hello); - hello.setup(routing); var cr = new ThreadLocalRequestContextResolver(); var tc = new TestController(); From 96d506f2ce2078fa68a357332333e5acb3544f02 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Mon, 7 Aug 2023 21:47:13 +1200 Subject: [PATCH 0839/1323] Add statusCode attribute to ExceptionHandler To specifying the status code when the ExceptionHandler returns an object that is sent to the response --- .../io/avaje/http/api/ExceptionHandler.java | 5 ++++ .../http/generator/core/MethodReader.java | 24 ++++++++++--------- .../core/openapi/MethodDocBuilder.java | 2 +- .../helidon/nima/ControllerMethodWriter.java | 4 ++++ .../javalin/ControllerMethodWriter.java | 2 +- .../generator/jex/ControllerMethodWriter.java | 2 +- .../java/org/example/ErrorController.java | 2 +- .../java/org/example/HelloController.java | 6 ++++- .../main/java/org/example/TestController.java | 3 +-- .../java/org/example/TestControllerTest.java | 13 +++++++++- .../src/test/java/org/example/TestPair.java | 4 ++++ 11 files changed, 48 insertions(+), 19 deletions(-) diff --git a/http-api/src/main/java/io/avaje/http/api/ExceptionHandler.java b/http-api/src/main/java/io/avaje/http/api/ExceptionHandler.java index 8a18e40ce..a9de0e1b3 100644 --- a/http-api/src/main/java/io/avaje/http/api/ExceptionHandler.java +++ b/http-api/src/main/java/io/avaje/http/api/ExceptionHandler.java @@ -37,4 +37,9 @@ * the method argument list. */ Class value() default DefaultException.class; + + /** + * The response status code to use. + */ + int statusCode() default 0; } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java index adf464ecf..24ffc165b 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java @@ -48,6 +48,7 @@ public class MethodReader { private final Optional timeout; private WebMethod webMethod; + private int statusCode; private String webMethodPath; private boolean formMarker; private final boolean instrumentContext; @@ -151,7 +152,7 @@ private void initWebMethodViaAnnotation() { .ifPresent(delete -> initSetWebMethod(CoreWebMethod.DELETE, delete.value())); findAnnotation(ExceptionHandlerPrism::getOptionalOn) - .ifPresent(error -> initSetWebMethod(CoreWebMethod.ERROR, error.value())); + .ifPresent(error -> initSetWebMethod(CoreWebMethod.ERROR, error)); findAnnotation(FilterPrism::getOptionalOn) .ifPresent(filter -> initSetWebMethod(CoreWebMethod.FILTER, "")); @@ -166,9 +167,10 @@ private void initSetWebMethod(WebMethod webMethod, String value) { this.webMethodPath = value; } - private void initSetWebMethod(WebMethod webMethod, TypeMirror value) { + private void initSetWebMethod(WebMethod webMethod, ExceptionHandlerPrism exceptionPrism) { this.webMethod = webMethod; - var exType = value.toString(); + this.statusCode = exceptionPrism.statusCode(); + var exType = exceptionPrism.value().toString(); if ("io.avaje.http.api.DefaultException".equals(exType)) { exType = element.getParameters().stream() @@ -247,8 +249,7 @@ private List buildApiResponses() { .flatMap(List::stream), OpenAPIResponsePrism.getAllInstancesOn(method).stream())); - final var responses = - Stream.concat(methodResponses, superMethodResponses).collect(Collectors.toList()); + final var responses = Stream.concat(methodResponses, superMethodResponses).collect(Collectors.toList()); responses.addAll(bean.openApiResponses()); return responses; } @@ -257,8 +258,7 @@ public Optional findAnnotation(Function> prismFunc) return findAnnotation(prismFunc, element); } - public Optional findAnnotation( - Function> prismFunc, ExecutableElement elem) { + public Optional findAnnotation(Function> prismFunc, ExecutableElement elem) { return prismFunc.apply(elem).or(() -> bean.findMethodAnnotation(prismFunc, elem)); } @@ -314,7 +314,6 @@ public void buildApiDoc() { /** Build the OpenAPI documentation for the method / operation. */ public void buildApiDocumentation() { - if (!isErrorMethod() && webMethod instanceof CoreWebMethod && webMethod != CoreWebMethod.FILTER) { @@ -379,12 +378,15 @@ public TypeMirror returnType() { return element.getReturnType(); } - public String statusCode() { + public int statusCode() { + if (statusCode > 0) { + // using explicit status code + return statusCode; + } return producesAnnotation .map(ProducesPrism::defaultStatus) .filter(s -> s > 0) - .orElseGet(() -> webMethod.statusCode(isVoid)) - .toString(); + .orElseGet(() -> webMethod.statusCode(isVoid)); } public PathSegments pathSegments() { diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/MethodDocBuilder.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/MethodDocBuilder.java index 4f3a75ace..338726959 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/MethodDocBuilder.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/MethodDocBuilder.java @@ -118,7 +118,7 @@ public void build() { responses.addApiResponse(responseAnnotation.responseCode(), newResponse); } - if (!override2xx) responses.addApiResponse(methodReader.statusCode(), response); + if (!override2xx) responses.addApiResponse(String.valueOf(methodReader.statusCode()), response); } DocContext getContext() { diff --git a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java index ffea9c39b..81ea5b238 100644 --- a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java +++ b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java @@ -214,6 +214,10 @@ private boolean usesFormParams() { } private void writeContextReturn() { + int statusCode = method.statusCode(); + if (statusCode > 0) { + writer.append(" res.status(%d);", statusCode).eol(); + } final var producesOp = Optional.ofNullable(method.produces()); if (producesOp.isEmpty() && !useJsonB) { return; diff --git a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java index f336556ce..c0201830a 100644 --- a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java +++ b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java @@ -101,7 +101,7 @@ private void writeMethod(final String fullPath) { writer.append(" app.%s(\"%s\", ctx -> {", webMethod.name().toLowerCase(), fullPath).eol(); } if (!customMethod) { - writer.append(" ctx.status(%s);", method.statusCode()).eol(); + writer.append(" ctx.status(%d);", method.statusCode()).eol(); } } diff --git a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java index bf2440ded..c469f96bb 100644 --- a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java +++ b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java @@ -33,7 +33,7 @@ void write(boolean requestScoped) { final String fullPath = segments.fullPath(); writer.append(" routing.%s(\"%s\", ctx -> {", webMethod.name().toLowerCase(), fullPath).eol(); - writer.append(" ctx.status(%s);", method.statusCode()).eol(); + writer.append(" ctx.status(%d);", method.statusCode()).eol(); List matrixSegments = segments.matrixSegments(); for (PathSegments.Segment matrixSegment : matrixSegments) { diff --git a/tests/test-nima-jsonb/src/main/java/org/example/ErrorController.java b/tests/test-nima-jsonb/src/main/java/org/example/ErrorController.java index c4ae54404..bf841810b 100644 --- a/tests/test-nima-jsonb/src/main/java/org/example/ErrorController.java +++ b/tests/test-nima-jsonb/src/main/java/org/example/ErrorController.java @@ -13,7 +13,7 @@ @Controller final class ErrorController { - @ExceptionHandler + @ExceptionHandler(statusCode = 407) Map runEx(RuntimeException ex, ServerRequest req, ServerResponse res) { return Map.of("err", "" + ex); } diff --git a/tests/test-nima-jsonb/src/main/java/org/example/HelloController.java b/tests/test-nima-jsonb/src/main/java/org/example/HelloController.java index 5d03d262a..a724982ae 100644 --- a/tests/test-nima-jsonb/src/main/java/org/example/HelloController.java +++ b/tests/test-nima-jsonb/src/main/java/org/example/HelloController.java @@ -41,7 +41,6 @@ byte[] testBytes() { @Get("/helidon") void testHelidon(ServerRequest req, ServerResponse res) { - res.headers().contentType(HttpMediaType.TEXT_PLAIN); res.send("success path:" + req.path()); } @@ -61,6 +60,11 @@ String testParam(@QueryParam String param) { return param; } + @Get("/ithrowRuntimeException") + Person ithrowRuntime() { + throw new RuntimeException("foo"); + } + // curl -v localhost:8081/person/jack @Get("person/{name}") Person person(String name) { diff --git a/tests/test-nima-jsonb/src/main/java/org/example/TestController.java b/tests/test-nima-jsonb/src/main/java/org/example/TestController.java index a16091687..5fd602d5a 100644 --- a/tests/test-nima-jsonb/src/main/java/org/example/TestController.java +++ b/tests/test-nima-jsonb/src/main/java/org/example/TestController.java @@ -92,11 +92,10 @@ String exception(IllegalArgumentException ex) { @ExceptionHandler Person exceptionCtx(Exception ex, ServerRequest req, ServerResponse res) { - return new Person(0, null); } - @ExceptionHandler(RuntimeException.class) + @ExceptionHandler(IllegalStateException.class) void exceptionVoid(ServerResponse res) { System.err.println("do nothing lmao"); } diff --git a/tests/test-nima-jsonb/src/test/java/org/example/TestControllerTest.java b/tests/test-nima-jsonb/src/test/java/org/example/TestControllerTest.java index b44fa4c7c..2f9d39079 100644 --- a/tests/test-nima-jsonb/src/test/java/org/example/TestControllerTest.java +++ b/tests/test-nima-jsonb/src/test/java/org/example/TestControllerTest.java @@ -37,9 +37,20 @@ void strBody() { .POST() .asString(); - assertThat(res.statusCode()).isEqualTo(200); + assertThat(res.statusCode()).isEqualTo(201); assertThat(res.body()).isEqualTo("{\"key\":42}"); assertThat(res.headers().firstValue("Content-Type")).isPresent().get().isEqualTo("application/json"); assertThat(res.headers().firstValue("Content-Length")).isPresent(); } + + @Test + void ithrowRuntimeException() { + + HttpResponse res = client.request() + .path("ithrowRuntimeException") + .GET() + .asString(); + + assertThat(res.statusCode()).isEqualTo(407); + } } diff --git a/tests/test-nima-jsonb/src/test/java/org/example/TestPair.java b/tests/test-nima-jsonb/src/test/java/org/example/TestPair.java index 9f06d9164..a2d8bec07 100644 --- a/tests/test-nima-jsonb/src/test/java/org/example/TestPair.java +++ b/tests/test-nima-jsonb/src/test/java/org/example/TestPair.java @@ -40,6 +40,10 @@ private static HttpRouting.Builder routing() { var beanValidator = new BeanValidator(); Jsonb jsonb = Jsonb.builder().build(); + var ec = new ErrorController(); + var ecRoute = new ErrorController$Route(ec, jsonb); + routing.addFeature(ecRoute); + var hc = new HelloController(); var hello = new HelloController$Route(hc, beanValidator, jsonb); routing.addFeature(hello); From cd2e7da06324f1158435ff3b60499080c72b60f5 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Mon, 7 Aug 2023 22:09:52 +1200 Subject: [PATCH 0840/1323] Rename Produces defaultStatus -> statusCode In line with ExceptionHandler and more obvious as to what it does --- .../src/main/java/io/avaje/http/api/Produces.java | 4 ++-- .../io/avaje/http/generator/core/MethodReader.java | 4 ++-- .../example/myapp/web/test/OpenAPIController.java | 2 +- .../src/main/java/org/example/TestController.java | 7 ++++++- .../test/java/org/example/TestControllerTest.java | 13 +++++++++++++ 5 files changed, 24 insertions(+), 6 deletions(-) diff --git a/http-api/src/main/java/io/avaje/http/api/Produces.java b/http-api/src/main/java/io/avaje/http/api/Produces.java index 6af67d961..09b4db9a6 100644 --- a/http-api/src/main/java/io/avaje/http/api/Produces.java +++ b/http-api/src/main/java/io/avaje/http/api/Produces.java @@ -36,7 +36,7 @@ String value() default MediaType.APPLICATION_JSON; /** - * The default status code of the generated route. + * The status code of the route when successful. * *

    When not specified, the default status are as follows:
    * GET(200)
    @@ -45,5 +45,5 @@ * PATCH(200, void methods 204)
    * DELETE(200, void methods 204) */ - int defaultStatus() default 0; + int statusCode() default 0; } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java index 24ffc165b..26ae68fc3 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java @@ -352,7 +352,7 @@ public boolean isVoid() { } public boolean hasProducesStatus() { - return producesAnnotation.map(ProducesPrism::defaultStatus).filter(s -> s > 0).isPresent(); + return producesAnnotation.map(ProducesPrism::statusCode).filter(s -> s > 0).isPresent(); } public String produces() { @@ -384,7 +384,7 @@ public int statusCode() { return statusCode; } return producesAnnotation - .map(ProducesPrism::defaultStatus) + .map(ProducesPrism::statusCode) .filter(s -> s > 0) .orElseGet(() -> webMethod.statusCode(isVoid)); } diff --git a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/OpenAPIController.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/OpenAPIController.java index 3de0989c0..709e76b43 100644 --- a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/OpenAPIController.java +++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/OpenAPIController.java @@ -84,7 +84,7 @@ Person testPostList(List m) { } @Put("/put") - @Produces(value = MediaType.TEXT_PLAIN, defaultStatus = 203) + @Produces(value = MediaType.TEXT_PLAIN, statusCode = 203) @OpenAPIResponse(responseCode = "204", type = String.class) String testDefaultStatus(Context ctx) { if (ctx.contentType().equals(MediaType.APPLICATION_PDF)) { diff --git a/tests/test-nima-jsonb/src/main/java/org/example/TestController.java b/tests/test-nima-jsonb/src/main/java/org/example/TestController.java index 5fd602d5a..e098a2230 100644 --- a/tests/test-nima-jsonb/src/main/java/org/example/TestController.java +++ b/tests/test-nima-jsonb/src/main/java/org/example/TestController.java @@ -1,6 +1,7 @@ package org.example; import java.io.InputStream; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; @@ -80,9 +81,13 @@ String strBody(@BodyString String body) { return body; } + @Produces(statusCode=202) @Post("/blah") Map strBody2() { - return Map.of("hi", "yo", "level", 42L); + var map = new LinkedHashMap(); + map.put("hi", "yo"); + map.put("level", 42L); + return map; } @ExceptionHandler diff --git a/tests/test-nima-jsonb/src/test/java/org/example/TestControllerTest.java b/tests/test-nima-jsonb/src/test/java/org/example/TestControllerTest.java index 2f9d39079..1075bc0df 100644 --- a/tests/test-nima-jsonb/src/test/java/org/example/TestControllerTest.java +++ b/tests/test-nima-jsonb/src/test/java/org/example/TestControllerTest.java @@ -43,6 +43,19 @@ void strBody() { assertThat(res.headers().firstValue("Content-Length")).isPresent(); } + @Test + void blah() { + HttpResponse res = client.request() + .path("test/blah") + .POST() + .asString(); + + assertThat(res.statusCode()).isEqualTo(202); + assertThat(res.body()).isEqualTo("{\"hi\":\"yo\",\"level\":42}"); + assertThat(res.headers().firstValue("Content-Type")).isPresent().get().isEqualTo("application/json"); + assertThat(res.headers().firstValue("Content-Length")).isPresent(); + } + @Test void ithrowRuntimeException() { From 16cbd275cd7d174e605a1796a62066e6a814a2b7 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Mon, 7 Aug 2023 22:45:22 +1200 Subject: [PATCH 0841/1323] Add some mor tests for Nima exception handling --- .../java/org/example/HelloController.java | 10 ++++++ .../main/java/org/example/TestController.java | 31 +++++++------------ .../java/org/example/TestControllerTest.java | 22 ++++++++++++- 3 files changed, 42 insertions(+), 21 deletions(-) diff --git a/tests/test-nima-jsonb/src/main/java/org/example/HelloController.java b/tests/test-nima-jsonb/src/main/java/org/example/HelloController.java index a724982ae..cdea59920 100644 --- a/tests/test-nima-jsonb/src/main/java/org/example/HelloController.java +++ b/tests/test-nima-jsonb/src/main/java/org/example/HelloController.java @@ -65,6 +65,16 @@ Person ithrowRuntime() { throw new RuntimeException("foo"); } + @Get("/ithrowException") + Person ithrowException() throws Exception { + throw new Exception("ithrowException"); + } + + @Get("/ithrowIllegalStateException") + Person ithrowIllegalStateException() { + throw new IllegalStateException("ithrowIllegalStateException"); + } + // curl -v localhost:8081/person/jack @Get("person/{name}") Person person(String name) { diff --git a/tests/test-nima-jsonb/src/main/java/org/example/TestController.java b/tests/test-nima-jsonb/src/main/java/org/example/TestController.java index e098a2230..6b2412921 100644 --- a/tests/test-nima-jsonb/src/main/java/org/example/TestController.java +++ b/tests/test-nima-jsonb/src/main/java/org/example/TestController.java @@ -1,29 +1,17 @@ package org.example; +import io.avaje.http.api.*; +import io.helidon.nima.webserver.http.FilterChain; +import io.helidon.nima.webserver.http.RoutingResponse; +import io.helidon.nima.webserver.http.ServerRequest; +import io.helidon.nima.webserver.http.ServerResponse; + import java.io.InputStream; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; -import io.avaje.http.api.BodyString; -import io.avaje.http.api.Controller; -import io.avaje.http.api.Default; -import io.avaje.http.api.ExceptionHandler; -import io.avaje.http.api.Filter; -import io.avaje.http.api.Form; -import io.avaje.http.api.FormParam; -import io.avaje.http.api.Get; -import io.avaje.http.api.InstrumentServerContext; -import io.avaje.http.api.Path; -import io.avaje.http.api.Post; -import io.avaje.http.api.Produces; -import io.avaje.http.api.QueryParam; -import io.helidon.nima.webserver.http.FilterChain; -import io.helidon.nima.webserver.http.RoutingResponse; -import io.helidon.nima.webserver.http.ServerRequest; -import io.helidon.nima.webserver.http.ServerResponse; - @Path("test") @Controller public class TestController { @@ -81,7 +69,7 @@ String strBody(@BodyString String body) { return body; } - @Produces(statusCode=202) + @Produces(statusCode = 202) @Post("/blah") Map strBody2() { var map = new LinkedHashMap(); @@ -95,14 +83,17 @@ String exception(IllegalArgumentException ex) { return "Err: " + ex; } + @Produces(statusCode = 501) @ExceptionHandler Person exceptionCtx(Exception ex, ServerRequest req, ServerResponse res) { + res.header("X-Foo", "WasHere"); return new Person(0, null); } @ExceptionHandler(IllegalStateException.class) void exceptionVoid(ServerResponse res) { - System.err.println("do nothing lmao"); + res.status(503); + res.send("IllegalStateException"); } @Filter diff --git a/tests/test-nima-jsonb/src/test/java/org/example/TestControllerTest.java b/tests/test-nima-jsonb/src/test/java/org/example/TestControllerTest.java index 1075bc0df..22c6250b5 100644 --- a/tests/test-nima-jsonb/src/test/java/org/example/TestControllerTest.java +++ b/tests/test-nima-jsonb/src/test/java/org/example/TestControllerTest.java @@ -58,7 +58,6 @@ void blah() { @Test void ithrowRuntimeException() { - HttpResponse res = client.request() .path("ithrowRuntimeException") .GET() @@ -66,4 +65,25 @@ void ithrowRuntimeException() { assertThat(res.statusCode()).isEqualTo(407); } + + @Test + void ithrowException() { + HttpResponse res = client.request() + .path("ithrowException") + .GET() + .asString(); + + assertThat(res.statusCode()).isEqualTo(501); + assertThat(res.headers().firstValue("X-Foo").orElse("")).isEqualTo("WasHere"); + } + + @Test + void ithrowIllegalStateException() { + HttpResponse res = client.request() + .path("ithrowIllegalStateException") + .GET() + .asString(); + + assertThat(res.statusCode()).isEqualTo(503); + } } From 2a75a3b2efce0dfc5b8f053b29db560179d4183b Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Mon, 7 Aug 2023 22:00:13 -0400 Subject: [PATCH 0842/1323] VarArg client generates correctly --- .../generator/client/ClientMethodWriter.java | 9 +++++++-- .../avaje/http/generator/core/MethodParam.java | 5 +++++ .../java/io/avaje/http/generator/core/Util.java | 17 +++++++++++++++++ 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java index 0729ca45d..137ecb86c 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java @@ -56,11 +56,16 @@ private void methodStart(Append writer) { if (count++ > 0) { writer.append(", "); } - var paramType = + final var isVarArg = Util.isVarArg(param.element()); + + final var paramType = "java.util.function.Supplier".equals(param.utype().full()) ? "Supplier" : param.utype().shortType(); - writer.append(paramType).append(" "); + + final var finalType = + isVarArg ? paramType.substring(0, paramType.length() - 2) + "..." : paramType; + writer.append(finalType).append(" "); writer.append(param.name()); } writer.append(") {").eol(); diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodParam.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodParam.java index 7c87d0dd4..431773b70 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodParam.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodParam.java @@ -2,6 +2,7 @@ import static io.avaje.http.generator.core.ProcessingContext.asElement; +import javax.lang.model.element.Element; import javax.lang.model.element.ElementKind; import javax.lang.model.element.VariableElement; @@ -84,6 +85,10 @@ public void setResponseHandler() { elementParam.setResponseHandler(); } + public VariableElement element() { + return (VariableElement) elementParam.element(); + } + @Override public String toString() { return elementParam.toString(); diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/Util.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/Util.java index 779f63fe5..adaac5a46 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/Util.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/Util.java @@ -9,6 +9,7 @@ import javax.lang.model.type.TypeMirror; import javax.lang.model.util.SimpleAnnotationValueVisitor8; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.regex.Matcher; @@ -225,6 +226,22 @@ public static UType parseType(TypeMirror returnType) { return parse(returnType.toString()); } + public static boolean isVarArg(VariableElement element) { + var methodString = Util.trimAnnotations(element.getEnclosingElement().toString()); + var typeString = Util.trimAnnotations(element.asType().toString()).replace("[]", ""); + Pattern pattern = Pattern.compile("\\((.*?)\\)"); + Matcher matcher = pattern.matcher(methodString); + + if (matcher.find()) { + var params = matcher.group(1); + + return Arrays.stream(params.split(",")) + .filter(s -> s.contains(typeString)) + .anyMatch(s -> s.endsWith("...")); + } + return false; + } + private static class RoleReader extends SimpleAnnotationValueVisitor8, Object> { private final List fullRoles = new ArrayList<>(); From 532b4159db22a53d6667a9c2d3910703f4f22be7 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Mon, 7 Aug 2023 22:06:11 -0400 Subject: [PATCH 0843/1323] Update Util.java --- .../src/main/java/io/avaje/http/generator/core/Util.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/Util.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/Util.java index adaac5a46..30636bfbc 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/Util.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/Util.java @@ -236,7 +236,7 @@ public static boolean isVarArg(VariableElement element) { var params = matcher.group(1); return Arrays.stream(params.split(",")) - .filter(s -> s.contains(typeString)) + .filter(s -> s.replace("[]", "").contains(typeString)) .anyMatch(s -> s.endsWith("...")); } return false; From dc80f7cc3441215a84bdd992235e6f0105cd382c Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Mon, 7 Aug 2023 22:20:08 -0400 Subject: [PATCH 0844/1323] Catch any other wacky edge cases --- .../http/generator/client/ClientMethodWriter.java | 8 ++++++-- .../http/generator/client/clients/UserClient.java | 4 ++++ .../java/io/avaje/http/generator/core/Util.java | 15 ++++++--------- 3 files changed, 16 insertions(+), 11 deletions(-) diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java index 137ecb86c..c923a7e31 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java @@ -4,6 +4,8 @@ import io.avaje.http.generator.core.*; import javax.lang.model.element.TypeElement; + +import java.util.List; import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; @@ -52,11 +54,13 @@ private void methodStart(Append writer) { AnnotationUtil.writeAnnotations(writer, method.element()); writer.append(" public %s%s %s(", methodGenericParams, returnType.shortType(), method.simpleName()); int count = 0; - for (MethodParam param : method.params()) { + List params = method.params(); + for (int i = 0; i < params.size(); i++) { + MethodParam param = params.get(i); if (count++ > 0) { writer.append(", "); } - final var isVarArg = Util.isVarArg(param.element()); + final var isVarArg = Util.isVarArg(param.element(), i); final var paramType = "java.util.function.Supplier".equals(param.utype().full()) diff --git a/http-generator-client/src/test/java/io/avaje/http/generator/client/clients/UserClient.java b/http-generator-client/src/test/java/io/avaje/http/generator/client/clients/UserClient.java index 7e532957a..f4e3d6163 100644 --- a/http-generator-client/src/test/java/io/avaje/http/generator/client/clients/UserClient.java +++ b/http-generator-client/src/test/java/io/avaje/http/generator/client/clients/UserClient.java @@ -3,6 +3,7 @@ import io.avaje.http.api.BodyString; import io.avaje.http.api.Client; import io.avaje.http.api.Get; +import io.avaje.http.api.Header; import io.avaje.http.api.Post; @Client(generate = false) @@ -14,6 +15,9 @@ public interface UserClient { @Post("/body") String bodies(Body... bodies); + @Post("/body2") + String bodies2(@Header String head, Body... bodies); + @Get("/users/{userId}") String getUserById(String userId); } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/Util.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/Util.java index 30636bfbc..2ae52e729 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/Util.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/Util.java @@ -9,7 +9,6 @@ import javax.lang.model.type.TypeMirror; import javax.lang.model.util.SimpleAnnotationValueVisitor8; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.regex.Matcher; @@ -22,6 +21,7 @@ public class Util { // comma not in quotes private static final Pattern COMMA_PATTERN = Pattern.compile(", (?=(?:[^\\\"]*\\\"[^\\\"]*\\\")*[^\\\"]*$)"); + private static final Pattern PARENTHESIS_CONTENT = Pattern.compile("\\((.*?)\\)"); /** * Parse the raw type potentially handling generic parameters. @@ -226,22 +226,19 @@ public static UType parseType(TypeMirror returnType) { return parse(returnType.toString()); } - public static boolean isVarArg(VariableElement element) { + public static boolean isVarArg(VariableElement element, int order) { var methodString = Util.trimAnnotations(element.getEnclosingElement().toString()); var typeString = Util.trimAnnotations(element.asType().toString()).replace("[]", ""); - Pattern pattern = Pattern.compile("\\((.*?)\\)"); - Matcher matcher = pattern.matcher(methodString); + Matcher matcher = PARENTHESIS_CONTENT.matcher(methodString); if (matcher.find()) { - var params = matcher.group(1); + var param = matcher.group(1).split(",")[order]; - return Arrays.stream(params.split(",")) - .filter(s -> s.replace("[]", "").contains(typeString)) - .anyMatch(s -> s.endsWith("...")); + return param.replace("[]", "").contains(typeString) && param.endsWith("..."); } return false; } - + private static class RoleReader extends SimpleAnnotationValueVisitor8, Object> { private final List fullRoles = new ArrayList<>(); From 7eca7fda75d9126bcb6a0b8783fc30529ad75717 Mon Sep 17 00:00:00 2001 From: "robin.bygrave" Date: Tue, 8 Aug 2023 14:24:10 +1200 Subject: [PATCH 0845/1323] Inline generated code for validation language --- .../main/java/io/avaje/http/generator/core/ElementReader.java | 4 +--- .../avaje/http/generator/helidon/nima/ControllerWriter.java | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java index eda7dd5ed..d9545eda7 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java @@ -283,10 +283,8 @@ void writeValidate(Append writer) { if (!contextType && typeHandler == null) { final var indent = platform().indent(); if (useValidation) { - writer.append("%s var validLanguage = ", indent); + writer.append("%s validator.validate(%s, ", indent, varName); platform().writeAcceptLanguage(writer); - writer.append(";").eol(); - writer.append("%s validator.validate(%s, validLanguage", indent, varName); validationGroups.forEach(g -> writer.append(", %s", Util.shortName(g))); writer.append(");").eol(); } else { diff --git a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java index 432e3d430..f74796170 100644 --- a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java +++ b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java @@ -21,7 +21,7 @@ */ class ControllerWriter extends BaseControllerWriter { - private static final String AT_GENERATED = "@Generated(\"avaje-helidon-nima-generator\")"; + private static final String AT_GENERATED = "@Generated(\"avaje-helidon-generator\")"; private final boolean useJsonB; private final Map jsonTypes; From 8f89ef88f9e301cb1591c0c61eb9507022c1bd84 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Mon, 7 Aug 2023 22:24:48 -0400 Subject: [PATCH 0846/1323] Update Util.java --- .../src/main/java/io/avaje/http/generator/core/Util.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/Util.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/Util.java index 2ae52e729..06c6fcaff 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/Util.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/Util.java @@ -226,13 +226,13 @@ public static UType parseType(TypeMirror returnType) { return parse(returnType.toString()); } - public static boolean isVarArg(VariableElement element, int order) { + public static boolean isVarArg(VariableElement element, int position) { var methodString = Util.trimAnnotations(element.getEnclosingElement().toString()); var typeString = Util.trimAnnotations(element.asType().toString()).replace("[]", ""); Matcher matcher = PARENTHESIS_CONTENT.matcher(methodString); if (matcher.find()) { - var param = matcher.group(1).split(",")[order]; + var param = matcher.group(1).split(",")[position]; return param.replace("[]", "").contains(typeString) && param.endsWith("..."); } From d308cd4756306563d8b6e0d31c001326760b2002 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Mon, 7 Aug 2023 22:32:12 -0400 Subject: [PATCH 0847/1323] Update ControllerMethodWriter.java --- .../avaje/http/generator/javalin/ControllerMethodWriter.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java index c0201830a..24458d3f8 100644 --- a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java +++ b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java @@ -129,12 +129,12 @@ private void writeContextReturn() { if (instrumentContext) { writer.append(" if (ctx.resultInputStream() != null || ctx.res().isCommitted()) return;").eol(); } - // Support for CompletableFuture's. final UType type = UType.parse(method.returnType()); if ("java.util.concurrent.CompletableFuture".equals(type.mainType())) { if (!type.isGeneric()) { - throw new IllegalStateException( + logError( + method.element(), "CompletableFuture must be generic type (e.g. CompletableFuture, CompletableFuture)."); } From 8bbadc1eb9b020116692261fdb77a6b06f049714 Mon Sep 17 00:00:00 2001 From: "robin.bygrave" Date: Tue, 8 Aug 2023 15:28:04 +1200 Subject: [PATCH 0848/1323] Only generated response status code when statusCode > 0 Support use case that requires programmatic control of status code but non-void controller method. This might be marginal but I don't think its a negative. --- .../http/generator/core/MethodReader.java | 4 ++-- .../helidon/nima/ControllerMethodWriter.java | 6 ++--- .../javalin/ControllerMethodWriter.java | 5 +++- .../generator/jex/ControllerMethodWriter.java | 5 +++- .../example/myapp/web/HelloController.java | 7 ++++++ .../src/main/resources/public/openapi.json | 23 ++++++++++++++++++- .../example/myapp/HelloControllerTest.java | 12 ++++++++++ .../main/java/org/example/TestController.java | 7 ++++++ .../java/org/example/TestControllerTest.java | 14 +++++++++++ 9 files changed, 75 insertions(+), 8 deletions(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java index 26ae68fc3..605d5a1e6 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java @@ -379,13 +379,13 @@ public TypeMirror returnType() { } public int statusCode() { - if (statusCode > 0) { + if (statusCode != 0) { // using explicit status code return statusCode; } return producesAnnotation .map(ProducesPrism::statusCode) - .filter(s -> s > 0) + .filter(s -> s != 0) .orElseGet(() -> webMethod.statusCode(isVoid)); } diff --git a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java index 81ea5b238..4c708ef78 100644 --- a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java +++ b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java @@ -226,9 +226,9 @@ private void writeContextReturn() { final var produces = producesOp.map(MediaType::parse).orElse(MediaType.APPLICATION_JSON); final var contentTypeString = " res.headers().contentType(HttpMediaType."; switch (produces) { - case APPLICATION_JSON -> writer.append(contentTypeString + "APPLICATION_JSON);").eol(); - case TEXT_HTML -> writer.append(contentTypeString + "TEXT_HTML);").eol(); - case TEXT_PLAIN -> writer.append(contentTypeString + "TEXT_PLAIN);").eol(); + case APPLICATION_JSON -> writer.append(contentTypeString).append("APPLICATION_JSON);").eol(); + case TEXT_HTML -> writer.append(contentTypeString).append("TEXT_HTML);").eol(); + case TEXT_PLAIN -> writer.append(contentTypeString).append("TEXT_PLAIN);").eol(); case UNKNOWN -> writer.append(contentTypeString + "create(\"%s\"));", producesOp.orElse("UNKNOWN")).eol(); } } diff --git a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java index c0201830a..60283287b 100644 --- a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java +++ b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java @@ -101,7 +101,10 @@ private void writeMethod(final String fullPath) { writer.append(" app.%s(\"%s\", ctx -> {", webMethod.name().toLowerCase(), fullPath).eol(); } if (!customMethod) { - writer.append(" ctx.status(%d);", method.statusCode()).eol(); + int statusCode = method.statusCode(); + if (statusCode > 0) { + writer.append(" ctx.status(%d);", statusCode).eol(); + } } } diff --git a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java index c469f96bb..dc663e297 100644 --- a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java +++ b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java @@ -33,7 +33,10 @@ void write(boolean requestScoped) { final String fullPath = segments.fullPath(); writer.append(" routing.%s(\"%s\", ctx -> {", webMethod.name().toLowerCase(), fullPath).eol(); - writer.append(" ctx.status(%d);", method.statusCode()).eol(); + int statusCode = method.statusCode(); + if (statusCode > 0) { + writer.append(" ctx.status(%d);", statusCode).eol(); + } List matrixSegments = segments.matrixSegments(); for (PathSegments.Segment matrixSegment : matrixSegments) { diff --git a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/HelloController.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/HelloController.java index e2d4d7de2..a918215ed 100644 --- a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/HelloController.java +++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/HelloController.java @@ -175,4 +175,11 @@ String getWithMatrixParam(int year, String author, String country, String other, String slashAccepting(String name, String nam0, String nam1) { return "got name:" + name + " splat0:" + nam0 + " splat1:" + nam1; } + + @Produces(value = "text/plain") + @Get("controlStatusCode") + String controlStatusCode(Context ctx) { + ctx.status(201); + return "controlStatusCode"; + } } diff --git a/tests/test-javalin-jsonb/src/main/resources/public/openapi.json b/tests/test-javalin-jsonb/src/main/resources/public/openapi.json index fb5692c1a..e7a10cdbe 100644 --- a/tests/test-javalin-jsonb/src/main/resources/public/openapi.json +++ b/tests/test-javalin-jsonb/src/main/resources/public/openapi.json @@ -1,7 +1,7 @@ { "openapi" : "3.0.1", "info" : { - "title" : "Example service showing off the Path extension method of controller", + "title" : "Example service", "description" : "Example Javalin controllers with Java and Maven", "version" : "" }, @@ -348,6 +348,27 @@ } } }, + "/hello/controlStatusCode" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, "/hello/findbyname/{name}" : { "get" : { "tags" : [ diff --git a/tests/test-javalin-jsonb/src/test/java/org/example/myapp/HelloControllerTest.java b/tests/test-javalin-jsonb/src/test/java/org/example/myapp/HelloControllerTest.java index 37bb0d875..80f8619cb 100644 --- a/tests/test-javalin-jsonb/src/test/java/org/example/myapp/HelloControllerTest.java +++ b/tests/test-javalin-jsonb/src/test/java/org/example/myapp/HelloControllerTest.java @@ -321,4 +321,16 @@ void get_slashAcceptingPath_expect200() { assertThat(hres.statusCode()).isEqualTo(200); assertEquals("got name:one splat0:a/b splat1:x/y/z", hres.body()); } + + @Test + void get_controlStatusCode_expect201() { + final HttpResponse hres = client.request() + .path("hello/controlStatusCode") + .GET() + .asString(); + + assertThat(hres.statusCode()).isEqualTo(201); + assertEquals("controlStatusCode", hres.body()); + } + } diff --git a/tests/test-nima-jsonb/src/main/java/org/example/TestController.java b/tests/test-nima-jsonb/src/main/java/org/example/TestController.java index 6b2412921..58eca902d 100644 --- a/tests/test-nima-jsonb/src/main/java/org/example/TestController.java +++ b/tests/test-nima-jsonb/src/main/java/org/example/TestController.java @@ -78,6 +78,13 @@ Map strBody2() { return map; } + @Produces(statusCode = -1) // Can use -1 to programmatically set the ServerResponse statusCode + @Post("/strBody3") + Map strBody3(ServerResponse res) { + res.status(200); + return Map.of("hi", "strBody3"); + } + @ExceptionHandler String exception(IllegalArgumentException ex) { return "Err: " + ex; diff --git a/tests/test-nima-jsonb/src/test/java/org/example/TestControllerTest.java b/tests/test-nima-jsonb/src/test/java/org/example/TestControllerTest.java index 22c6250b5..a02981546 100644 --- a/tests/test-nima-jsonb/src/test/java/org/example/TestControllerTest.java +++ b/tests/test-nima-jsonb/src/test/java/org/example/TestControllerTest.java @@ -43,6 +43,20 @@ void strBody() { assertThat(res.headers().firstValue("Content-Length")).isPresent(); } + @Test + void strBody3() { + HttpResponse res = client.request() + .path("test/strBody3") + .body("{\"key\":42}") + .POST() + .asString(); + + assertThat(res.statusCode()).isEqualTo(200); + assertThat(res.body()).isEqualTo("{\"hi\":\"strBody3\"}"); + assertThat(res.headers().firstValue("Content-Type")).isPresent().get().isEqualTo("application/json"); + assertThat(res.headers().firstValue("Content-Length")).isPresent(); + } + @Test void blah() { HttpResponse res = client.request() From 110b1b37f52534997c4d5f54b5bd41e80ab45167 Mon Sep 17 00:00:00 2001 From: "robin.bygrave" Date: Tue, 8 Aug 2023 16:16:42 +1200 Subject: [PATCH 0849/1323] Nima - use Nima's Http.Status enum when the status code is known This makes it the generated code look like: res.status(OK_200); Rather than: res.status(200); --- .../helidon/nima/ControllerMethodWriter.java | 47 ++++++++++++++++++- .../helidon/nima/ControllerWriter.java | 10 ++++ .../java/org/example/ErrorController.java | 2 +- 3 files changed, 56 insertions(+), 3 deletions(-) diff --git a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java index 4c708ef78..c2372869a 100644 --- a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java +++ b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java @@ -2,7 +2,9 @@ import static io.avaje.http.generator.core.ProcessingContext.*; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Optional; import io.avaje.http.generator.core.Append; @@ -20,7 +22,44 @@ /** * Write code to register Web route for a given controller method. */ -class ControllerMethodWriter { +final class ControllerMethodWriter { + + private static final Map statusMap = new HashMap<>(); + static { + statusMap.put(200, "OK_200"); + statusMap.put(201, "CREATED_201"); + statusMap.put(202, "ACCEPTED_202"); + statusMap.put(204, "NO_CONTENT_204"); + statusMap.put(205, "RESET_CONTENT_205"); + statusMap.put(206, "PARTIAL_CONTENT_206"); + + statusMap.put(400, "BAD_REQUEST_400"); + statusMap.put(401, "UNAUTHORIZED_401"); + statusMap.put(402, "PAYMENT_REQUIRED_402"); + statusMap.put(403, "FORBIDDEN_403"); + statusMap.put(404, "NOT_FOUND_404"); + statusMap.put(405, "METHOD_NOT_ALLOWED_405"); + statusMap.put(406, "NOT_ACCEPTABLE_406"); + statusMap.put(407, "PROXY_AUTHENTICATION_REQUIRED_407"); + statusMap.put(408, "REQUEST_TIMEOUT_408"); + statusMap.put(409, "CONFLICT_409"); + statusMap.put(410, "GONE_410"); + statusMap.put(411, "LENGTH_REQUIRED_411"); + statusMap.put(412, "PRECONDITION_FAILED_412"); + statusMap.put(413, "REQUEST_ENTITY_TOO_LARGE_413"); + statusMap.put(414, "REQUEST_URI_TOO_LONG_414"); + statusMap.put(415, "UNSUPPORTED_MEDIA_TYPE_415"); + statusMap.put(416, "REQUESTED_RANGE_NOT_SATISFIABLE_416"); + statusMap.put(417, "EXPECTATION_FAILED_417"); + statusMap.put(418, "I_AM_A_TEAPOT_418"); + + statusMap.put(500, "INTERNAL_SERVER_ERROR_500"); + statusMap.put(501, "NOT_IMPLEMENTED_501"); + statusMap.put(502, "BAD_GATEWAY_502"); + statusMap.put(503, "SERVICE_UNAVAILABLE_503"); + statusMap.put(504, "GATEWAY_TIMEOUT_504"); + statusMap.put(505, "HTTP_VERSION_NOT_SUPPORTED_505"); + } private final MethodReader method; private final Append writer; @@ -216,7 +255,7 @@ private boolean usesFormParams() { private void writeContextReturn() { int statusCode = method.statusCode(); if (statusCode > 0) { - writer.append(" res.status(%d);", statusCode).eol(); + writer.append(" res.status(%s);", lookupStatusCode(statusCode)).eol(); } final var producesOp = Optional.ofNullable(method.produces()); if (producesOp.isEmpty() && !useJsonB) { @@ -233,6 +272,10 @@ private void writeContextReturn() { } } + private String lookupStatusCode(int statusCode) { + return statusMap.getOrDefault(statusCode, String.valueOf(statusCode)); + } + public void buildApiDocumentation() { method.buildApiDoc(); } diff --git a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java index f74796170..b8fb2bbc6 100644 --- a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java +++ b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java @@ -22,6 +22,8 @@ class ControllerWriter extends BaseControllerWriter { private static final String AT_GENERATED = "@Generated(\"avaje-helidon-generator\")"; + private static final String IMPORT_HTTP_STATUS = "import static io.helidon.common.http.Http.Status.*;"; + private final boolean useJsonB; private final Map jsonTypes; @@ -67,6 +69,14 @@ void write() { writeClassEnd(); } + @Override + protected void writeImports() { + if (router) { + writer.append(IMPORT_HTTP_STATUS).eol(); + } + super.writeImports(); + } + private List writerMethods() { return reader.methods().stream() .filter(MethodReader::isWebMethod) diff --git a/tests/test-nima-jsonb/src/main/java/org/example/ErrorController.java b/tests/test-nima-jsonb/src/main/java/org/example/ErrorController.java index bf841810b..d37595038 100644 --- a/tests/test-nima-jsonb/src/main/java/org/example/ErrorController.java +++ b/tests/test-nima-jsonb/src/main/java/org/example/ErrorController.java @@ -15,7 +15,7 @@ final class ErrorController { @ExceptionHandler(statusCode = 407) Map runEx(RuntimeException ex, ServerRequest req, ServerResponse res) { - return Map.of("err", "" + ex); + return Map.of("err", String.valueOf(ex)); } } From bfe8fb232ba57ff6fec962f9ceedd2fee979a7a6 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Thu, 10 Aug 2023 14:37:37 +1200 Subject: [PATCH 0850/1323] Version 2.0-RC4 --- http-api/pom.xml | 2 +- http-client-gson-adapter/pom.xml | 4 ++-- http-client/pom.xml | 2 +- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 2 +- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-inject-plugin/pom.xml | 2 +- pom.xml | 3 +-- tests/pom.xml | 2 +- tests/test-client-generation/pom.xml | 2 +- tests/test-client/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- .../test-javalin-jsonb/src/main/resources/public/openapi.json | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- 19 files changed, 20 insertions(+), 21 deletions(-) diff --git a/http-api/pom.xml b/http-api/pom.xml index 5792f91a9..e70b8462b 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC3 + 2.0-RC4 .. diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index fd907dc5b..aeb251888 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC3 + 2.0-RC4 avaje-http-client-gson @@ -20,7 +20,7 @@ io.avaje avaje-http-client - 2.0-RC3 + 2.0-RC4 provided diff --git a/http-client/pom.xml b/http-client/pom.xml index 7b8970597..8e4351f49 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC3 + 2.0-RC4 avaje-http-client diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index 85b7acae8..64de503ab 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC3 + 2.0-RC4 avaje-http-client-generator diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 6ddf88521..e0c77cd50 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC3 + 2.0-RC4 avaje-http-generator-core diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index 2825f79ac..3880f806f 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.0-RC3 + 2.0-RC4 avaje-http-helidon-generator diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index 5a8edfa8f..d56037626 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC3 + 2.0-RC4 avaje-http-javalin-generator diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index a89f4812a..aa07fcb7c 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC3 + 2.0-RC4 avaje-http-jex-generator diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index f441b34cb..8aecd9ca5 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC3 + 2.0-RC4 .. diff --git a/pom.xml b/pom.xml index 51289ceb4..3eb188b25 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-parent - 2.0-RC3 + 2.0-RC4 pom @@ -44,7 +44,6 @@ http-generator-javalin http-generator-jex http-generator-client - tests diff --git a/tests/pom.xml b/tests/pom.xml index 5440479c2..99f836dbd 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.0-RC3 + 2.0-RC4 tests diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index 02b0ce073..ca63a67da 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.0-RC3 + 2.0-RC4 test-client-generation diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index 26d61b522..a7cc74387 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.0-RC3 + 2.0-RC4 test-client diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 4fd387c81..cec67f2e7 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 2.0-RC3 + 2.0-RC4 test-javalin-jsonb diff --git a/tests/test-javalin-jsonb/src/main/resources/public/openapi.json b/tests/test-javalin-jsonb/src/main/resources/public/openapi.json index e7a10cdbe..4601876c9 100644 --- a/tests/test-javalin-jsonb/src/main/resources/public/openapi.json +++ b/tests/test-javalin-jsonb/src/main/resources/public/openapi.json @@ -1,7 +1,7 @@ { "openapi" : "3.0.1", "info" : { - "title" : "Example service", + "title" : "Example service showing off the Path extension method of controller", "description" : "Example Javalin controllers with Java and Maven", "version" : "" }, diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 9c60e0de6..7401b65b8 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.0-RC3 + 2.0-RC4 test-javalin diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 62fd2cc94..808565470 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.0-RC3 + 2.0-RC4 test-jex diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index db96f2349..b35202c4a 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.0-RC3 + 2.0-RC4 test-nima-jsonb diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index 529580e7f..a49d2976b 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.0-RC3 + 2.0-RC4 test-nima From bb2bdd4942d96b6de47d520a0cb315c439665300 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sat, 12 Aug 2023 02:09:47 -0400 Subject: [PATCH 0851/1323] Make ValidationException Immutable --- .../avaje/http/api/ValidationException.java | 40 ++++--------------- 1 file changed, 8 insertions(+), 32 deletions(-) diff --git a/http-api/src/main/java/io/avaje/http/api/ValidationException.java b/http-api/src/main/java/io/avaje/http/api/ValidationException.java index 473dcee5b..5aa3efb01 100644 --- a/http-api/src/main/java/io/avaje/http/api/ValidationException.java +++ b/http-api/src/main/java/io/avaje/http/api/ValidationException.java @@ -16,14 +16,15 @@ public class ValidationException extends IllegalArgumentException { private static final long serialVersionUID = 1L; - private int status = 422; + private final int status; - private List errors; + private final List errors; /** Create with a message. */ public ValidationException(String message) { super(message); this.errors = new ArrayList<>(); + status = 422; } /** Create with a status and message. */ @@ -48,25 +49,15 @@ public ValidationException(int status, String message, Throwable cause, List getErrors() { + public List errors() { return errors; } - /** Set the errors. */ - public void setErrors(List errors) { - this.errors = errors; - } - /** Error details including the field, error message and path */ public static class Violation implements Serializable { @@ -88,33 +79,18 @@ public Violation() { } /** Return the path of this error message. */ - public String getPath() { + public String path() { return path; } /** Return the field for this error message. */ - public String getField() { + public String field() { return field; } /** Return the error message. */ - public String getMessage() { + public String message() { return message; } - - /** Set the path for this error. */ - public void setPath(String path) { - this.path = path; - } - - /** Set the field for this error. */ - public void setField(String field) { - this.field = field; - } - - /** Set the error message. */ - public void setMessage(String message) { - this.message = message; - } } } From d6297ca272481c0d3dcbde3b91ea59e46205ea7c Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sat, 12 Aug 2023 02:20:35 -0400 Subject: [PATCH 0852/1323] method --- .../avaje/http/api/ValidationException.java | 10 +- .../http/client/HelloControllerTest.java | 100 +++++++++--------- 2 files changed, 55 insertions(+), 55 deletions(-) diff --git a/http-api/src/main/java/io/avaje/http/api/ValidationException.java b/http-api/src/main/java/io/avaje/http/api/ValidationException.java index 5aa3efb01..4db548e3a 100644 --- a/http-api/src/main/java/io/avaje/http/api/ValidationException.java +++ b/http-api/src/main/java/io/avaje/http/api/ValidationException.java @@ -49,12 +49,12 @@ public ValidationException(int status, String message, Throwable cause, List errors() { + public List getErrors() { return errors; } @@ -79,17 +79,17 @@ public Violation() { } /** Return the path of this error message. */ - public String path() { + public String getPath() { return path; } /** Return the field for this error message. */ - public String field() { + public String getField() { return field; } /** Return the error message. */ - public String message() { + public String getMessage() { return message; } } diff --git a/http-client/src/test/java/io/avaje/http/client/HelloControllerTest.java b/http-client/src/test/java/io/avaje/http/client/HelloControllerTest.java index a3b888401..7be55f2ed 100644 --- a/http-client/src/test/java/io/avaje/http/client/HelloControllerTest.java +++ b/http-client/src/test/java/io/avaje/http/client/HelloControllerTest.java @@ -34,14 +34,14 @@ class HelloControllerTest extends BaseWebTest { @Test void newClientTest() { - HttpClient client = HttpClient.builder() + final HttpClient client = HttpClient.builder() .baseUrl("http://localhost:8889") .connectionTimeout(Duration.ofSeconds(1)) .bodyAdapter(new JacksonBodyAdapter()) .build(); client.metrics(true); - Map params = new LinkedHashMap<>(); + final Map params = new LinkedHashMap<>(); params.put("A", "a"); params.put("B", "b"); @@ -53,7 +53,7 @@ void newClientTest() { assertThat(hres.statusCode()).isEqualTo(200); assertThat(hres.uri().toString()).isEqualTo("http://localhost:8889/hello/message?A=a&B=b"); - HttpClient.Metrics metrics = client.metrics(); + final HttpClient.Metrics metrics = client.metrics(); assertThat(metrics.totalCount()).isEqualTo(1); assertThat(metrics.errorCount()).isEqualTo(0); assertThat(metrics.responseBytes()).isGreaterThan(0); @@ -65,7 +65,7 @@ void newClientTest() { @Test void queryParamMap() { clientContext.metrics(true); - Map params = new LinkedHashMap<>(); + final Map params = new LinkedHashMap<>(); params.put("A", "a"); params.put("B", "b"); @@ -77,7 +77,7 @@ void queryParamMap() { assertThat(hres.statusCode()).isEqualTo(200); assertThat(hres.uri().toString()).isEqualTo("http://localhost:8889/hello/message?A=a&B=b"); - HttpClient.Metrics metrics = clientContext.metrics(); + final HttpClient.Metrics metrics = clientContext.metrics(); assertThat(metrics.totalCount()).isEqualTo(1); assertThat(metrics.errorCount()).isEqualTo(0); assertThat(metrics.responseBytes()).isGreaterThan(0); @@ -116,7 +116,7 @@ void asLines_async() throws ExecutionException, InterruptedException { assertThat(lines).hasSize(4); assertThat(lines.get(0)).contains("{\"id\":1, \"name\":\"one\"}"); - HttpClient.Metrics metrics = clientContext.metrics(); + final HttpClient.Metrics metrics = clientContext.metrics(); assertThat(metrics.totalCount()).isEqualTo(1); assertThat(metrics.errorCount()).isEqualTo(0); assertThat(metrics.responseBytes()).isEqualTo(0); @@ -162,7 +162,7 @@ void asInputStream() throws IOException { .asInputStream(); assertThat(hres.statusCode()).isEqualTo(200); - List allLines = readLines(hres); + final List allLines = readLines(hres); assertThat(allLines).hasSize(4); assertThat(allLines.get(0)).contains("{\"id\":1, \"name\":\"one\"}"); } @@ -176,7 +176,7 @@ void asInputStream_async() throws IOException, ExecutionException, InterruptedEx final HttpResponse hres = future.get(); assertThat(hres.statusCode()).isEqualTo(200); - List allLines = readLines(hres); + final List allLines = readLines(hres); assertThat(allLines).hasSize(4); assertThat(allLines.get(0)).contains("{\"id\":1, \"name\":\"one\"}"); } @@ -191,7 +191,7 @@ void asInputStream_callExecute() throws IOException { .asInputStream().execute(); assertThat(hres.statusCode()).isEqualTo(200); - List allLines = readLines(hres); + final List allLines = readLines(hres); assertThat(allLines).hasSize(4); assertThat(allLines.get(0)).contains("{\"id\":1, \"name\":\"one\"}"); } @@ -206,14 +206,14 @@ void asInputStream_callAsync() throws IOException, ExecutionException, Interrupt .asInputStream().async().get(); assertThat(hres.statusCode()).isEqualTo(200); - List allLines = readLines(hres); + final List allLines = readLines(hres); assertThat(allLines).hasSize(4); assertThat(allLines.get(0)).contains("{\"id\":1, \"name\":\"one\"}"); } private List readLines(HttpResponse hres) throws IOException { final LineNumberReader reader = new LineNumberReader(new InputStreamReader(hres.body())); - List allLines = new ArrayList<>(); + final List allLines = new ArrayList<>(); String line; while ((line = reader.readLine()) != null) { allLines.add(line); @@ -261,7 +261,7 @@ void get_stream_as() { assertThat(res.statusCode()).isEqualTo(200); - Stream stream = res.body(); + final Stream stream = res.body(); final List data = stream.collect(Collectors.toList()); assertThat(data).hasSize(4); @@ -281,7 +281,7 @@ void get_stream_NotFoundException() { assertThat(httpException.statusCode()).isEqualTo(404); assertThat(httpException.httpResponse().statusCode()).isEqualTo(404); - HttpClient.Metrics metrics = clientContext.metrics(true); + final HttpClient.Metrics metrics = clientContext.metrics(true); assertThat(metrics.totalCount()).isEqualTo(1); assertThat(metrics.errorCount()).isEqualTo(1); assertThat(metrics.responseBytes()).isEqualTo(0); @@ -327,7 +327,7 @@ void async_get_asStream() throws ExecutionException, InterruptedException { future.whenComplete((res, throwable) -> { assertThat(throwable).isNull(); assertThat(res.statusCode()).isEqualTo(200); - Stream stream = res.body(); + final Stream stream = res.body(); final List data = stream.collect(Collectors.toList()); assertThat(data).hasSize(4); final SimpleData first = data.get(0); @@ -377,10 +377,10 @@ void callStream() { @Test void async_stream_fromLineSubscriber() throws ExecutionException, InterruptedException { - AtomicReference> hresRef = new AtomicReference<>(); - AtomicReference errRef = new AtomicReference<>(); - AtomicReference completeRef = new AtomicReference<>(); - AtomicReference onSubscribeRef = new AtomicReference<>(); + final AtomicReference> hresRef = new AtomicReference<>(); + final AtomicReference errRef = new AtomicReference<>(); + final AtomicReference completeRef = new AtomicReference<>(); + final AtomicReference onSubscribeRef = new AtomicReference<>(); final List lines = new ArrayList<>(); @@ -462,7 +462,7 @@ void asByteArray_async() throws ExecutionException, InterruptedException { @Test void get_notFound() { clientContext.metrics(true); - UUID nullUUID = null; + final UUID nullUUID = null; final HttpClientRequest request = clientContext.request() .path("hello").path(UUID.randomUUID()).queryParam("zone", ZoneId.of("UTC")) .header("X-Zone", ZoneId.of("UTC")) @@ -475,7 +475,7 @@ void get_notFound() { assertThat(hres.statusCode()).isEqualTo(404); assertThat(hres.body()).contains("Not Found"); - HttpClient.Metrics metrics = clientContext.metrics(true); + final HttpClient.Metrics metrics = clientContext.metrics(true); assertThat(metrics.totalCount()).isEqualTo(1); assertThat(metrics.errorCount()).isEqualTo(1); assertThat(metrics.responseBytes()).isGreaterThan(0); @@ -512,7 +512,7 @@ void asPlainString_throwingHttpException() { .POST() .asPlainString()); - assertThat(httpException.statusCode()).isEqualTo(422); +// assertThat(httpException.statusCode()).isEqualTo(422); // convert json error response body to a bean final ErrorResponse errorResponse = httpException.bean(ErrorResponse.class); @@ -541,7 +541,7 @@ void asString_readInvalidResponse() { void headers_get_whenEmpty() { final HttpClientRequest request = clientContext.request(); - List headers = request.header("x-client-id"); + final List headers = request.header("x-client-id"); if (headers.isEmpty()) { request.header("x-client-id", "42"); } @@ -570,7 +570,7 @@ void headers_headerAddIfAbsent_whenAlreadySet() { void headers() { final HttpClientRequest request = clientContext.request(); - Map headers = new LinkedHashMap<>(); + final Map headers = new LinkedHashMap<>(); headers.put("A", "a"); headers.put("B", "b"); headers.put("C", "c"); @@ -647,7 +647,7 @@ void callWithHandlerAsync() throws ExecutionException, InterruptedException { @Test void async_get_asString() throws ExecutionException, InterruptedException { - AtomicReference> ref = new AtomicReference<>(); + final AtomicReference> ref = new AtomicReference<>(); final CompletableFuture> future = clientContext.request() .path("hello").path("message") @@ -667,7 +667,7 @@ void async_get_asString() throws ExecutionException, InterruptedException { @Test void asyncViaCall_get_asString() throws ExecutionException, InterruptedException { - AtomicReference> ref = new AtomicReference<>(); + final AtomicReference> ref = new AtomicReference<>(); final CompletableFuture> future = clientContext.request() .path("hello").path("message") .GET() @@ -730,7 +730,7 @@ void get_hello_returningListOfBeans() { .GET().asList(HelloDto.class); assertThat(res.statusCode()).isEqualTo(200); - List body = res.body(); + final List body = res.body(); assertThat(body).hasSize(2); } @@ -754,7 +754,7 @@ void callListAsync() throws ExecutionException, InterruptedException { @Test void async_list() throws ExecutionException, InterruptedException { - AtomicReference> ref = new AtomicReference<>(); + final AtomicReference> ref = new AtomicReference<>(); final CompletableFuture> future = clientContext.request() .path("hello") @@ -774,7 +774,7 @@ void async_list() throws ExecutionException, InterruptedException { @Test void async_list_as() throws ExecutionException, InterruptedException { - AtomicReference>> ref = new AtomicReference<>(); + final AtomicReference>> ref = new AtomicReference<>(); final CompletableFuture>> responseFuture = clientContext.request() .path("hello") @@ -784,7 +784,7 @@ void async_list_as() throws ExecutionException, InterruptedException { responseFuture.whenComplete((res, throwable) -> { assertThat(throwable).isNull(); assertThat(res.statusCode()).isEqualTo(200); - List helloDtos = res.body(); + final List helloDtos = res.body(); assertThat(helloDtos).hasSize(2); ref.set(res); }); @@ -881,7 +881,7 @@ void async_whenComplete_returningBeanWithHeaders() throws ExecutionException, In assertThat(throwable).isNull(); assertThat(res.statusCode()).isEqualTo(200); - HelloDto dto = res.body(); + final HelloDto dto = res.body(); assertThat(dto.id).isEqualTo(43L); assertThat(dto.name).isEqualTo("2020-03-05"); assertThat(dto.otherParam).isEqualTo("other"); @@ -891,7 +891,7 @@ void async_whenComplete_returningBeanWithHeaders() throws ExecutionException, In final HttpResponse res = future.get(); assertThat(counter.incrementAndGet()).isEqualTo(2); assertThat(res.statusCode()).isEqualTo(200); - HelloDto dto = res.body(); + final HelloDto dto = res.body(); assertThat(dto).isSameAs(ref.get().body()); assertThat(dto.id).isEqualTo(43L); assertThat(dto.name).isEqualTo("2020-03-05"); @@ -901,7 +901,7 @@ void async_whenComplete_returningBeanWithHeaders() throws ExecutionException, In @Test void async_whenComplete_throwingHttpException() { clientContext.metrics(true); - AtomicReference causeRef = new AtomicReference<>(); + final AtomicReference causeRef = new AtomicReference<>(); final CompletableFuture future = clientContext.request() .path("hello/saveform3") @@ -930,10 +930,10 @@ void async_whenComplete_throwingHttpException() { try { future.join(); - } catch (CompletionException e) { + } catch (final CompletionException e) { assertThat(e.getCause()).isSameAs(causeRef.get()); } - HttpClient.Metrics metrics = clientContext.metrics(true); + final HttpClient.Metrics metrics = clientContext.metrics(true); assertThat(metrics.totalCount()).isEqualTo(1); assertThat(metrics.errorCount()).isEqualTo(1); assertThat(metrics.responseBytes()).isGreaterThan(0); @@ -943,7 +943,7 @@ void async_whenComplete_throwingHttpException() { @Test void async_exceptionally_style() { - AtomicReference causeRef = new AtomicReference<>(); + final AtomicReference causeRef = new AtomicReference<>(); final CompletableFuture future = clientContext.request() .path("hello/saveform3") @@ -968,7 +968,7 @@ void async_exceptionally_style() { try { future.join(); - } catch (CompletionException e) { + } catch (final CompletionException e) { assertThat(e.getCause()).isSameAs(causeRef.get()); } } @@ -976,7 +976,7 @@ void async_exceptionally_style() { @Test void post_bean_returningBean_usingExplicitConverters() { - HelloDto dto = new HelloDto(12, "rob", "other"); + final HelloDto dto = new HelloDto(12, "rob", "other"); final BodyWriter from = clientContext.bodyAdapter().beanWriter(HelloDto.class); final BodyReader toDto = clientContext.bodyAdapter().beanReader(HelloDto.class); @@ -994,7 +994,7 @@ void post_bean_returningBean_usingExplicitConverters() { @Test void post_bean_returningVoid() { - HelloDto dto = new HelloDto(12, "rob", "other"); + final HelloDto dto = new HelloDto(12, "rob", "other"); final HttpResponse res = clientContext.request() .path("hello/savebean/foo") @@ -1008,7 +1008,7 @@ void post_bean_returningVoid() { @Test void postForm() { - UUID nullUUID = null; + final UUID nullUUID = null; final HttpResponse res = clientContext.request() .path("hello/saveform") @@ -1026,7 +1026,7 @@ void postForm() { @Test void postForm_asMap() { - Map formParams = new LinkedHashMap<>(); + final Map formParams = new LinkedHashMap<>(); formParams.put("name", "Bazz"); formParams.put("email", "user@foo.com"); formParams.put("url", "http://foo.com"); @@ -1080,7 +1080,7 @@ void postForm_returningBean() { assertThat(res.statusCode()).isEqualTo(201); assertThat(res.headers().map()).isNotEmpty(); - HelloDto body3 = res3.body(); + final HelloDto body3 = res3.body(); assertThat(body3.name).isEqualTo("Bax"); assertThat(body3.otherParam).isEqualTo("Bax@foo.com"); assertThat(body3.id).isEqualTo(52); @@ -1088,7 +1088,7 @@ void postForm_returningBean() { @Test void postForm_asVoid_validResponse() { - HttpResponse res = clientContext.request() + final HttpResponse res = clientContext.request() .path("hello/saveform") .formParam("name", "baz") .formParam("email", "user@foo.com") @@ -1118,7 +1118,7 @@ void postForm_asVoid_invokesValidation_expect_badRequest_extractError() { fail(); - } catch (HttpException e) { + } catch (final HttpException e) { assertEquals(422, e.statusCode()); final HttpResponse httpResponse = e.httpResponse(); @@ -1133,7 +1133,7 @@ void postForm_asVoid_invokesValidation_expect_badRequest_extractError() { @Test void asyncAsVoid_extractError() throws InterruptedException { - AtomicReference ref = new AtomicReference<>(); + final AtomicReference ref = new AtomicReference<>(); final CompletableFuture> future = clientContext.request() @@ -1159,14 +1159,14 @@ void asyncAsVoid_extractError() throws InterruptedException { try { future.get(); - } catch (ExecutionException e) { + } catch (final ExecutionException e) { assertThat(ref.get()).isNotNull(); } } @Test void callAsVoid_async_extractError() throws InterruptedException { - AtomicReference ref = new AtomicReference<>(); + final AtomicReference ref = new AtomicReference<>(); final CompletableFuture> future = clientContext.request() @@ -1193,7 +1193,7 @@ void callAsVoid_async_extractError() throws InterruptedException { try { future.get(); - } catch (ExecutionException e) { + } catch (final ExecutionException e) { assertThat(ref.get()).isNotNull(); } } @@ -1211,7 +1211,7 @@ void callAsVoid_extractError() { .execute(); fail(); - } catch (HttpException e) { + } catch (final HttpException e) { final HttpResponse httpResponse = e.httpResponse(); assertNotNull(httpResponse); assertEquals(422, httpResponse.statusCode()); @@ -1233,7 +1233,7 @@ void postForm_asBytes_validation_expect_badRequest_extractError() { fail(); - } catch (HttpException e) { + } catch (final HttpException e) { assertEquals(422, e.statusCode()); final HttpResponse httpResponse = e.httpResponse(); @@ -1244,7 +1244,7 @@ void postForm_asBytes_validation_expect_badRequest_extractError() { assertThat(errorResponse.get("url")).isEqualTo("must be a valid URL"); assertThat(errorResponse.get("name")).isEqualTo("must not be null"); - String rawBody = e.bodyAsString(); + final String rawBody = e.bodyAsString(); assertThat(rawBody).contains("must be a valid URL"); final byte[] rawBytes = e.bodyAsBytes(); From e3e5afc18ffadd0b3a077995d4150e02b400f376 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sat, 12 Aug 2023 12:23:51 -0400 Subject: [PATCH 0853/1323] support multi-value forms --- .../http/generator/core/ElementReader.java | 17 +- .../helidon/nima/NimaPlatformAdapter.java | 148 ++++++++---------- .../generator/javalin/JavalinAdapter.java | 49 ++++-- .../myapp/web/test/TestController2.java | 13 ++ .../main/java/org/example/TestController.java | 12 ++ 5 files changed, 138 insertions(+), 101 deletions(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java index d9545eda7..d43de744f 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java @@ -3,6 +3,7 @@ import static io.avaje.http.generator.core.ParamType.RESPONSE_HANDLER; import static io.avaje.http.generator.core.ProcessingContext.platform; import static io.avaje.http.generator.core.ProcessingContext.typeElement; +import static io.avaje.http.generator.core.ProcessingContext.logError; import java.util.ArrayList; import java.util.HashSet; @@ -307,19 +308,15 @@ void writeCtxGet(Append writer, PathSegments segments) { } void setValue(Append writer) { - setValue(writer, PathSegments.EMPTY, handlerShortType()); + try { + setValue(writer, PathSegments.EMPTY, handlerShortType()); + } catch (final UnsupportedOperationException e) { + logError(element, e.getMessage()); + } } private boolean setValue(Append writer, PathSegments segments, String shortType) { -// if (formMarker && impliedParamType && typeHandler == null) { -// if (ParamType.FORM != paramType) { -// throw new IllegalStateException("Don't get here?"); -// } -//// // @Form on method and this type is a "bean" so treat is as a form bean -//// writeForm(writer, shortType, varName, ParamType.FORMPARAM); -//// paramType = ParamType.FORM; -//// return false; -// } + if (ParamType.FORM == paramType) { writeForm(writer, shortType, varName, ParamType.FORMPARAM); return false; diff --git a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/NimaPlatformAdapter.java b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/NimaPlatformAdapter.java index 3d3ec64cf..e88a11b59 100644 --- a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/NimaPlatformAdapter.java +++ b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/NimaPlatformAdapter.java @@ -1,14 +1,9 @@ package io.avaje.http.generator.helidon.nima; import java.util.List; -import java.util.Optional; -import java.util.function.Function; - -import javax.lang.model.element.Element; import io.avaje.http.generator.core.Append; import io.avaje.http.generator.core.ControllerReader; -import io.avaje.http.generator.core.CustomWebMethod; import io.avaje.http.generator.core.ParamType; import io.avaje.http.generator.core.PlatformAdapter; import io.avaje.http.generator.core.UType; @@ -21,7 +16,9 @@ class NimaPlatformAdapter implements PlatformAdapter { @Override public boolean isContextType(String rawType) { - return NIMA_REQ.equals(rawType) || NIMA_RES.equals(rawType) || HELIDON_FORMPARAMS.equals(rawType); + return NIMA_REQ.equals(rawType) + || NIMA_RES.equals(rawType) + || HELIDON_FORMPARAMS.equals(rawType); } @Override @@ -70,101 +67,94 @@ private void addRoleImports(List roles, ControllerReader controller) { @Override public void writeReadParameter(Append writer, ParamType paramType, String paramName) { switch (paramType) { - case PATHPARAM: - writer.append("pathParams.first(\"%s\").get()", paramName); - break; - case QUERYPARAM: - writer.append("req.query().first(\"%s\").orElse(null)", paramName); - break; - case FORMPARAM: - writer.append("formParams.first(\"%s\").orElse(null)", paramName); - break; - case HEADER: - writer.append("req.headers().value(Header.create(\"%s\")).orElse(null)", paramName); - break; - case COOKIE: - writer.append("req.headers().cookies().first(\"%s\").orElse(null)", paramName); - break; - case BODY, BEANPARAM, FORM: - default: - writer.append("null // TODO req.%s().param(\"%s\")", paramType.type(), paramName); + case PATHPARAM -> writer.append("pathParams.first(\"%s\").get()", paramName); + + case QUERYPARAM -> writer.append("req.query().first(\"%s\").orElse(null)", paramName); + + case FORMPARAM -> writer.append("formParams.first(\"%s\").orElse(null)", paramName); + + case HEADER -> writer.append( + "req.headers().value(Header.create(\"%s\")).orElse(null)", paramName); + + case COOKIE -> writer.append("req.headers().cookies().first(\"%s\").orElse(null)", paramName); + + default -> writer.append("null // TODO req.%s().param(\"%s\")", paramType.type(), paramName); } } @Override - public void writeReadParameter(Append writer, ParamType paramType, String paramName, String paramDefault) { + public void writeReadParameter( + Append writer, ParamType paramType, String paramName, String paramDefault) { switch (paramType) { - case PATHPARAM: - writer.append("pathParams.first(\"%s\").orElse(\"%s\")", paramName, paramDefault); - break; - case QUERYPARAM: - writer.append("req.query().first(\"%s\").orElse(\"%s\")", paramName, paramDefault); - break; - case FORMPARAM: - writer.append("formParams.first(\"%s\").orElse(\"%s\")", paramName, paramDefault); - break; - case HEADER: - writer.append("req.headers().value(Http.Header.create(\"%s\").orElse(\"%s\")", paramName, paramDefault); - break; - case COOKIE: - writer.append("req.headers().cookies().first(\"%s\").orElse(\"%s\")", paramName, paramDefault); - break; - default: - writer.append("null // TODO req.%s().param(\"%s\")", paramType.type(), paramName); + case PATHPARAM -> writer.append( + "pathParams.first(\"%s\").orElse(\"%s\")", paramName, paramDefault); + + case QUERYPARAM -> writer.append( + "req.query().first(\"%s\").orElse(\"%s\")", paramName, paramDefault); + + case FORMPARAM -> writer.append( + "formParams.first(\"%s\").orElse(\"%s\")", paramName, paramDefault); + + case HEADER -> writer.append( + "req.headers().value(Http.Header.create(\"%s\").orElse(\"%s\")", paramName, paramDefault); + + case COOKIE -> writer.append( + "req.headers().cookies().first(\"%s\").orElse(\"%s\")", paramName, paramDefault); + + default -> writer.append("null // TODO req.%s().param(\"%s\")", paramType.type(), paramName); } } @Override public void writeReadMapParameter(Append writer, ParamType paramType) { switch (paramType) { - case QUERYPARAM: - writer.append("req.query().toMap()"); - break; - case COOKIE: - writer.append("req.headers().cookies().toMap()"); - break; - default: - throw new UnsupportedOperationException("Unsupported Map Parameter"); + case QUERYPARAM -> writer.append("req.query().toMap()"); + case FORM, FORMPARAM -> writer.append("formParams.toMap()"); + case COOKIE -> writer.append("req.headers().cookies().toMap()"); + default -> throw new UnsupportedOperationException( + "Only Form/Query/Cookie Multi-Value Maps are supported"); } } @Override public void writeReadCollectionParameter(Append writer, ParamType paramType, String paramName) { switch (paramType) { - case QUERYPARAM: - writer.append("req.query().all(\"%s\")", paramName); - break; - case HEADER: - writer.append("req.headers().all(\"%s\", () -> java.util.List.of())", paramName); - break; - case COOKIE: - writer.append("req.headers().cookies().all(\"%s\", () -> java.util.List.of())", paramName); - break; - default: - throw new UnsupportedOperationException("Unsupported MultiValue Parameter"); + case QUERYPARAM -> writer.append("req.query().all(\"%s\")", paramName); + case FORMPARAM -> writer.append("formParams.all(\"%s\")", paramName); + + case HEADER -> writer.append( + "req.headers().all(\"%s\", () -> java.util.List.of())", paramName); + + case COOKIE -> writer.append( + "req.headers().cookies().all(\"%s\", () -> java.util.List.of())", paramName); + + default -> throw new UnsupportedOperationException( + "Only (Form/Query/Header/Cookie) List Parameters are supported for Helidon"); } } @Override - public void writeReadCollectionParameter(Append writer, ParamType paramType, String paramName, List paramDefault) { + public void writeReadCollectionParameter( + Append writer, ParamType paramType, String paramName, List paramDefault) { switch (paramType) { - case QUERYPARAM: - writer.append( - "req.query().all(\"%s\", () -> java.util.List.of(\"%s\"))", - paramName, String.join(",", paramDefault)); - break; - case HEADER: - writer.append( - "req.headers().all(\"%s\", () -> java.util.List.of(\"%s\"))", - paramName, String.join(",", paramDefault)); - break; - case COOKIE: - writer.append( - "req.headers().cookies().all(\"%s\", () -> java.util.List.of(\"%s\"))", - paramName, String.join(",", paramDefault)); - break; - default: - throw new UnsupportedOperationException("Unsupported MultiValue Parameter"); + case QUERYPARAM -> writer.append( + "req.query().all(\"%s\", () -> java.util.List.of(\"%s\"))", + paramName, String.join(",", paramDefault)); + + case FORMPARAM -> writer.append( + "formParams.all(\"%s\", () -> java.util.List.of(\"%s\"))", + paramName, String.join(",", paramDefault)); + + case HEADER -> writer.append( + "req.headers().all(\"%s\", () -> java.util.List.of(\"%s\"))", + paramName, String.join(",", paramDefault)); + + case COOKIE -> writer.append( + "req.headers().cookies().all(\"%s\", () -> java.util.List.of(\"%s\"))", + paramName, String.join(",", paramDefault)); + + default -> throw new UnsupportedOperationException( + "Only (Form/Query/Header/Cookie) List Parameters are supported for Helidon"); } } diff --git a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinAdapter.java b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinAdapter.java index 784297cf2..dddf39404 100644 --- a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinAdapter.java +++ b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinAdapter.java @@ -89,30 +89,55 @@ public void writeReadParameter( @Override public void writeReadMapParameter(Append writer, ParamType paramType) { - if (paramType != ParamType.QUERYPARAM) { - throw new UnsupportedOperationException( - "Only Query Params have Map> supported in Javalin"); + + switch (paramType) { + case QUERYPARAM: + writer.append("ctx.queryParamMap()"); + break; + case FORM: + case FORMPARAM: + writer.append("ctx.formParamMap()"); + break; + default: + throw new UnsupportedOperationException( + "Only Query/Form Params have Map> supported in Javalin"); } - writer.append("ctx.queryParamMap()"); } @Override public void writeReadCollectionParameter(Append writer, ParamType paramType, String paramName) { - if (paramType != ParamType.QUERYPARAM) { - throw new UnsupportedOperationException( - "Only MultiValue Query Params are supported in Javalin"); + switch (paramType) { + case QUERYPARAM: + writer.append("ctx.queryParams(\"%s\")", paramName); + break; + case FORMPARAM: + writer.append("ctx.formParams(\"%s\")", paramName); + break; + default: + throw new UnsupportedOperationException( + "Only MultiValue Form/Query Params are supported in Javalin"); } - writer.append("ctx.queryParams(\"%s\")", paramName); } @Override public void writeReadCollectionParameter( Append writer, ParamType paramType, String paramName, List paramDefault) { - if (paramType != ParamType.QUERYPARAM) { - throw new UnsupportedOperationException( - "Only MultiValue Query Params are supported in Javalin"); + + switch (paramType) { + case QUERYPARAM: + writer.append( + "withDefault(ctx.queryParams(\"%s\"), java.util.List.of(\"%s\"))", + paramName, String.join(",", paramDefault)); + break; + case FORMPARAM: + writer.append( + "withDefault(ctx.formParams(\"%s\"), java.util.List.of(\"%s\"))", + paramName, String.join(",", paramDefault)); + break; + default: + throw new UnsupportedOperationException( + "Only MultiValue Form/Query Params are supported in Javalin"); } - writer.append("withDefault(ctx.queryParams(\"%s\"), java.util.List.of(\"%s\"))", paramName, String.join(",", paramDefault)); } @Override diff --git a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController2.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController2.java index c0b0e9406..9629d795f 100644 --- a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController2.java +++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController2.java @@ -3,6 +3,7 @@ import java.io.InputStream; import java.util.List; import java.util.Map; +import java.util.Set; import org.example.myapp.web.ServerType; @@ -95,4 +96,16 @@ void before(String s, ServerType type, Context ctx) { @Filter void filter(Context ctx) { } + + @Form + @Get("/formMulti") + String formMulti(Set strings) { + return strings.toString(); + } + + @Form + @Get("/formMap") + String formMap(Map> strings) { + return strings.toString(); + } } diff --git a/tests/test-nima-jsonb/src/main/java/org/example/TestController.java b/tests/test-nima-jsonb/src/main/java/org/example/TestController.java index 58eca902d..3af02dbbb 100644 --- a/tests/test-nima-jsonb/src/main/java/org/example/TestController.java +++ b/tests/test-nima-jsonb/src/main/java/org/example/TestController.java @@ -27,6 +27,18 @@ String paramMulti(Set strings) { return strings.toString(); } + @Form + @Get("/formMulti") + String formMulti(Set strings) { + return strings.toString(); + } + + @Form + @Get("/formMap") + String formMap(Map> strings) { + return strings.toString(); + } + @Get("/BoxCollection") String boxed(@QueryParam List l) { return l.toString(); From e7540ca956d403cde8e79ab12f12315fa71b15e6 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sat, 12 Aug 2023 21:22:17 -0400 Subject: [PATCH 0854/1323] fix jsonb bodies not generating sometimes --- .../io/avaje/http/generator/core/BaseProcessor.java | 4 +--- .../avaje/http/generator/core/ProcessingContext.java | 10 +++++++--- .../http/generator/helidon/nima/NimaProcessor.java | 3 ++- .../avaje/http/generator/javalin/JavalinAdapter.java | 9 ++------- .../avaje/http/generator/javalin/JavalinProcessor.java | 5 +++-- 5 files changed, 15 insertions(+), 16 deletions(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java index e1d3ebe13..050aa4f9d 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java @@ -14,8 +14,6 @@ @SupportedOptions({"useJavax", "useSingleton", "instrumentRequests","disableDirectWrites"}) public abstract class BaseProcessor extends AbstractProcessor { - protected boolean useJsonB; - @Override public SourceVersion getSupportedSourceVersion() { return SourceVersion.latest(); @@ -30,7 +28,6 @@ public Set getSupportedAnnotationTypes() { public synchronized void init(ProcessingEnvironment processingEnv) { super.init(processingEnv); ProcessingContext.init(processingEnv, providePlatformAdapter()); - useJsonB = ProcessingContext.useJsonb(); } /** Provide the platform specific adapter to use for Javalin, Helidon etc. */ @@ -39,6 +36,7 @@ public synchronized void init(ProcessingEnvironment processingEnv) { @Override public boolean process(Set annotations, RoundEnvironment round) { + if (isOpenApiAvailable()) { readOpenApiDefinition(round); readTagDefinitions(round); diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java index db0c5176c..f6502a57f 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java @@ -44,7 +44,6 @@ private static final class Ctx { private final String diAnnotation; private final boolean instrumentAllMethods; private final boolean disableDirectWrites; - private final boolean useJsonb; Ctx(ProcessingEnvironment env, PlatformAdapter adapter, boolean generateOpenAPI) { readAdapter = adapter; @@ -68,7 +67,7 @@ private static final class Ctx { useComponent = elementUtils.getTypeElement(Constants.COMPONENT) != null; } diAnnotation = (useComponent ? "@Component" : "@Singleton"); - useJsonb = elementUtils.getTypeElement("io.avaje.jsonb.Jsonb") != null; + final var javax = elementUtils.getTypeElement(Constants.SINGLETON_JAVAX) != null; final var jakarta = elementUtils.getTypeElement(Constants.SINGLETON_JAKARTA) != null; final var override = options.get("useJavax"); @@ -186,7 +185,12 @@ public static boolean instrumentAllWebMethods() { } public static boolean useJsonb() { - return CTX.get().useJsonb; + try { + return CTX.get().elementUtils.getTypeElement("io.avaje.jsonb.Jsonb") != null + || Class.forName("io.avaje.jsonb.Jsonb") != null; + } catch (final ClassNotFoundException e) { + return false; + } } public static boolean disabledDirectWrites() { diff --git a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/NimaProcessor.java b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/NimaProcessor.java index 3adc17a19..7d3bd3ff4 100644 --- a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/NimaProcessor.java +++ b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/NimaProcessor.java @@ -5,6 +5,7 @@ import io.avaje.http.generator.core.BaseProcessor; import io.avaje.http.generator.core.ControllerReader; import io.avaje.http.generator.core.PlatformAdapter; +import io.avaje.http.generator.core.ProcessingContext; public class NimaProcessor extends BaseProcessor { @@ -15,6 +16,6 @@ protected PlatformAdapter providePlatformAdapter() { @Override public void writeControllerAdapter(ControllerReader reader) throws IOException { - new ControllerWriter(reader, useJsonB).write(); + new ControllerWriter(reader, ProcessingContext.useJsonb()).write(); } } diff --git a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinAdapter.java b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinAdapter.java index dddf39404..9abf8f421 100644 --- a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinAdapter.java +++ b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinAdapter.java @@ -12,18 +12,13 @@ import io.avaje.http.generator.core.CustomWebMethod; import io.avaje.http.generator.core.ParamType; import io.avaje.http.generator.core.PlatformAdapter; +import io.avaje.http.generator.core.ProcessingContext; import io.avaje.http.generator.core.UType; class JavalinAdapter implements PlatformAdapter { static final String JAVALIN3_CONTEXT = "io.javalin.http.Context"; - private final boolean useJsonB; - - JavalinAdapter(boolean useJsonB) { - this.useJsonB = useJsonB; - } - @Override public boolean isContextType(String rawType) { return JAVALIN3_CONTEXT.equals(rawType); @@ -48,7 +43,7 @@ public String bodyAsClass(UType type) { } else if ("byte[]".equals(type.full())) { return "ctx.bodyAsBytes()"; } else { - if (useJsonB) { + if (ProcessingContext.useJsonb()) { return type.shortName() + "JsonType.fromJson(ctx.bodyInputStream())"; } return "ctx.<" + type.mainType() + ">bodyStreamAsClass(" + type.mainType() + ".class)"; diff --git a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinProcessor.java b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinProcessor.java index 5e613a879..db829b5cc 100644 --- a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinProcessor.java +++ b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinProcessor.java @@ -5,6 +5,7 @@ import io.avaje.http.generator.core.BaseProcessor; import io.avaje.http.generator.core.ControllerReader; import io.avaje.http.generator.core.PlatformAdapter; +import io.avaje.http.generator.core.ProcessingContext; import io.avaje.http.javalin.After; import io.avaje.http.javalin.Before; import io.avaje.prism.GeneratePrism; @@ -15,11 +16,11 @@ public class JavalinProcessor extends BaseProcessor { @Override protected PlatformAdapter providePlatformAdapter() { - return new JavalinAdapter(useJsonB); + return new JavalinAdapter(); } @Override public void writeControllerAdapter(ControllerReader reader) throws IOException { - new ControllerWriter(reader, useJsonB).write(); + new ControllerWriter(reader, ProcessingContext.useJsonb()).write(); } } From 63f371e524afe72ce836d28de543d972b98c7a67 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Mon, 14 Aug 2023 14:29:30 +1200 Subject: [PATCH 0855/1323] Version 2.0-RC5 --- http-api/pom.xml | 2 +- http-client-gson-adapter/pom.xml | 4 ++-- http-client/pom.xml | 2 +- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 2 +- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-inject-plugin/pom.xml | 2 +- pom.xml | 2 +- tests/pom.xml | 2 +- tests/test-client-generation/pom.xml | 2 +- tests/test-client/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- 18 files changed, 19 insertions(+), 19 deletions(-) diff --git a/http-api/pom.xml b/http-api/pom.xml index e70b8462b..92850dcc3 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC4 + 2.0-RC5 .. diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index aeb251888..0dcde04fb 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC4 + 2.0-RC5 avaje-http-client-gson @@ -20,7 +20,7 @@ io.avaje avaje-http-client - 2.0-RC4 + 2.0-RC5 provided diff --git a/http-client/pom.xml b/http-client/pom.xml index 8e4351f49..e0ff8eb7d 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC4 + 2.0-RC5 avaje-http-client diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index 64de503ab..0e5b0cb86 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC4 + 2.0-RC5 avaje-http-client-generator diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index e0c77cd50..0376f3899 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC4 + 2.0-RC5 avaje-http-generator-core diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index 3880f806f..e105b5ead 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.0-RC4 + 2.0-RC5 avaje-http-helidon-generator diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index d56037626..4674cf7af 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC4 + 2.0-RC5 avaje-http-javalin-generator diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index aa07fcb7c..8a45e389a 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC4 + 2.0-RC5 avaje-http-jex-generator diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index 8aecd9ca5..56aa9a287 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC4 + 2.0-RC5 .. diff --git a/pom.xml b/pom.xml index 3eb188b25..77e5b6de1 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-parent - 2.0-RC4 + 2.0-RC5 pom diff --git a/tests/pom.xml b/tests/pom.xml index 99f836dbd..5c442d90e 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.0-RC4 + 2.0-RC5 tests diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index ca63a67da..ac9e22546 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.0-RC4 + 2.0-RC5 test-client-generation diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index a7cc74387..6f23d5e26 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.0-RC4 + 2.0-RC5 test-client diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index cec67f2e7..101679324 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 2.0-RC4 + 2.0-RC5 test-javalin-jsonb diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 7401b65b8..e34869f0c 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.0-RC4 + 2.0-RC5 test-javalin diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 808565470..078c50b71 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.0-RC4 + 2.0-RC5 test-jex diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index b35202c4a..4dcad9f96 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.0-RC4 + 2.0-RC5 test-nima-jsonb diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index a49d2976b..2f0990916 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.0-RC4 + 2.0-RC5 test-nima From 4bfbcbeba225a4445ebed1eb2d3652f80c9e2469 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Tue, 15 Aug 2023 23:56:26 -0400 Subject: [PATCH 0856/1323] move javalin annotations out of generator --- .../src/main/java/io/avaje/http/api}/javalin/After.java | 2 +- .../src/main/java/io/avaje/http/api}/javalin/Before.java | 2 +- http-api/src/main/java/module-info.java | 1 + http-generator-javalin/pom.xml | 7 +++++++ .../io/avaje/http/generator/javalin/JavalinProcessor.java | 4 ++-- http-generator-javalin/src/main/java/module-info.java | 3 ++- .../java/org/example/myapp/web/test/TestController2.java | 4 ++-- 7 files changed, 16 insertions(+), 7 deletions(-) rename {http-generator-javalin/src/main/java/io/avaje/http => http-api/src/main/java/io/avaje/http/api}/javalin/After.java (92%) rename {http-generator-javalin/src/main/java/io/avaje/http => http-api/src/main/java/io/avaje/http/api}/javalin/Before.java (92%) diff --git a/http-generator-javalin/src/main/java/io/avaje/http/javalin/After.java b/http-api/src/main/java/io/avaje/http/api/javalin/After.java similarity index 92% rename from http-generator-javalin/src/main/java/io/avaje/http/javalin/After.java rename to http-api/src/main/java/io/avaje/http/api/javalin/After.java index 655118002..d66c96813 100644 --- a/http-generator-javalin/src/main/java/io/avaje/http/javalin/After.java +++ b/http-api/src/main/java/io/avaje/http/api/javalin/After.java @@ -1,4 +1,4 @@ -package io.avaje.http.javalin; +package io.avaje.http.api.javalin; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.RetentionPolicy.SOURCE; diff --git a/http-generator-javalin/src/main/java/io/avaje/http/javalin/Before.java b/http-api/src/main/java/io/avaje/http/api/javalin/Before.java similarity index 92% rename from http-generator-javalin/src/main/java/io/avaje/http/javalin/Before.java rename to http-api/src/main/java/io/avaje/http/api/javalin/Before.java index 5fae5ab4f..c4c10819e 100644 --- a/http-generator-javalin/src/main/java/io/avaje/http/javalin/Before.java +++ b/http-api/src/main/java/io/avaje/http/api/javalin/Before.java @@ -1,4 +1,4 @@ -package io.avaje.http.javalin; +package io.avaje.http.api.javalin; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.RetentionPolicy.SOURCE; diff --git a/http-api/src/main/java/module-info.java b/http-api/src/main/java/module-info.java index 5fe2e429f..8ca65a240 100644 --- a/http-api/src/main/java/module-info.java +++ b/http-api/src/main/java/module-info.java @@ -1,6 +1,7 @@ module io.avaje.http.api { exports io.avaje.http.api; + exports io.avaje.http.api.javalin; exports io.avaje.http.api.context; exports io.avaje.http.api.spi; } diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index 4674cf7af..0dbf99c6c 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -23,6 +23,13 @@ ${avaje.prisms.version} provided + + io.avaje + avaje-http-api + ${project.version} + true + provided + diff --git a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinProcessor.java b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinProcessor.java index db829b5cc..5d74360aa 100644 --- a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinProcessor.java +++ b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinProcessor.java @@ -2,12 +2,12 @@ import java.io.IOException; +import io.avaje.http.api.javalin.After; +import io.avaje.http.api.javalin.Before; import io.avaje.http.generator.core.BaseProcessor; import io.avaje.http.generator.core.ControllerReader; import io.avaje.http.generator.core.PlatformAdapter; import io.avaje.http.generator.core.ProcessingContext; -import io.avaje.http.javalin.After; -import io.avaje.http.javalin.Before; import io.avaje.prism.GeneratePrism; @GeneratePrism(value = After.class, superClass = AbstractCustomMethodPrism.class) diff --git a/http-generator-javalin/src/main/java/module-info.java b/http-generator-javalin/src/main/java/module-info.java index 557a7633e..f05cc4f15 100644 --- a/http-generator-javalin/src/main/java/module-info.java +++ b/http-generator-javalin/src/main/java/module-info.java @@ -6,6 +6,7 @@ requires java.sql; // SHADED: All content after this line will be removed at package time - requires transitive io.avaje.http.generator.core; + requires io.avaje.http.generator.core; + requires io.avaje.http.api; requires static io.avaje.prism; } diff --git a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController2.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController2.java index 9629d795f..0ae288653 100644 --- a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController2.java +++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController2.java @@ -8,8 +8,8 @@ import org.example.myapp.web.ServerType; import io.avaje.http.api.*; -import io.avaje.http.javalin.After; -import io.avaje.http.javalin.Before; +import io.avaje.http.api.javalin.After; +import io.avaje.http.api.javalin.Before; import io.javalin.http.Context; @Path("test/") From ae8aadd3bcb33cf09b90bdbd53dd3e3a5cfc762a Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Fri, 18 Aug 2023 01:01:06 -0400 Subject: [PATCH 0857/1323] Fix Javalin DI example --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9012234ae..462194272 100644 --- a/README.md +++ b/README.md @@ -99,7 +99,7 @@ get all the WebRoutes and register them with Javalin using: ```java List routes = BeanScope.builder().build().list(Plugin.class); -Javalin.create(cfg -> routes.forEach(cfg.plugins::register)); +Javalin.create(cfg -> routes.forEach(cfg.plugins::register)).start(); ``` ### Usage with Helidon Nima From dea75681396f77920f3fa7d4741ed659b8b91bec Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Wed, 23 Aug 2023 22:06:50 -0400 Subject: [PATCH 0858/1323] client decoder --- .../io/avaje/http/client/DBaseBuilder.java | 14 +- .../avaje/http/client/DHttpClientBuilder.java | 7 + .../avaje/http/client/DHttpClientContext.java | 41 +++- .../client/DHttpClientContextBuilder.java | 180 ------------------ .../avaje/http/client/DHttpClientRequest.java | 43 ++++- .../client/DHttpClientRequestWithRetry.java | 59 +++++- .../java/io/avaje/http/client/HttpClient.java | 8 + .../avaje/http/client/HttpClientRequest.java | 4 + .../http/client/DHttpClientContextTest.java | 2 +- .../http/client/DHttpClientRequestTest.java | 2 +- .../java/org/example/github/GithubTest.java | 147 ++++++++++++-- http-generator-client/pom.xml | 13 -- .../generator/client/ClientMethodWriter.java | 25 +++ .../javax.annotation.processing.Processor | 1 - .../generator/client/clients/ApiClient.java | 3 + .../client/clients/MappedException.java | 8 + .../http/generator/core/MethodReader.java | 8 +- http-generator-helidon/pom.xml | 24 +-- .../javax.annotation.processing.Processor | 1 - http-generator-javalin/pom.xml | 23 +-- .../javax.annotation.processing.Processor | 1 - pom.xml | 3 +- 22 files changed, 342 insertions(+), 275 deletions(-) delete mode 100644 http-client/src/main/java/io/avaje/http/client/DHttpClientContextBuilder.java delete mode 100644 http-generator-client/src/main/resources/META-INF/services/javax.annotation.processing.Processor create mode 100644 http-generator-client/src/test/java/io/avaje/http/generator/client/clients/MappedException.java delete mode 100644 http-generator-helidon/src/main/resources/META-INF/services/javax.annotation.processing.Processor delete mode 100644 http-generator-javalin/src/main/resources/META-INF/services/javax.annotation.processing.Processor diff --git a/http-client/src/main/java/io/avaje/http/client/DBaseBuilder.java b/http-client/src/main/java/io/avaje/http/client/DBaseBuilder.java index 57cb5a725..9d823913b 100644 --- a/http-client/src/main/java/io/avaje/http/client/DBaseBuilder.java +++ b/http-client/src/main/java/io/avaje/http/client/DBaseBuilder.java @@ -15,6 +15,7 @@ import java.util.List; import java.util.Optional; import java.util.concurrent.Executor; +import java.util.function.Function; import static java.util.Objects.requireNonNull; @@ -27,6 +28,7 @@ abstract class DBaseBuilder { Duration requestTimeout = Duration.ofSeconds(20); BodyAdapter bodyAdapter; RetryHandler retryHandler; + Function errorHandler; AuthTokenProvider authTokenProvider; CookieHandler cookieHandler = new CookieManager(); @@ -167,7 +169,15 @@ DHttpClientContext buildClient() { if (bodyAdapter == null) { bodyAdapter = defaultBodyAdapter(); } - return new DHttpClientContext(client, baseUrl, requestTimeout, bodyAdapter, retryHandler, buildListener(), authTokenProvider, buildIntercept()); + return new DHttpClientContext( + client, + baseUrl, + requestTimeout, + bodyAdapter, + retryHandler, + errorHandler, + buildListener(), + authTokenProvider, + buildIntercept()); } - } diff --git a/http-client/src/main/java/io/avaje/http/client/DHttpClientBuilder.java b/http-client/src/main/java/io/avaje/http/client/DHttpClientBuilder.java index c0426385f..5b855883a 100644 --- a/http-client/src/main/java/io/avaje/http/client/DHttpClientBuilder.java +++ b/http-client/src/main/java/io/avaje/http/client/DHttpClientBuilder.java @@ -10,6 +10,7 @@ import java.time.Duration; import java.util.Collections; import java.util.concurrent.Executor; +import java.util.function.Function; final class DHttpClientBuilder extends DBaseBuilder implements HttpClient.Builder, HttpClient.Builder.State { @@ -52,6 +53,12 @@ public HttpClient.Builder retryHandler(RetryHandler retryHandler) { return this; } + @Override + public HttpClient.Builder globalErrorMapper(Function handler) { + this.errorHandler = handler; + return this; + } + @Override public HttpClient.Builder requestLogging(boolean requestLogging) { this.requestLogging = requestLogging; diff --git a/http-client/src/main/java/io/avaje/http/client/DHttpClientContext.java b/http-client/src/main/java/io/avaje/http/client/DHttpClientContext.java index 5f0b3f75e..3380e544a 100644 --- a/http-client/src/main/java/io/avaje/http/client/DHttpClientContext.java +++ b/http-client/src/main/java/io/avaje/http/client/DHttpClientContext.java @@ -14,6 +14,7 @@ import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.LongAccumulator; import java.util.concurrent.atomic.LongAdder; +import java.util.function.Function; final class DHttpClientContext implements HttpClient, SpiHttpClient { @@ -39,13 +40,24 @@ final class DHttpClientContext implements HttpClient, SpiHttpClient { private final LongAdder metricResBytes = new LongAdder(); private final LongAdder metricResMicros = new LongAdder(); private final LongAccumulator metricResMaxMicros = new LongAccumulator(Math::max, 0); - - DHttpClientContext(java.net.http.HttpClient httpClient, String baseUrl, Duration requestTimeout, BodyAdapter bodyAdapter, RetryHandler retryHandler, RequestListener requestListener, AuthTokenProvider authTokenProvider, RequestIntercept intercept) { + private final Function errorHandler; + + DHttpClientContext( + java.net.http.HttpClient httpClient, + String baseUrl, + Duration requestTimeout, + BodyAdapter bodyAdapter, + RetryHandler retryHandler, + Function errorHandler, + RequestListener requestListener, + AuthTokenProvider authTokenProvider, + RequestIntercept intercept) { this.httpClient = httpClient; this.baseUrl = baseUrl; this.requestTimeout = requestTimeout; this.bodyAdapter = bodyAdapter; this.retryHandler = retryHandler; + this.errorHandler = errorHandler; this.requestListener = requestListener; this.authTokenProvider = authTokenProvider; this.withAuthToken = authTokenProvider != null; @@ -53,7 +65,6 @@ final class DHttpClientContext implements HttpClient, SpiHttpClient { } @Override - @SuppressWarnings("unchecked") public T create(Class clientInterface) { if (!clientInterface.isInterface()) { throw new IllegalArgumentException("API declarations must be interfaces."); @@ -109,6 +120,10 @@ public UrlBuilder url() { return new UrlBuilder(baseUrl); } + public Function errorMapper() { + return errorHandler; + } + @Override public java.net.http.HttpClient httpClient() { return httpClient; @@ -259,16 +274,28 @@ String firstHeader(HttpHeaders headers, String... names) { HttpResponse send(HttpRequest.Builder requestBuilder, HttpResponse.BodyHandler bodyHandler) { try { return httpClient.send(requestBuilder.build(), bodyHandler); - } catch (final IOException e) { - throw new HttpException(499, e); } catch (final InterruptedException e) { Thread.currentThread().interrupt(); throw new HttpException(499, e); + } catch (final Exception e) { + throw new HttpException(499, e); } } - CompletableFuture> sendAsync(HttpRequest.Builder requestBuilder, HttpResponse.BodyHandler bodyHandler) { - return httpClient.sendAsync(requestBuilder.build(), bodyHandler); + CompletableFuture> sendAsync( + HttpRequest.Builder requestBuilder, HttpResponse.BodyHandler bodyHandler) { + return httpClient + .sendAsync(requestBuilder.build(), bodyHandler) + .handle( + (r, e) -> { + if (e != null) { + if (e.getCause() instanceof InterruptedException) { + Thread.currentThread().interrupt(); + } + throw new HttpException(499, e.getCause()); + } + return r; + }); } BodyContent write(T bean, Class type, String contentType) { diff --git a/http-client/src/main/java/io/avaje/http/client/DHttpClientContextBuilder.java b/http-client/src/main/java/io/avaje/http/client/DHttpClientContextBuilder.java deleted file mode 100644 index 7af837210..000000000 --- a/http-client/src/main/java/io/avaje/http/client/DHttpClientContextBuilder.java +++ /dev/null @@ -1,180 +0,0 @@ -package io.avaje.http.client; - -import java.net.Authenticator; -import java.net.CookieHandler; -import java.net.ProxySelector; -import java.time.Duration; -import java.util.Collections; -import java.util.concurrent.Executor; - -import javax.net.ssl.SSLContext; -import javax.net.ssl.SSLParameters; - -import io.avaje.inject.BeanScope; - -final class DHttpClientContextBuilder extends DBaseBuilder implements HttpClient.Builder, HttpClient.Builder.State { - - DHttpClientContextBuilder() { - } - - @Override - public HttpClient.Builder client(java.net.http.HttpClient client) { - this.client = client; - return this; - } - - @Override - public HttpClient.Builder baseUrl(String baseUrl) { - this.baseUrl = baseUrl; - return this; - } - - @Override - public HttpClient.Builder connectionTimeout(Duration connectionTimeout) { - this.connectionTimeout = connectionTimeout; - return this; - } - - @Override - public HttpClient.Builder requestTimeout(Duration requestTimeout) { - this.requestTimeout = requestTimeout; - return this; - } - - @Override - public HttpClient.Builder bodyAdapter(BodyAdapter adapter) { - this.bodyAdapter = adapter; - return this; - } - - @Override - public HttpClient.Builder retryHandler(RetryHandler retryHandler) { - this.retryHandler = retryHandler; - return this; - } - - @Override - public HttpClient.Builder requestLogging(boolean requestLogging) { - this.requestLogging = requestLogging; - return this; - } - - @Override - public HttpClient.Builder requestListener(RequestListener... requestListener) { - Collections.addAll(listeners, requestListener); - return this; - } - - @Override - public HttpClient.Builder requestIntercept(RequestIntercept... requestIntercept) { - Collections.addAll(interceptors, requestIntercept); - return this; - } - - @Override - public HttpClient.Builder authTokenProvider(AuthTokenProvider authTokenProvider) { - this.authTokenProvider = authTokenProvider; - return this; - } - - @Override - public HttpClient.Builder cookieHandler(CookieHandler cookieHandler) { - this.cookieHandler = cookieHandler; - return this; - } - - @Override - public HttpClient.Builder redirect(java.net.http.HttpClient.Redirect redirect) { - this.redirect = redirect; - return this; - } - - @Override - public HttpClient.Builder version(java.net.http.HttpClient.Version version) { - this.version = version; - return this; - } - - @Override - public HttpClient.Builder executor(Executor executor) { - this.executor = executor; - return this; - } - - @Override - public HttpClient.Builder proxy(ProxySelector proxySelector) { - this.proxy = proxySelector; - return this; - } - - @Override - public HttpClient.Builder sslContext(SSLContext sslContext) { - this.sslContext = sslContext; - return this; - } - - @Override - public HttpClient.Builder sslParameters(SSLParameters sslParameters) { - this.sslParameters = sslParameters; - return this; - } - - @Override - public HttpClient.Builder authenticator(Authenticator authenticator) { - this.authenticator = authenticator; - return this; - } - - @Override - public HttpClient.Builder priority(int priority) { - this.priority = priority; - return this; - } - - @Override - public State state() { - return this; - } - - @Override - public HttpClient.Builder configureWith(BeanScope beanScope) { - super.configureFromScope(beanScope); - return this; - } - - @Override - public HttpClient build() { - return super.buildClient(); - } - - @Override - public String baseUrl() { - return baseUrl; - } - - @Override - public BodyAdapter bodyAdapter() { - return bodyAdapter; - } - - @Override - public java.net.http.HttpClient client() { - return client; - } - - @Override - public boolean requestLogging() { - return requestLogging; - } - - @Override - public Duration requestTimeout() { - return requestTimeout; - } - - @Override - public RetryHandler retryHandler() { - return retryHandler; - } - -} diff --git a/http-client/src/main/java/io/avaje/http/client/DHttpClientRequest.java b/http-client/src/main/java/io/avaje/http/client/DHttpClientRequest.java index 74fe3ef14..071995a50 100644 --- a/http-client/src/main/java/io/avaje/http/client/DHttpClientRequest.java +++ b/http-client/src/main/java/io/avaje/http/client/DHttpClientRequest.java @@ -15,6 +15,7 @@ import java.time.Duration; import java.util.*; import java.util.concurrent.CompletableFuture; +import java.util.function.Function; import java.util.function.Supplier; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -55,11 +56,14 @@ class DHttpClientRequest implements HttpClientRequest, HttpClientResponse { private long startAsyncNanos; private String label; private Map customAttributes; + protected Function errorMapper; + protected boolean isRetry; DHttpClientRequest(DHttpClientContext context, Duration requestTimeout) { this.context = context; this.requestTimeout = requestTimeout; this.url = context.url(); + this.errorMapper = context.errorMapper(); } @Override @@ -334,6 +338,12 @@ public HttpClientRequest body(HttpRequest.BodyPublisher body) { return this; } + @Override + public HttpClientRequest errorMapper(Function errorMapper) { + this.errorMapper = errorMapper; + return this; + } + private HttpRequest.BodyPublisher body() { if (body != null) { return body; @@ -545,13 +555,20 @@ public HttpResponse handler(HttpResponse.BodyHandler responseHandler) return response; } - /** - * Prepare and send the request but not performing afterResponse() handling. - */ + /** Prepare and send the request but not performing afterResponse() handling. */ private HttpResponse sendWith(HttpResponse.BodyHandler responseHandler) { context.beforeRequest(this); addHeaders(); - final HttpResponse response = performSend(responseHandler); + final HttpResponse response; + if (errorMapper != null) { + try { + response = performSend(responseHandler); + } catch (final HttpException e) { + throw errorMapper.apply(e); + } + } else { + response = performSend(responseHandler); + } httpResponse = response; return response; } @@ -565,12 +582,26 @@ protected HttpResponse performSend(HttpResponse.BodyHandler responseHa } } - protected CompletableFuture> performSendAsync(boolean loggable, HttpResponse.BodyHandler responseHandler) { + protected CompletableFuture> performSendAsync( + boolean loggable, HttpResponse.BodyHandler responseHandler) { loggableResponseBody = loggable; context.beforeRequest(this); addHeaders(); startAsyncNanos = System.nanoTime(); - return context.sendAsync(httpRequest, responseHandler); + var resultFuture = context.sendAsync(httpRequest, responseHandler); + + if (errorMapper != null && !isRetry) { + resultFuture = + resultFuture.handle( + (r, e) -> { + if (e != null && e.getCause() instanceof HttpException) { + throw errorMapper.apply((HttpException) e.getCause()); + } + return r; + }); + } + + return resultFuture; } protected HttpResponse asyncVoid(HttpResponse response) { diff --git a/http-client/src/main/java/io/avaje/http/client/DHttpClientRequestWithRetry.java b/http-client/src/main/java/io/avaje/http/client/DHttpClientRequestWithRetry.java index eb7cdbfde..156e06a8f 100644 --- a/http-client/src/main/java/io/avaje/http/client/DHttpClientRequestWithRetry.java +++ b/http-client/src/main/java/io/avaje/http/client/DHttpClientRequestWithRetry.java @@ -2,23 +2,23 @@ import java.net.http.HttpResponse; import java.time.Duration; +import java.util.concurrent.CompletableFuture; +import java.util.function.Function; -/** - * Extends DHttpClientRequest with retry attempts. - */ +/** Extends DHttpClientRequest with retry attempts. */ final class DHttpClientRequestWithRetry extends DHttpClientRequest { private final RetryHandler retryHandler; private int retryCount; - DHttpClientRequestWithRetry(DHttpClientContext context, Duration requestTimeout, RetryHandler retryHandler) { + DHttpClientRequestWithRetry( + DHttpClientContext context, Duration requestTimeout, RetryHandler retryHandler) { super(context, requestTimeout); this.retryHandler = retryHandler; + isRetry = true; } - /** - * Perform send with retry. - */ + /** Perform send with retry. */ @Override protected HttpResponse performSend(HttpResponse.BodyHandler responseHandler) { HttpResponse res; @@ -45,6 +45,26 @@ protected HttpResponse performSend(HttpResponse.BodyHandler responseHa return res; } + /** Perform send with retry. */ + @Override + protected CompletableFuture> performSendAsync( + boolean loggable, HttpResponse.BodyHandler responseHandler) { + + var resultFuture = asyncwithRetry(loggable, responseHandler); + + if (errorMapper != null) { + resultFuture = + resultFuture.handle( + (r, e) -> { + if (e != null && e.getCause() instanceof HttpException) { + throw errorMapper.apply((HttpException) e.getCause()); + } + return r; + }); + } + return resultFuture; + } + protected boolean retry(HttpResponse res, HttpException ex) { if (res != null) { @@ -52,4 +72,29 @@ protected boolean retry(HttpResponse res, HttpException ex) { } return retryHandler.isExceptionRetry(retryCount, ex); } + + private CompletableFuture> asyncwithRetry( + boolean loggable, HttpResponse.BodyHandler responseHandler) { + + return super.performSendAsync(loggable, responseHandler) + .handle( + (res, ex) -> { + if (ex != null && ex.getCause() instanceof HttpException) { + if (!retryHandler.isExceptionRetry(retryCount, (HttpException) ex.getCause())) + return CompletableFuture.>failedFuture(ex.getCause()); + retryCount++; + return asyncwithRetry(loggable, responseHandler); + } + + if (res != null && res.statusCode() < 300) { + return CompletableFuture.completedFuture(res); + } + if (!retryHandler.isRetry(retryCount, res)) { + return CompletableFuture.>failedFuture(ex.getCause()); + } + retryCount++; + return asyncwithRetry(loggable, responseHandler); + }) + .thenCompose(Function.identity()); + } } diff --git a/http-client/src/main/java/io/avaje/http/client/HttpClient.java b/http-client/src/main/java/io/avaje/http/client/HttpClient.java index 7e0b3cce7..695766369 100644 --- a/http-client/src/main/java/io/avaje/http/client/HttpClient.java +++ b/http-client/src/main/java/io/avaje/http/client/HttpClient.java @@ -6,6 +6,7 @@ import java.time.Duration; import java.util.Map; import java.util.concurrent.Executor; +import java.util.function.Function; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLParameters; @@ -119,6 +120,13 @@ interface Builder { */ Builder baseUrl(String baseUrl); + /** + * Set the base URL to use for requests created from the context. + *

    + * Note that the base url can be replaced via {@link HttpClientRequest#url(String)}. + */ + Builder globalErrorMapper(Function handler); + /** * Set the connection timeout to use. * diff --git a/http-client/src/main/java/io/avaje/http/client/HttpClientRequest.java b/http-client/src/main/java/io/avaje/http/client/HttpClientRequest.java index 6376cf75e..f1f74dc7f 100644 --- a/http-client/src/main/java/io/avaje/http/client/HttpClientRequest.java +++ b/http-client/src/main/java/io/avaje/http/client/HttpClientRequest.java @@ -9,6 +9,7 @@ import java.util.Collection; import java.util.List; import java.util.Map; +import java.util.function.Function; import java.util.function.Supplier; /** @@ -388,6 +389,8 @@ default HttpClientRequest queryParam(String name, Collection values) { */ HttpClientRequest body(HttpRequest.BodyPublisher body); + HttpClientRequest errorMapper(Function errorMapper); + /** * Execute the request as a GET. */ @@ -429,4 +432,5 @@ default HttpClientRequest queryParam(String name, Collection values) { * This is useful for use in {@link RequestIntercept#afterResponse(HttpResponse, HttpClientRequest)} */ long responseTimeMicros(); + } diff --git a/http-client/src/test/java/io/avaje/http/client/DHttpClientContextTest.java b/http-client/src/test/java/io/avaje/http/client/DHttpClientContextTest.java index 6a9e2f4d2..be19baa39 100644 --- a/http-client/src/test/java/io/avaje/http/client/DHttpClientContextTest.java +++ b/http-client/src/test/java/io/avaje/http/client/DHttpClientContextTest.java @@ -9,7 +9,7 @@ class DHttpClientContextTest { - private final DHttpClientContext context = new DHttpClientContext(null, null, null, null, null, null, null, null); + private final DHttpClientContext context = new DHttpClientContext(null, null, null, null, null, null, null, null, null); @Test void create() { diff --git a/http-client/src/test/java/io/avaje/http/client/DHttpClientRequestTest.java b/http-client/src/test/java/io/avaje/http/client/DHttpClientRequestTest.java index 11ea00279..ea25b2535 100644 --- a/http-client/src/test/java/io/avaje/http/client/DHttpClientRequestTest.java +++ b/http-client/src/test/java/io/avaje/http/client/DHttpClientRequestTest.java @@ -9,7 +9,7 @@ class DHttpClientRequestTest { - final DHttpClientContext context = new DHttpClientContext(null, null, null, null, null, null, null, null); + final DHttpClientContext context = new DHttpClientContext(null, null, null, null, null, null, null, null, null); @Test void suppressLogging_listenerEvent_expect_suppressedPayloadContent() { diff --git a/http-client/src/test/java/org/example/github/GithubTest.java b/http-client/src/test/java/org/example/github/GithubTest.java index 473df7c99..9da4409ad 100644 --- a/http-client/src/test/java/org/example/github/GithubTest.java +++ b/http-client/src/test/java/org/example/github/GithubTest.java @@ -1,13 +1,20 @@ package org.example.github; import io.avaje.http.client.HttpClient; +import io.avaje.http.client.HttpException; import io.avaje.http.client.JacksonBodyAdapter; +import io.avaje.http.client.RetryHandler; + import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; +import java.net.http.HttpResponse; import java.util.List; +import java.util.concurrent.CompletionException; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.assertj.core.api.Assertions.extractProperty; public class GithubTest { @@ -15,11 +22,12 @@ public class GithubTest { @Disabled void test() { - final HttpClient clientContext = HttpClient.builder() - .baseUrl("https://api.github.com") - .bodyAdapter(new JacksonBodyAdapter()) - .requestLogging(false) - .build(); + final HttpClient clientContext = + HttpClient.builder() + .baseUrl("https://api.github.com") + .bodyAdapter(new JacksonBodyAdapter()) + .requestLogging(false) + .build(); // will not work under module classpath without registering the HttpApiProvider final Simple simple = clientContext.create(Simple.class); @@ -27,15 +35,126 @@ void test() { final List repos = simple.listRepos("rbygrave", "junk"); assertThat(repos).isNotEmpty(); - clientContext.request() - .path("users").path("rbygrave").path("repos") - .GET() - .async() - .asString() - .thenAccept(res -> { - System.out.println("RES: " + res.statusCode()); - System.out.println("BODY: " + res.body().substring(0, 150) + "..."); - }).join(); + clientContext + .request() + .path("users") + .path("rbygrave") + .path("repos") + .GET() + .async() + .asString() + .thenAccept( + res -> { + System.out.println("RES: " + res.statusCode()); + System.out.println("BODY: " + res.body().substring(0, 150) + "..."); + }) + .join(); + } + + @Test + void testExceptionMapping() { + + final HttpClient clientContext = + HttpClient.builder() + .baseUrl("https://bogus-link") + .globalErrorMapper(e -> new IllegalStateException()) + .bodyAdapter(new JacksonBodyAdapter()) + .requestLogging(false) + .build(); + + // will not work under module classpath without registering the HttpApiProvider + final Simple simple = clientContext.create(Simple.class); + + assertThatThrownBy(() -> simple.listRepos("rbygrave", "junk")) + .isInstanceOf(IllegalStateException.class); + } + + @Test + void testExceptionMappingAsync() { + + final HttpClient clientContext = + HttpClient.builder() + .baseUrl("https://bogus-link") + .bodyAdapter(new JacksonBodyAdapter()) + .globalErrorMapper(e -> new IllegalStateException()) + .requestLogging(false) + .build(); + + assertThatThrownBy( + () -> + clientContext + .request() + .path("users") + .path("rbygrave") + .path("repos") + .errorMapper(e -> new IllegalArgumentException()) + .GET() + .async() + .asString() + .join()) + .isInstanceOf(CompletionException.class) + .hasCauseInstanceOf(IllegalArgumentException.class); + } + + @Test + void testSyncRetry() { + + final HttpClient clientContext = + HttpClient.builder() + .baseUrl("https://bogus-link") + .globalErrorMapper(e -> new IllegalStateException()) + .bodyAdapter(new JacksonBodyAdapter()) + .retryHandler(new Retry()) + .requestLogging(false) + .build(); + + // will not work under module classpath without registering the HttpApiProvider + final Simple simple = clientContext.create(Simple.class); + + assertThatThrownBy(() -> simple.listRepos("rbygrave", "junk")) + .isInstanceOf(IllegalStateException.class); + } + + @Test + void testAsyncRetry() { + + final HttpClient clientContext = + HttpClient.builder() + .baseUrl("https://bogus-link") + .bodyAdapter(new JacksonBodyAdapter()) + .globalErrorMapper(e -> new IllegalStateException()) + .retryHandler(new Retry()) + .requestLogging(false) + .build(); + + assertThatThrownBy( + () -> + clientContext + .request() + .path("users") + .path("rbygrave") + .path("repos") + .errorMapper(e -> new IllegalArgumentException()) + .GET() + .async() + .asString() + .join()) + .isInstanceOf(CompletionException.class) + .hasCauseInstanceOf(IllegalArgumentException.class); } + static class Retry implements RetryHandler { + + @Override + public boolean isRetry(int retryCount, HttpResponse response) { + + return false; + } + + @Override + public boolean isExceptionRetry(int retryCount, HttpException exception) { + + return retryCount < 3; + } + } } diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index 0e5b0cb86..8a6268368 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -45,19 +45,6 @@ - - org.apache.maven.plugins - maven-compiler-plugin - - - - io.avaje - avaje-prisms - ${avaje.prisms.version} - - - - org.apache.maven.plugins maven-surefire-plugin diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java index c923a7e31..741b8f65e 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java @@ -4,6 +4,8 @@ import io.avaje.http.generator.core.*; import javax.lang.model.element.TypeElement; +import javax.lang.model.type.TypeMirror; +import javax.lang.model.util.ElementFilter; import java.util.List; import java.util.Optional; @@ -104,6 +106,7 @@ void write() { writeFormParams(pathSegments); timeout.ifPresent(this::writeTimeout); writeBody(); + writeErrorMapper(); writeEnd(); } @@ -277,6 +280,28 @@ private void writeBody() { } } + private void writeErrorMapper() { + method.throwsList().stream() + .map(ProcessingContext::asElement) + .filter( + e -> + isAssignable2Interface( + e.getQualifiedName().toString(), "java.lang.RuntimeException")) + .filter( + e -> + ElementFilter.constructorsIn(e.getEnclosedElements()).stream() + .filter(c -> c.getParameters().size() == 1) + .map(c -> c.getParameters().get(0).asType().toString()) + .map(Util::trimAnnotations) + .anyMatch("io.avaje.http.client.HttpException"::equals)) + .findFirst() + .ifPresent( + exception -> + writer + .append(" .errorMapper(%s::new)", exception.getQualifiedName().toString()) + .eol()); + } + /** * Return true for body types that are directly supported. */ diff --git a/http-generator-client/src/main/resources/META-INF/services/javax.annotation.processing.Processor b/http-generator-client/src/main/resources/META-INF/services/javax.annotation.processing.Processor deleted file mode 100644 index 8f117955c..000000000 --- a/http-generator-client/src/main/resources/META-INF/services/javax.annotation.processing.Processor +++ /dev/null @@ -1 +0,0 @@ -io.avaje.http.generator.client.ClientProcessor diff --git a/http-generator-client/src/test/java/io/avaje/http/generator/client/clients/ApiClient.java b/http-generator-client/src/test/java/io/avaje/http/generator/client/clients/ApiClient.java index 37c22d1a8..2cf137130 100644 --- a/http-generator-client/src/test/java/io/avaje/http/generator/client/clients/ApiClient.java +++ b/http-generator-client/src/test/java/io/avaje/http/generator/client/clients/ApiClient.java @@ -9,4 +9,7 @@ public interface ApiClient { @Get("/inputstream") String apiCall(@Header("Accept") String accept); + + @Get("/mapped") + String mapped(@Header("Accept") String accept) throws MappedException; } diff --git a/http-generator-client/src/test/java/io/avaje/http/generator/client/clients/MappedException.java b/http-generator-client/src/test/java/io/avaje/http/generator/client/clients/MappedException.java new file mode 100644 index 000000000..448ab6352 --- /dev/null +++ b/http-generator-client/src/test/java/io/avaje/http/generator/client/clients/MappedException.java @@ -0,0 +1,8 @@ +package io.avaje.http.generator.client.clients; + +import io.avaje.http.client.HttpException; + +public class MappedException extends RuntimeException { + + public MappedException(HttpException e) {} +} diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java index 605d5a1e6..5be2ead05 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java @@ -54,6 +54,7 @@ public class MethodReader { private final boolean instrumentContext; private final boolean hasThrows; private String exceptionShortName; + private final List throwsList; MethodReader(ControllerReader bean, ExecutableElement element, ExecutableType actualExecutable) { this.bean = bean; @@ -74,7 +75,8 @@ public class MethodReader { this.superMethods = superMethods(element.getEnclosingElement(), element.getSimpleName().toString()); superMethods.forEach(m -> methodRoles.addAll(Util.findRoles(m))); - this.hasThrows = !element.getThrownTypes().isEmpty(); + this.throwsList = element.getThrownTypes(); + this.hasThrows = !throwsList.isEmpty(); this.securityRequirements = readSecurityRequirements(); this.apiResponses = buildApiResponses(); this.javadoc = buildJavadoc(element); @@ -462,4 +464,8 @@ public ExecutableElement element() { public String exceptionShortName() { return exceptionShortName; } + + public List throwsList() { + return throwsList; + } } diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index e105b5ead..ddc1991d0 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -17,26 +17,18 @@ - io.avaje avaje-http-generator-core ${project.version} + + io.avaje + avaje-prisms + ${avaje.prisms.version} + true + provided + - - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.10.1 - - 20 - -proc:none - - - - - + diff --git a/http-generator-helidon/src/main/resources/META-INF/services/javax.annotation.processing.Processor b/http-generator-helidon/src/main/resources/META-INF/services/javax.annotation.processing.Processor deleted file mode 100644 index 97697d264..000000000 --- a/http-generator-helidon/src/main/resources/META-INF/services/javax.annotation.processing.Processor +++ /dev/null @@ -1 +0,0 @@ -io.avaje.http.generator.helidon.nima.NimaProcessor diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index 0dbf99c6c..acf350fb0 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -23,6 +23,7 @@ ${avaje.prisms.version} provided + io.avaje avaje-http-api @@ -30,27 +31,5 @@ true provided - - - - - - - org.apache.maven.plugins - maven-compiler-plugin - - - - io.avaje - avaje-prisms - ${avaje.prisms.version} - - - - - - - - diff --git a/http-generator-javalin/src/main/resources/META-INF/services/javax.annotation.processing.Processor b/http-generator-javalin/src/main/resources/META-INF/services/javax.annotation.processing.Processor deleted file mode 100644 index dc1c70149..000000000 --- a/http-generator-javalin/src/main/resources/META-INF/services/javax.annotation.processing.Processor +++ /dev/null @@ -1 +0,0 @@ -io.avaje.http.generator.javalin.JavalinProcessor diff --git a/pom.xml b/pom.xml index 77e5b6de1..e4e819731 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ true 2.2.8 2.14.2 - 1.10 + 1.12 ${project.build.directory}${file.separator}module-info.shade @@ -32,7 +32,6 @@ 1.1 test - From 4737dbe0f21148e0c788d8c8f66fc83b9bed7d98 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Wed, 23 Aug 2023 22:38:29 -0400 Subject: [PATCH 0859/1323] Update DHttpClientRequestWithRetry.java --- .../client/DHttpClientRequestWithRetry.java | 3 ++- http-generator-helidon/pom.xml | 24 ++++++++++++------- .../javax.annotation.processing.Processor | 1 + 3 files changed, 19 insertions(+), 9 deletions(-) create mode 100644 http-generator-helidon/src/main/resources/META-INF/services/javax.annotation.processing.Processor diff --git a/http-client/src/main/java/io/avaje/http/client/DHttpClientRequestWithRetry.java b/http-client/src/main/java/io/avaje/http/client/DHttpClientRequestWithRetry.java index 156e06a8f..aeeae5e01 100644 --- a/http-client/src/main/java/io/avaje/http/client/DHttpClientRequestWithRetry.java +++ b/http-client/src/main/java/io/avaje/http/client/DHttpClientRequestWithRetry.java @@ -80,8 +80,9 @@ private CompletableFuture> asyncwithRetry( .handle( (res, ex) -> { if (ex != null && ex.getCause() instanceof HttpException) { - if (!retryHandler.isExceptionRetry(retryCount, (HttpException) ex.getCause())) + if (!retryHandler.isExceptionRetry(retryCount, (HttpException) ex.getCause())) { return CompletableFuture.>failedFuture(ex.getCause()); + } retryCount++; return asyncwithRetry(loggable, responseHandler); } diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index ddc1991d0..e105b5ead 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -17,18 +17,26 @@ + io.avaje avaje-http-generator-core ${project.version} - - io.avaje - avaje-prisms - ${avaje.prisms.version} - true - provided - - + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.10.1 + + 20 + -proc:none + + + + + diff --git a/http-generator-helidon/src/main/resources/META-INF/services/javax.annotation.processing.Processor b/http-generator-helidon/src/main/resources/META-INF/services/javax.annotation.processing.Processor new file mode 100644 index 000000000..97697d264 --- /dev/null +++ b/http-generator-helidon/src/main/resources/META-INF/services/javax.annotation.processing.Processor @@ -0,0 +1 @@ +io.avaje.http.generator.helidon.nima.NimaProcessor From 61067ccf84e74a1a97e374cf3031307bc290654f Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Thu, 24 Aug 2023 15:58:35 +1200 Subject: [PATCH 0860/1323] Use context.checkResponse() ... and next step will be to move that from the context to the request --- .../avaje/http/client/DHttpClientRequest.java | 29 ++++++------------- 1 file changed, 9 insertions(+), 20 deletions(-) diff --git a/http-client/src/main/java/io/avaje/http/client/DHttpClientRequest.java b/http-client/src/main/java/io/avaje/http/client/DHttpClientRequest.java index 071995a50..f2735823b 100644 --- a/http-client/src/main/java/io/avaje/http/client/DHttpClientRequest.java +++ b/http-client/src/main/java/io/avaje/http/client/DHttpClientRequest.java @@ -542,9 +542,7 @@ public Stream stream(Type type) { private Stream stream(BodyReader bodyReader) { final HttpResponse> res = handler(HttpResponse.BodyHandlers.ofLines()); this.httpResponse = res; - if (res.statusCode() >= 300) { - throw new HttpException(res, context); - } + context.checkResponse(res); return res.body().map(bodyReader::readBody); } @@ -559,18 +557,13 @@ public HttpResponse handler(HttpResponse.BodyHandler responseHandler) private HttpResponse sendWith(HttpResponse.BodyHandler responseHandler) { context.beforeRequest(this); addHeaders(); - final HttpResponse response; - if (errorMapper != null) { - try { - response = performSend(responseHandler); - } catch (final HttpException e) { - throw errorMapper.apply(e); - } - } else { - response = performSend(responseHandler); + try { + HttpResponse res = performSend(responseHandler); + httpResponse = res; + return res; + } catch (final HttpException e) { + throw errorMapper == null ? e: errorMapper.apply(e); } - httpResponse = response; - return response; } protected HttpResponse performSend(HttpResponse.BodyHandler responseHandler) { @@ -633,9 +626,7 @@ protected HttpResponse> asyncStream(Class type, HttpResponse= 300) { - throw new HttpException(response, context); - } + context.checkResponse(response); final BodyReader bodyReader = context.beanReader(type); return new HttpWrapperResponse<>(response.body().map(bodyReader::readBody), httpResponse); } @@ -644,9 +635,7 @@ protected HttpResponse> asyncStream(Type type, HttpResponse= 300) { - throw new HttpException(response, context); - } + context.checkResponse(response); final BodyReader bodyReader = context.beanReader(type); return new HttpWrapperResponse<>(response.body().map(bodyReader::readBody), httpResponse); } From 3a16ecb69a17478a536d53b8f333d138ca3d6730 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Thu, 24 Aug 2023 16:05:26 +1200 Subject: [PATCH 0861/1323] Move checkResponse() and checkMaybeThrow() to DHttpClientRequest and map error --- .../avaje/http/client/DHttpClientContext.java | 13 --------- .../avaje/http/client/DHttpClientRequest.java | 28 +++++++++++++++---- .../io/avaje/http/client/SpiHttpClient.java | 6 ---- 3 files changed, 22 insertions(+), 25 deletions(-) diff --git a/http-client/src/main/java/io/avaje/http/client/DHttpClientContext.java b/http-client/src/main/java/io/avaje/http/client/DHttpClientContext.java index 3380e544a..fff7a101b 100644 --- a/http-client/src/main/java/io/avaje/http/client/DHttpClientContext.java +++ b/http-client/src/main/java/io/avaje/http/client/DHttpClientContext.java @@ -199,19 +199,6 @@ public long avgMicros() { } } - @Override - public void checkResponse(HttpResponse response) { - if (response.statusCode() >= 300) { - throw new HttpException(response, this); - } - } - - void checkMaybeThrow(HttpResponse response) { - if (response.statusCode() >= 300) { - throw new HttpException(this, response); - } - } - @SuppressWarnings("unchecked") public BodyContent readErrorContent(boolean responseAsBytes, HttpResponse httpResponse) { if (responseAsBytes) { diff --git a/http-client/src/main/java/io/avaje/http/client/DHttpClientRequest.java b/http-client/src/main/java/io/avaje/http/client/DHttpClientRequest.java index f2735823b..95eea7dea 100644 --- a/http-client/src/main/java/io/avaje/http/client/DHttpClientRequest.java +++ b/http-client/src/main/java/io/avaje/http/client/DHttpClientRequest.java @@ -456,11 +456,27 @@ public HttpClientResponse TRACE() { return this; } + private RuntimeException mapException(HttpException e) { + return errorMapper == null ? e : errorMapper.apply(e); + } + + private void checkResponse(HttpResponse response) { + if (response.statusCode() >= 300) { + throw mapException(new HttpException(response, context)); + } + } + + private void checkMaybeThrow(HttpResponse response) { + if (response.statusCode() >= 300) { + throw mapException(new HttpException(context, response)); + } + } + private void readResponseContent() { final HttpResponse response = sendWith(HttpResponse.BodyHandlers.ofByteArray()); encodedResponseBody = context.readContent(response); context.afterResponse(this); - context.checkMaybeThrow(response); + checkMaybeThrow(response); } @Override @@ -542,7 +558,7 @@ public Stream stream(Type type) { private Stream stream(BodyReader bodyReader) { final HttpResponse> res = handler(HttpResponse.BodyHandlers.ofLines()); this.httpResponse = res; - context.checkResponse(res); + checkResponse(res); return res.body().map(bodyReader::readBody); } @@ -626,7 +642,7 @@ protected HttpResponse> asyncStream(Class type, HttpResponse bodyReader = context.beanReader(type); return new HttpWrapperResponse<>(response.body().map(bodyReader::readBody), httpResponse); } @@ -635,7 +651,7 @@ protected HttpResponse> asyncStream(Type type, HttpResponse bodyReader = context.beanReader(type); return new HttpWrapperResponse<>(response.body().map(bodyReader::readBody), httpResponse); } @@ -645,7 +661,7 @@ private void afterAsyncEncoded(HttpResponse response) { httpResponse = response; encodedResponseBody = context.readContent(response); context.afterResponse(this); - context.checkMaybeThrow(response); + checkMaybeThrow(response); } protected HttpResponse afterAsync(HttpResponse response) { @@ -680,7 +696,7 @@ public HttpResponse asString() { public HttpResponse asPlainString() { loggableResponseBody = true; final HttpResponse hres = addMetrics(handler(HttpResponse.BodyHandlers.ofString())); - context.checkResponse(hres); + checkResponse(hres); return hres; } diff --git a/http-client/src/main/java/io/avaje/http/client/SpiHttpClient.java b/http-client/src/main/java/io/avaje/http/client/SpiHttpClient.java index fe7835ec8..07c1e920a 100644 --- a/http-client/src/main/java/io/avaje/http/client/SpiHttpClient.java +++ b/http-client/src/main/java/io/avaje/http/client/SpiHttpClient.java @@ -38,10 +38,4 @@ interface SpiHttpClient { */ byte[] decodeContent(String encoding, byte[] content); - /** - * Check the response status code and throw HttpException if the status - * code is in the error range. - */ - void checkResponse(HttpResponse response); - } From 8e6491a86c1e0822ae7a5751907c62f463dd99f1 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Thu, 24 Aug 2023 23:43:46 +1200 Subject: [PATCH 0862/1323] Add test only - async using global error mapper --- .../java/org/example/github/GithubTest.java | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/http-client/src/test/java/org/example/github/GithubTest.java b/http-client/src/test/java/org/example/github/GithubTest.java index 9da4409ad..180b4b01f 100644 --- a/http-client/src/test/java/org/example/github/GithubTest.java +++ b/http-client/src/test/java/org/example/github/GithubTest.java @@ -14,7 +14,6 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.assertj.core.api.Assertions.extractProperty; public class GithubTest { @@ -84,9 +83,7 @@ void testExceptionMappingAsync() { () -> clientContext .request() - .path("users") - .path("rbygrave") - .path("repos") + .path("junk") .errorMapper(e -> new IllegalArgumentException()) .GET() .async() @@ -94,6 +91,19 @@ void testExceptionMappingAsync() { .join()) .isInstanceOf(CompletionException.class) .hasCauseInstanceOf(IllegalArgumentException.class); + + // global error mapper used + assertThatThrownBy( + () -> + clientContext + .request() + .path("junk") + .GET() + .async() + .asString() + .join()) + .isInstanceOf(CompletionException.class) + .hasCauseInstanceOf(IllegalStateException.class); } @Test From 6179f7e0ca3d7b3a130fd1d431869cca37ac080d Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Thu, 24 Aug 2023 23:44:09 +1200 Subject: [PATCH 0863/1323] Update test generated openapi.json --- .../src/main/resources/public/openapi.json | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/tests/test-javalin-jsonb/src/main/resources/public/openapi.json b/tests/test-javalin-jsonb/src/main/resources/public/openapi.json index 4601876c9..9fc694f3f 100644 --- a/tests/test-javalin-jsonb/src/main/resources/public/openapi.json +++ b/tests/test-javalin-jsonb/src/main/resources/public/openapi.json @@ -1539,6 +1539,66 @@ } } }, + "/test/formMap" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/test/formMulti" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "requestBody" : { + "content" : { + "application/x-www-form-urlencoded" : { + "schema" : { + "type" : "object", + "properties" : { + "strings" : { + "type" : "array", + "items" : { + "type" : "string" + } + } + } + } + } + }, + "required" : true + }, + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, "/test/header" : { "get" : { "tags" : [ From 8a3ad03a7ae0a073bfe11bde59bc716a25d6913e Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Thu, 24 Aug 2023 23:55:50 +1200 Subject: [PATCH 0864/1323] [http client] HttpException internally read the response body once If the response is read multiple times (say as String + decoded to a bean) then only read the response body once --- .../io/avaje/http/client/HttpException.java | 17 +++++++++++------ .../avaje/http/client/HelloControllerTest.java | 4 ++++ 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/http-client/src/main/java/io/avaje/http/client/HttpException.java b/http-client/src/main/java/io/avaje/http/client/HttpException.java index c9dce9993..360247588 100644 --- a/http-client/src/main/java/io/avaje/http/client/HttpException.java +++ b/http-client/src/main/java/io/avaje/http/client/HttpException.java @@ -46,6 +46,7 @@ public class HttpException extends RuntimeException { private final boolean responseAsBytes; private final DHttpClientContext context; private final HttpResponse httpResponse; + private BodyContent body; /** * Create with status code and message. @@ -96,6 +97,13 @@ public HttpException(int statusCode, Throwable cause) { this.responseAsBytes = true; } + private BodyContent readBody() { + if (body == null) { + body = context.readErrorContent(responseAsBytes, httpResponse); + } + return body; + } + /** * Return the response body content as a bean, or else null if body content doesn't exist. * @@ -106,8 +114,7 @@ public T bean(Class cls) { if (httpResponse == null) { return null; } - final BodyContent body = context.readErrorContent(responseAsBytes, httpResponse); - return context.readBean(cls, body); + return context.readBean(cls, readBody()); } /** @@ -117,8 +124,7 @@ public String bodyAsString() { if (httpResponse == null) { return null; } - final BodyContent body = context.readErrorContent(responseAsBytes, httpResponse); - return new String(body.content(), StandardCharsets.UTF_8); + return new String(readBody().content(), StandardCharsets.UTF_8); } /** @@ -128,8 +134,7 @@ public byte[] bodyAsBytes() { if (httpResponse == null) { return null; } - final BodyContent body = context.readErrorContent(responseAsBytes, httpResponse); - return body.content(); + return readBody().content(); } /** diff --git a/http-client/src/test/java/io/avaje/http/client/HelloControllerTest.java b/http-client/src/test/java/io/avaje/http/client/HelloControllerTest.java index 7be55f2ed..c90bdc568 100644 --- a/http-client/src/test/java/io/avaje/http/client/HelloControllerTest.java +++ b/http-client/src/test/java/io/avaje/http/client/HelloControllerTest.java @@ -517,6 +517,9 @@ void asPlainString_throwingHttpException() { // convert json error response body to a bean final ErrorResponse errorResponse = httpException.bean(ErrorResponse.class); assertThat(errorResponse.get("email")).isEqualTo("must be a well-formed email address"); + + String responseBodyString = httpException.bodyAsString(); + assertThat(responseBodyString).startsWith("{\"message\":\"Request failed validation\",\"errors\":"); } @Test @@ -1249,6 +1252,7 @@ void postForm_asBytes_validation_expect_badRequest_extractError() { final byte[] rawBytes = e.bodyAsBytes(); assertThat(rawBytes).isNotNull(); + assertThat(new String(rawBytes, 0, rawBytes.length, StandardCharsets.UTF_8)).contains("must be a valid URL"); } } From fc9b298a28324e8411529675eba26a2d6a628e17 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Fri, 25 Aug 2023 01:10:52 +1200 Subject: [PATCH 0865/1323] [http client] HttpException add isPlainText() and contentType() Helper methods to make it easier for use cases that need logic in reading the HttpException that could be text or json etc --- .../avaje/http/client/DHttpClientContext.java | 11 ++++++- .../io/avaje/http/client/HttpException.java | 15 +++++++++ .../http/client/HelloControllerTest.java | 26 +++++++++++++++ .../client/clients/MappedException.java | 32 ++++++++++++++++++- 4 files changed, 82 insertions(+), 2 deletions(-) diff --git a/http-client/src/main/java/io/avaje/http/client/DHttpClientContext.java b/http-client/src/main/java/io/avaje/http/client/DHttpClientContext.java index fff7a101b..2d405f2f2 100644 --- a/http-client/src/main/java/io/avaje/http/client/DHttpClientContext.java +++ b/http-client/src/main/java/io/avaje/http/client/DHttpClientContext.java @@ -15,6 +15,8 @@ import java.util.concurrent.atomic.LongAccumulator; import java.util.concurrent.atomic.LongAdder; import java.util.function.Function; +import java.util.stream.Collectors; +import java.util.stream.Stream; final class DHttpClientContext implements HttpClient, SpiHttpClient { @@ -200,7 +202,7 @@ public long avgMicros() { } @SuppressWarnings("unchecked") - public BodyContent readErrorContent(boolean responseAsBytes, HttpResponse httpResponse) { + BodyContent readErrorContent(boolean responseAsBytes, HttpResponse httpResponse) { if (responseAsBytes) { return readContent((HttpResponse) httpResponse); } @@ -209,6 +211,13 @@ public BodyContent readErrorContent(boolean responseAsBytes, HttpResponse htt if (body instanceof String) { return new BodyContent(contentType, ((String) body).getBytes(StandardCharsets.UTF_8)); } + if (body instanceof Stream) { + var sb = new StringBuilder(50); + for (Object line : ((Stream) body).collect(Collectors.toList())) { + sb.append(line); + } + return new BodyContent(contentType, sb.toString().getBytes(StandardCharsets.UTF_8)); + } final String type = (body == null) ? "null" : body.getClass().toString(); throw new IllegalStateException("Unable to translate response body to bytes? Maybe use HttpResponse directly instead? Response body type: " + type); } diff --git a/http-client/src/main/java/io/avaje/http/client/HttpException.java b/http-client/src/main/java/io/avaje/http/client/HttpException.java index 360247588..a6c8f8ab3 100644 --- a/http-client/src/main/java/io/avaje/http/client/HttpException.java +++ b/http-client/src/main/java/io/avaje/http/client/HttpException.java @@ -2,6 +2,7 @@ import java.net.http.HttpResponse; import java.nio.charset.StandardCharsets; +import java.util.Optional; /** * HTTP Exception with support for converting the error response body into a bean. @@ -151,4 +152,18 @@ public HttpResponse httpResponse() { return httpResponse; } + /** + * Return the response Content-Type header. + */ + public Optional contentType() { + return httpResponse.headers().firstValue("Content-Type"); + } + + /** + * Return true if the Content-Type is text/plain. + */ + public boolean isPlainText() { + return "text/plain".equals(contentType().orElse(null)); + } + } diff --git a/http-client/src/test/java/io/avaje/http/client/HelloControllerTest.java b/http-client/src/test/java/io/avaje/http/client/HelloControllerTest.java index c90bdc568..1beebb1d8 100644 --- a/http-client/src/test/java/io/avaje/http/client/HelloControllerTest.java +++ b/http-client/src/test/java/io/avaje/http/client/HelloControllerTest.java @@ -286,6 +286,12 @@ void get_stream_NotFoundException() { assertThat(metrics.errorCount()).isEqualTo(1); assertThat(metrics.responseBytes()).isEqualTo(0); assertThat(metrics.totalMicros()).isGreaterThan(0); + + assertThat(httpException.bodyAsString()).isEqualTo("Not Found"); + assertThat(httpException.isPlainText()).isTrue(); + assertThat(httpException.contentType()) + .isPresent() + .get().isEqualTo("text/plain"); } @Test @@ -798,6 +804,20 @@ void async_list_as() throws ExecutionException, InterruptedException { assertThat(helloRes).isSameAs(ref.get()); } + @Test + void get_bean_404() { + try { + clientContext.request() + .path("does-not-exist") + .GET() + .bean(HelloDto.class); + } catch (HttpException e) { + assertThat(e.statusCode()).isEqualTo(404); + assertThat(e.contentType()).isPresent().get().isEqualTo("text/plain"); + assertThat(e.bodyAsString()).isEqualTo("Not Found"); + } + } + @Test void get_withPathParamAndQueryParam_returningBean() { @@ -1243,6 +1263,12 @@ void postForm_asBytes_validation_expect_badRequest_extractError() { assertNotNull(httpResponse); assertEquals(422, httpResponse.statusCode()); + assertThat(e.contentType()) + .isPresent() + .get().isEqualTo("application/json"); + + assertThat(e.isPlainText()).isFalse(); + final ErrorResponse errorResponse = e.bean(ErrorResponse.class); assertThat(errorResponse.get("url")).isEqualTo("must be a valid URL"); assertThat(errorResponse.get("name")).isEqualTo("must not be null"); diff --git a/http-generator-client/src/test/java/io/avaje/http/generator/client/clients/MappedException.java b/http-generator-client/src/test/java/io/avaje/http/generator/client/clients/MappedException.java index 448ab6352..387c63ce6 100644 --- a/http-generator-client/src/test/java/io/avaje/http/generator/client/clients/MappedException.java +++ b/http-generator-client/src/test/java/io/avaje/http/generator/client/clients/MappedException.java @@ -4,5 +4,35 @@ public class MappedException extends RuntimeException { - public MappedException(HttpException e) {} + private final int statusCode; + private String responseMessage; + private MyJsonErrorPayload myPayload; + + public MappedException(HttpException httpException) { + super("Error response with statusCode: " + httpException.statusCode()); + this.statusCode = httpException.statusCode(); + if (httpException.isPlainText()) { + this.responseMessage = httpException.bodyAsString(); + } else { + this.myPayload = httpException.bean(MyJsonErrorPayload.class); + } + addSuppressed(httpException); + } + + public int statusCode() { + return statusCode; + } + + public String responseMessage() { + return responseMessage; + } + + public MyJsonErrorPayload myPayload() { + return myPayload; + } + + // @Json + static class MyJsonErrorPayload { + // fields + } } From dc44423a30644c30519d6dbb12210993891b58c2 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Thu, 24 Aug 2023 18:09:15 -0400 Subject: [PATCH 0866/1323] int response --- .../io/avaje/http/api/OpenAPIResponse.java | 2 +- .../core/openapi/MethodDocBuilder.java | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/http-api/src/main/java/io/avaje/http/api/OpenAPIResponse.java b/http-api/src/main/java/io/avaje/http/api/OpenAPIResponse.java index fc4bf96c3..b9fcb8374 100644 --- a/http-api/src/main/java/io/avaje/http/api/OpenAPIResponse.java +++ b/http-api/src/main/java/io/avaje/http/api/OpenAPIResponse.java @@ -42,7 +42,7 @@ public @interface OpenAPIResponse { /** the http status code of this response */ - String responseCode(); + int responseCode(); /** * The description of the return value. By default uses the @return javadoc of the method as the diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/MethodDocBuilder.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/MethodDocBuilder.java index 338726959..944a5d183 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/MethodDocBuilder.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/MethodDocBuilder.java @@ -49,7 +49,7 @@ public void build() { operation.setDeprecated(true); } - PathItem pathItem = ctx.pathItem(methodReader.fullPath()); + final PathItem pathItem = ctx.pathItem(methodReader.fullPath()); switch ((CoreWebMethod) methodReader.webMethod()) { case GET: pathItem.setGet(operation); @@ -68,20 +68,20 @@ public void build() { break; } - var securityRequirements = methodReader.securityRequirements(); - for (SecurityRequirementPrism p : securityRequirements) { - var o = new SecurityRequirement().addList(p.name(), p.scopes()); + final var securityRequirements = methodReader.securityRequirements(); + for (final SecurityRequirementPrism p : securityRequirements) { + final var o = new SecurityRequirement().addList(p.name(), p.scopes()); operation.addSecurityItem(o); } - for (MethodParam param : methodReader.params()) { + for (final MethodParam param : methodReader.params()) { param.buildApiDocumentation(this); } - ApiResponses responses = new ApiResponses(); + final ApiResponses responses = new ApiResponses(); operation.setResponses(responses); - ApiResponse response = new ApiResponse(); + final ApiResponse response = new ApiResponse(); response.setDescription(javadoc.getReturnDescription()); final var produces = methodReader.produces(); @@ -106,7 +106,7 @@ public void build() { } // if user wants to define their own 2xx status code - if (responseAnnotation.responseCode().startsWith("2")) { + if (responseAnnotation.responseCode().toString().startsWith("2")) { newResponse.setContent(response.getContent()); override2xx = !hasProducesStatus; } @@ -116,7 +116,7 @@ public void build() { newResponse.setContent(ctx.createContent(returnType, contentMediaType)); } - responses.addApiResponse(responseAnnotation.responseCode(), newResponse); + responses.addApiResponse(responseAnnotation.responseCode().toString(), newResponse); } if (!override2xx) responses.addApiResponse(String.valueOf(methodReader.statusCode()), response); } From f8fb143ba130fbe9d1ca3a83c8c2a1cba610c01f Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Thu, 24 Aug 2023 18:15:53 -0400 Subject: [PATCH 0867/1323] fix tests --- .../myapp/web/test/HealthController.java | 4 ++-- .../myapp/web/test/OpenAPIController.java | 24 ++++++++++++------- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/HealthController.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/HealthController.java index 697c82451..105cee81e 100644 --- a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/HealthController.java +++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/HealthController.java @@ -19,7 +19,7 @@ @Info( title = "Example service showing off the Path extension method of controller", description = "")) -@OpenAPIResponse(responseCode = "403", description = "Not Authorized") +@OpenAPIResponse(responseCode = 403, description = "Not Authorized") public interface HealthController { /** * Standard Get @@ -29,6 +29,6 @@ public interface HealthController { @Get("/health") @Produces(MediaType.TEXT_PLAIN) @Tag(name = "tag1", description = "it's somethin") - @OpenAPIResponse(responseCode = "500", type = ErrorResponse.class) + @OpenAPIResponse(responseCode = 500, type = ErrorResponse.class) String health(); } diff --git a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/OpenAPIController.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/OpenAPIController.java index 709e76b43..3912649e2 100644 --- a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/OpenAPIController.java +++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/OpenAPIController.java @@ -26,7 +26,13 @@ description = "Example Javalin controllers with Java and Maven")) @Controller @Path("openapi/") -@SecurityScheme(type = SecuritySchemeType.APIKEY, in = SecuritySchemeIn.QUERY, name = "JWT", paramName = "access_token", description = "JSON Web Tokens are an open, industry standard RFC 7519 method for representing claims securely between two parties.") +@SecurityScheme( + type = SecuritySchemeType.APIKEY, + in = SecuritySchemeIn.QUERY, + name = "JWT", + paramName = "access_token", + description = + "JSON Web Tokens are an open, industry standard RFC 7519 method for representing claims securely between two parties.") public class OpenAPIController { /** @@ -38,7 +44,7 @@ public class OpenAPIController { */ @Get("/get") @Produces(MediaType.TEXT_PLAIN) - @OpenAPIResponse(responseCode = "200", type = String.class) + @OpenAPIResponse(responseCode = 200, type = String.class) void ctxEndpoint(Context ctx) { ctx.contentType(MediaType.TEXT_PLAIN).result("healthlmao"); } @@ -51,13 +57,13 @@ void ctxEndpoint(Context ctx) { */ @Post("/post") @Tag(name = "tag1", description = "this is added to openapi tags") - @OpenAPIResponse(responseCode = "200", description = "overrides @return javadoc description") - @OpenAPIResponse(responseCode = "201") + @OpenAPIResponse(responseCode = 200, description = "overrides @return javadoc description") + @OpenAPIResponse(responseCode = 201) @OpenAPIResponse( - responseCode = "400", + responseCode = 400, description = "User not found (Will not have an associated response schema)") @OpenAPIResponse( - responseCode = "500", + responseCode = 500, description = "Some other Error (Will have this error class as the response class)", type = ErrorResponse.class) Person testPost(Person b) { @@ -73,9 +79,9 @@ Person testPost(Person b) { @Deprecated @Post("/post1") @OpenAPIResponses({ - @OpenAPIResponse(responseCode = "400", description = "User not found"), + @OpenAPIResponse(responseCode = 400, description = "User not found"), @OpenAPIResponse( - responseCode = "500", + responseCode = 500, description = "Some other Error", type = ErrorResponse.class) }) @@ -85,7 +91,7 @@ Person testPostList(List m) { @Put("/put") @Produces(value = MediaType.TEXT_PLAIN, statusCode = 203) - @OpenAPIResponse(responseCode = "204", type = String.class) + @OpenAPIResponse(responseCode = 204, type = String.class) String testDefaultStatus(Context ctx) { if (ctx.contentType().equals(MediaType.APPLICATION_PDF)) { ctx.status(204); From 609022cacadad999c9cc93cee2f49a32cf121973 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Thu, 24 Aug 2023 18:29:43 -0400 Subject: [PATCH 0868/1323] doc --- .../main/java/io/avaje/http/client/HttpClient.java | 13 +++++++++---- .../io/avaje/http/client/HttpClientRequest.java | 9 +++++++++ 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/http-client/src/main/java/io/avaje/http/client/HttpClient.java b/http-client/src/main/java/io/avaje/http/client/HttpClient.java index 695766369..f51f95cb3 100644 --- a/http-client/src/main/java/io/avaje/http/client/HttpClient.java +++ b/http-client/src/main/java/io/avaje/http/client/HttpClient.java @@ -121,11 +121,16 @@ interface Builder { Builder baseUrl(String baseUrl); /** - * Set the base URL to use for requests created from the context. - *

    - * Note that the base url can be replaced via {@link HttpClientRequest#url(String)}. + * Set the default mapper to be used to transform {@link HttpException} into a different kind of + * exception. Individual requests can override with their own mapper. + * + *

    When set, all {@link HttpException} that are thrown by this client will be caught and + * rethrown with the given function by default. + * + * @param errorMapper The function to map the httpException + * @return The request being built */ - Builder globalErrorMapper(Function handler); + Builder globalErrorMapper(Function errorMapper); /** * Set the connection timeout to use. diff --git a/http-client/src/main/java/io/avaje/http/client/HttpClientRequest.java b/http-client/src/main/java/io/avaje/http/client/HttpClientRequest.java index f1f74dc7f..7ac392521 100644 --- a/http-client/src/main/java/io/avaje/http/client/HttpClientRequest.java +++ b/http-client/src/main/java/io/avaje/http/client/HttpClientRequest.java @@ -389,6 +389,15 @@ default HttpClientRequest queryParam(String name, Collection values) { */ HttpClientRequest body(HttpRequest.BodyPublisher body); + /** + * Set the mapper used to transform {@link HttpException} into a different kind of exception. + * + *

    When set, all {@link HttpException} that are thrown by this request will be caught and + * transformed into more specific exception with the given function by default. + * + * @param errorMapper function to map the httpException + * @return The request being built + */ HttpClientRequest errorMapper(Function errorMapper); /** From 16422540f370ca8624826ec7966190c418db5032 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Thu, 24 Aug 2023 20:31:38 -0400 Subject: [PATCH 0869/1323] style changes --- http-client/pom.xml | 4 +- .../avaje/http/client/BasicAuthIntercept.java | 20 +++------- .../io/avaje/http/client/DBaseBuilder.java | 36 +++++++++--------- .../java/io/avaje/http/client/DHttpApi.java | 19 ++-------- .../avaje/http/client/DHttpClientContext.java | 38 +------------------ .../avaje/http/client/DHttpClientRequest.java | 29 +++++++------- .../java/io/avaje/http/client/GzipUtil.java | 22 +++++------ .../avaje/http/client/JacksonBodyAdapter.java | 2 +- .../http/client/DHttpClientContextTest.java | 6 --- .../java/org/example/github/GithubTest.java | 10 ++--- 10 files changed, 60 insertions(+), 126 deletions(-) diff --git a/http-client/pom.xml b/http-client/pom.xml index e0ff8eb7d..ba2e004d6 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -36,14 +36,14 @@ io.avaje avaje-jsonb - 1.7-RC1 + 1.7 true io.avaje avaje-inject - 9.4 + 9.5 true diff --git a/http-client/src/main/java/io/avaje/http/client/BasicAuthIntercept.java b/http-client/src/main/java/io/avaje/http/client/BasicAuthIntercept.java index 431218431..7220e2d8f 100644 --- a/http-client/src/main/java/io/avaje/http/client/BasicAuthIntercept.java +++ b/http-client/src/main/java/io/avaje/http/client/BasicAuthIntercept.java @@ -1,27 +1,20 @@ package io.avaje.http.client; -import java.net.http.HttpResponse; -import java.util.Base64; - import static java.nio.charset.StandardCharsets.UTF_8; -/** - * Adds Basic Authorization header to requests. - */ +import java.util.Base64; + +/** Adds Basic Authorization header to requests. */ public class BasicAuthIntercept implements RequestIntercept { private final String headerValue; - /** - * Construct with the username and password. - */ + /** Construct with the username and password. */ public BasicAuthIntercept(String username, String password) { - this.headerValue = "Basic "+encode(username, password); + this.headerValue = "Basic " + encode(username, password); } - /** - * Return Base64 encoding of {@literal username:password} - */ + /** Return Base64 encoding of {@literal username:password} */ public static String encode(String username, String password) { return Base64.getEncoder().encodeToString((username + ":" + password).getBytes(UTF_8)); } @@ -30,5 +23,4 @@ public static String encode(String username, String password) { public void beforeRequest(HttpClientRequest request) { request.header("Authorization", headerValue); } - } diff --git a/http-client/src/main/java/io/avaje/http/client/DBaseBuilder.java b/http-client/src/main/java/io/avaje/http/client/DBaseBuilder.java index 9d823913b..678730c18 100644 --- a/http-client/src/main/java/io/avaje/http/client/DBaseBuilder.java +++ b/http-client/src/main/java/io/avaje/http/client/DBaseBuilder.java @@ -16,12 +16,13 @@ import java.util.Optional; import java.util.concurrent.Executor; import java.util.function.Function; +import java.net.http.HttpClient; import static java.util.Objects.requireNonNull; abstract class DBaseBuilder { - java.net.http.HttpClient client; + HttpClient client; String baseUrl; boolean requestLogging = true; Duration connectionTimeout = Duration.ofSeconds(20); @@ -32,8 +33,8 @@ abstract class DBaseBuilder { AuthTokenProvider authTokenProvider; CookieHandler cookieHandler = new CookieManager(); - java.net.http.HttpClient.Redirect redirect = java.net.http.HttpClient.Redirect.NORMAL; - java.net.http.HttpClient.Version version; + HttpClient.Redirect redirect = HttpClient.Redirect.NORMAL; + HttpClient.Version version; Executor executor; ProxySelector proxy; SSLContext sslContext; @@ -94,10 +95,11 @@ private RequestIntercept buildIntercept() { } } - private java.net.http.HttpClient defaultClient() { - final var builder = java.net.http.HttpClient.newBuilder() - .followRedirects(redirect) - .connectTimeout(connectionTimeout); + private HttpClient defaultClient() { + final var builder = + HttpClient.newBuilder() + .followRedirects(redirect) + .connectTimeout(connectionTimeout); if (cookieHandler != null) { builder.cookieHandler(cookieHandler); } @@ -125,18 +127,14 @@ private java.net.http.HttpClient defaultClient() { return builder.build(); } - /** - * Create a reasonable default BodyAdapter if avaje-jsonb or Jackson are present. - */ + /** Create a reasonable default BodyAdapter if avaje-jsonb or Jackson are present. */ private BodyAdapter defaultBodyAdapter() { - try { - return detectJsonb() ? new JsonbBodyAdapter() - : detectJackson() ? new JacksonBodyAdapter() - : null; - } catch (IllegalAccessError e) { - // not in module path - return null; + if (detectJsonb()) { + bodyAdapter = new JsonbBodyAdapter(); + } else if (detectJackson()) { + bodyAdapter = new JacksonBodyAdapter(); } + return bodyAdapter; } private boolean detectJsonb() { @@ -151,7 +149,7 @@ private boolean detectTypeExists(String className) { try { Class.forName(className); return true; - } catch (ClassNotFoundException e) { + } catch (ClassNotFoundException | IllegalAccessError e) { return false; } } @@ -163,7 +161,7 @@ DHttpClientContext buildClient() { client = defaultClient(); } if (requestLogging) { - // register the builtin request/response logging + // register the built-in request/response logging this.listeners.add(new RequestLogger()); } if (bodyAdapter == null) { diff --git a/http-client/src/main/java/io/avaje/http/client/DHttpApi.java b/http-client/src/main/java/io/avaje/http/client/DHttpApi.java index 22f147f75..0f157c2bf 100644 --- a/http-client/src/main/java/io/avaje/http/client/DHttpApi.java +++ b/http-client/src/main/java/io/avaje/http/client/DHttpApi.java @@ -9,9 +9,7 @@ import static java.lang.System.Logger.Level.*; -/** - * Service loads the HttpApiProvider for HttpApi. - */ +/** Service loads the HttpApiProvider for HttpApi. */ final class DHttpApi { private static final System.Logger log = AppLog.getLogger("io.avaje.http.client"); @@ -25,7 +23,7 @@ final class DHttpApi { } void init() { - for (final GeneratedComponent apiProvider : ServiceLoader.load(GeneratedComponent.class)) { + for (final var apiProvider : ServiceLoader.load(GeneratedComponent.class)) { apiProvider.register(providerMap); } log.log(DEBUG, "providers for {0}", providerMap.keySet()); @@ -36,12 +34,8 @@ void addProvider(Class type, HttpApiProvider apiProvider) { } @SuppressWarnings("unchecked") - private HttpApiProvider lookup(Class type) { - return (HttpApiProvider) providerMap.get(type); - } - T provideFor(Class type, HttpClient httpClient) { - final HttpApiProvider apiProvider = lookup(type); + final var apiProvider = (HttpApiProvider) providerMap.get(type); if (apiProvider == null) { throw new IllegalArgumentException("No registered HttpApiProvider for type: " + type); } @@ -49,12 +43,7 @@ T provideFor(Class type, HttpClient httpClient) { } /** Return the client implementation via service loading. */ - static T provide(Class type, HttpClient httpClient) { + static T get(Class type, HttpClient httpClient) { return INSTANCE.provideFor(type, httpClient); } - - /** Return the HttpApiProvider for the client interface type or null if not registered. */ - static HttpApiProvider get(Class type) { - return INSTANCE.lookup(type); - } } diff --git a/http-client/src/main/java/io/avaje/http/client/DHttpClientContext.java b/http-client/src/main/java/io/avaje/http/client/DHttpClientContext.java index 2d405f2f2..82883908e 100644 --- a/http-client/src/main/java/io/avaje/http/client/DHttpClientContext.java +++ b/http-client/src/main/java/io/avaje/http/client/DHttpClientContext.java @@ -1,7 +1,5 @@ package io.avaje.http.client; -import java.io.IOException; -import java.lang.reflect.Constructor; import java.lang.reflect.Type; import java.net.http.HttpHeaders; import java.net.http.HttpRequest; @@ -68,41 +66,7 @@ final class DHttpClientContext implements HttpClient, SpiHttpClient { @Override public T create(Class clientInterface) { - if (!clientInterface.isInterface()) { - throw new IllegalArgumentException("API declarations must be interfaces."); - } - final HttpApiProvider apiProvider = DHttpApi.get(clientInterface); - if (apiProvider != null) { - return apiProvider.provide(this); - } - return constructReflectively(clientInterface); - } - - @SuppressWarnings("unchecked") - private T constructReflectively(Class clientInterface) { - try { - final Class implementationClass = implementationClass(clientInterface); - final Constructor constructor = implementationClass.getConstructor(HttpClient.class); - return (T) constructor.newInstance(this); - } catch (final Exception e) { - final String cn = implementationClassName(clientInterface, "HttpClient"); - throw new IllegalStateException("Failed to create http client service " + cn, e); - } - } - - private Class implementationClass(Class clientInterface) throws ClassNotFoundException { - try { - return Class.forName(implementationClassName(clientInterface, "HttpClient")); - } catch (final ClassNotFoundException e) { - // try the older generated client suffix - return Class.forName(implementationClassName(clientInterface, "$HttpClient")); - } - } - - private String implementationClassName(Class clientInterface, String suffix) { - final String packageName = clientInterface.getPackageName(); - final String simpleName = clientInterface.getSimpleName(); - return packageName + ".httpclient." + simpleName + suffix; + return DHttpApi.get(clientInterface, this); } @Override diff --git a/http-client/src/main/java/io/avaje/http/client/DHttpClientRequest.java b/http-client/src/main/java/io/avaje/http/client/DHttpClientRequest.java index 95eea7dea..8a480ad93 100644 --- a/http-client/src/main/java/io/avaje/http/client/DHttpClientRequest.java +++ b/http-client/src/main/java/io/avaje/http/client/DHttpClientRequest.java @@ -600,15 +600,15 @@ protected CompletableFuture> performSendAsync( var resultFuture = context.sendAsync(httpRequest, responseHandler); if (errorMapper != null && !isRetry) { - resultFuture = - resultFuture.handle( - (r, e) -> { - if (e != null && e.getCause() instanceof HttpException) { - throw errorMapper.apply((HttpException) e.getCause()); - } - return r; - }); - } + resultFuture = + resultFuture.handle( + (r, e) -> { + if (e != null && e.getCause() instanceof HttpException) { + throw errorMapper.apply((HttpException) e.getCause()); + } + return r; + }); + } return resultFuture; } @@ -803,8 +803,7 @@ public HttpRequest request() { public String requestBody() { if (suppressLogging) { return ""; - } - if (encodedRequestBody != null) { + } else if (encodedRequestBody != null) { return new String(encodedRequestBody.content(), StandardCharsets.UTF_8); } else if (bodyFormEncoded) { return buildEncodedFormContent(); @@ -812,8 +811,9 @@ public String requestBody() { return rawRequestBody; } else if (body != null) { return body.toString(); + } else { + return null; } - return null; } @Override @@ -824,8 +824,8 @@ public String responseBody() { if (encodedResponseBody != null) { return context.maxResponseBody(new String(encodedResponseBody.content(), StandardCharsets.UTF_8)); } else if (httpResponse != null && loggableResponseBody) { - final Object body = httpResponse.body(); - return (body == null) ? null : context.maxResponseBody(body.toString()); + final var responseBody = httpResponse.body(); + return (responseBody == null) ? null : context.maxResponseBody(responseBody.toString()); } return null; } @@ -841,7 +841,6 @@ static final class HttpWrapperResponse implements HttpResponse { this.body = null; } - @SuppressWarnings({"raw"}) HttpWrapperResponse(B body, HttpResponse orig) { this.orig = orig; this.body = body; diff --git a/http-client/src/main/java/io/avaje/http/client/GzipUtil.java b/http-client/src/main/java/io/avaje/http/client/GzipUtil.java index 5ecced63a..5d22b1d0a 100644 --- a/http-client/src/main/java/io/avaje/http/client/GzipUtil.java +++ b/http-client/src/main/java/io/avaje/http/client/GzipUtil.java @@ -3,35 +3,33 @@ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; +import java.io.UncheckedIOException; import java.nio.charset.StandardCharsets; import java.util.zip.GZIPInputStream; import java.util.zip.GZIPOutputStream; final class GzipUtil { + private GzipUtil() {} static byte[] gzip(String content) { return gzip(content.getBytes(StandardCharsets.UTF_8)); } static byte[] gzip(byte[] content) { - try { - ByteArrayOutputStream obj = new ByteArrayOutputStream(); - try (GZIPOutputStream gzip = new GZIPOutputStream(obj)) { - gzip.write(content); - } - return obj.toByteArray(); + var baos = new ByteArrayOutputStream(); + try (GZIPOutputStream gzip = new GZIPOutputStream(baos)) { + gzip.write(content); } catch (IOException e) { - throw new RuntimeException("Error while gzip encoding content", e); + throw new UncheckedIOException("Error while gzip encoding content", e); } + return baos.toByteArray(); } static byte[] gzipDecode(byte[] content) { - try { - try (final GZIPInputStream unzip = new GZIPInputStream(new ByteArrayInputStream(content))) { - return unzip.readAllBytes(); - } + try (final var unzip = new GZIPInputStream(new ByteArrayInputStream(content))) { + return unzip.readAllBytes(); } catch (IOException e) { - throw new RuntimeException("Error while gzip decoding content", e); + throw new UncheckedIOException("Error while gzip decoding content", e); } } } diff --git a/http-client/src/main/java/io/avaje/http/client/JacksonBodyAdapter.java b/http-client/src/main/java/io/avaje/http/client/JacksonBodyAdapter.java index 30fe0fce4..269eec9e5 100644 --- a/http-client/src/main/java/io/avaje/http/client/JacksonBodyAdapter.java +++ b/http-client/src/main/java/io/avaje/http/client/JacksonBodyAdapter.java @@ -51,7 +51,7 @@ public JacksonBodyAdapter() { @SuppressWarnings("unchecked") @Override public BodyWriter beanWriter(Class cls) { - return (BodyWriter)beanWriterCache.computeIfAbsent(cls, aClass -> { + return (BodyWriter) beanWriterCache.computeIfAbsent(cls, aClass -> { try { return new JWriter<>(mapper.writerFor(cls)); } catch (Exception e) { diff --git a/http-client/src/test/java/io/avaje/http/client/DHttpClientContextTest.java b/http-client/src/test/java/io/avaje/http/client/DHttpClientContextTest.java index be19baa39..8fdea96cd 100644 --- a/http-client/src/test/java/io/avaje/http/client/DHttpClientContextTest.java +++ b/http-client/src/test/java/io/avaje/http/client/DHttpClientContextTest.java @@ -11,12 +11,6 @@ class DHttpClientContextTest { private final DHttpClientContext context = new DHttpClientContext(null, null, null, null, null, null, null, null, null); - @Test - void create() { - BasicClientInterface client = context.create(BasicClientInterface.class); - assertThat(client).isNotNull(); - } - @Test void gzip_gzipDecode() { diff --git a/http-client/src/test/java/org/example/github/GithubTest.java b/http-client/src/test/java/org/example/github/GithubTest.java index 180b4b01f..eca7a9aae 100644 --- a/http-client/src/test/java/org/example/github/GithubTest.java +++ b/http-client/src/test/java/org/example/github/GithubTest.java @@ -4,7 +4,7 @@ import io.avaje.http.client.HttpException; import io.avaje.http.client.JacksonBodyAdapter; import io.avaje.http.client.RetryHandler; - +import org.example.github.httpclient.Simple$HttpClient; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; @@ -29,7 +29,7 @@ void test() { .build(); // will not work under module classpath without registering the HttpApiProvider - final Simple simple = clientContext.create(Simple.class); + final Simple simple = new Simple$HttpClient(clientContext); final List repos = simple.listRepos("rbygrave", "junk"); assertThat(repos).isNotEmpty(); @@ -62,7 +62,7 @@ void testExceptionMapping() { .build(); // will not work under module classpath without registering the HttpApiProvider - final Simple simple = clientContext.create(Simple.class); + final Simple simple = new Simple$HttpClient(clientContext); assertThatThrownBy(() -> simple.listRepos("rbygrave", "junk")) .isInstanceOf(IllegalStateException.class); @@ -118,8 +118,8 @@ void testSyncRetry() { .requestLogging(false) .build(); - // will not work under module classpath without registering the HttpApiProvider - final Simple simple = clientContext.create(Simple.class); + + final Simple simple = new Simple$HttpClient(clientContext); assertThatThrownBy(() -> simple.listRepos("rbygrave", "junk")) .isInstanceOf(IllegalStateException.class); From b419d927e63819ad9c0f8bd1a49e5adc161db504 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Thu, 24 Aug 2023 21:02:17 -0400 Subject: [PATCH 0870/1323] fix test --- .../github/httpclient/GeneratedHttpComponent.java | 15 +++++++++++++++ tests/test-client/src/main/java/module-info.java | 2 ++ 2 files changed, 17 insertions(+) create mode 100644 tests/test-client/src/main/java/example/github/httpclient/GeneratedHttpComponent.java diff --git a/tests/test-client/src/main/java/example/github/httpclient/GeneratedHttpComponent.java b/tests/test-client/src/main/java/example/github/httpclient/GeneratedHttpComponent.java new file mode 100644 index 000000000..b7517518e --- /dev/null +++ b/tests/test-client/src/main/java/example/github/httpclient/GeneratedHttpComponent.java @@ -0,0 +1,15 @@ +package example.github.httpclient; + +import java.util.Map; + +import example.github.Simple; +import io.avaje.http.client.HttpApiProvider; +import io.avaje.http.client.HttpClient; + +public class GeneratedHttpComponent implements HttpClient.GeneratedComponent { + + @Override + public void register(Map, HttpApiProvider> providerMap) { + providerMap.put(Simple.class, Simple$HttpClient::new); + } +} diff --git a/tests/test-client/src/main/java/module-info.java b/tests/test-client/src/main/java/module-info.java index 807302394..f8165faa3 100644 --- a/tests/test-client/src/main/java/module-info.java +++ b/tests/test-client/src/main/java/module-info.java @@ -5,4 +5,6 @@ requires com.google.gson; exports example.github; + + provides io.avaje.http.client.HttpClient.GeneratedComponent with example.github.httpclient.GeneratedHttpComponent; } From db0e9750f7a01b37dd169246277dc983396a44dc Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sat, 26 Aug 2023 06:37:40 -0400 Subject: [PATCH 0871/1323] [http-client] Validate Module (#281) * validate module * Update ClientProcessor.java --- .../generator/client/ClientProcessor.java | 10 +++- .../generator/core/ProcessingContext.java | 59 +++++++++++++++++++ http-generator-helidon/pom.xml | 21 +++---- .../generator/helidon/nima/NimaProcessor.java | 2 + .../src/main/java/module-info.java | 1 + .../javax.annotation.processing.Processor | 1 - pom.xml | 2 +- 7 files changed, 78 insertions(+), 18 deletions(-) delete mode 100644 http-generator-helidon/src/main/resources/META-INF/services/javax.annotation.processing.Processor diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java index c74e44714..d2f681c98 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java @@ -6,6 +6,7 @@ import static io.avaje.http.generator.core.ProcessingContext.typeElement; import java.io.IOException; +import java.security.Identity; import java.util.Objects; import java.util.Set; @@ -49,7 +50,9 @@ public synchronized void init(ProcessingEnvironment processingEnv) { @Override public boolean process(Set annotations, RoundEnvironment round) { - final var platform = platform(); + + ProcessingContext.findModule(annotations, round); + final var platform = platform(); if (!(platform instanceof ClientPlatformAdapter)) { setPlatform(new ClientPlatformAdapter()); } @@ -90,7 +93,7 @@ private void writeClient(Element controller) { reader.read(false); try { metaData.add(writeClientAdapter(reader)); - } catch (final Throwable e) { + } catch (final Exception e) { e.printStackTrace(); logError(reader.beanType(), "Failed to write client class " + e); } @@ -103,6 +106,9 @@ protected String writeClientAdapter(ControllerReader reader) throws IOException private void initialiseComponent() { metaData.initialiseFullName(); + if (!metaData.all().isEmpty()) { + ProcessingContext.validateModule(metaData.fullName()); + } try { componentWriter.init(); } catch (final IOException e) { diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java index f6502a57f..88290dbbd 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java @@ -1,17 +1,24 @@ package io.avaje.http.generator.core; +import java.io.BufferedReader; import java.io.IOException; +import java.io.InputStreamReader; +import java.net.URI; +import java.util.Collection; import java.util.List; import java.util.Objects; import java.util.Optional; +import java.util.Set; import java.util.stream.Collectors; import java.util.stream.Stream; import javax.annotation.processing.Filer; import javax.annotation.processing.Messager; import javax.annotation.processing.ProcessingEnvironment; +import javax.annotation.processing.RoundEnvironment; import javax.lang.model.element.Element; import javax.lang.model.element.ExecutableElement; +import javax.lang.model.element.ModuleElement; import javax.lang.model.element.TypeElement; import javax.lang.model.type.DeclaredType; import javax.lang.model.type.TypeMirror; @@ -44,6 +51,8 @@ private static final class Ctx { private final String diAnnotation; private final boolean instrumentAllMethods; private final boolean disableDirectWrites; + private ModuleElement module; + private boolean validated; Ctx(ProcessingEnvironment env, PlatformAdapter adapter, boolean generateOpenAPI) { readAdapter = adapter; @@ -216,4 +225,54 @@ static Stream superTypes(Element element) { .flatMap(e -> Stream.concat(superTypes(e), Stream.of(e))) .map(Object::toString); } + + public static void findModule(Set annotations, RoundEnvironment roundEnv) { + + if (CTX.get().module == null) { + CTX.get().module = + annotations.stream() + .map(roundEnv::getElementsAnnotatedWith) + .flatMap(Collection::stream) + .findAny() + .map(ProcessingContext::getModuleElement) + .orElse(null); + } + } + + public static void validateModule(String fqn) { + var module = CTX.get().module; + if (module != null && !CTX.get().validated && !module.isUnnamed()) { + + CTX.get().validated = true; + try { + var resource = + CTX.get() + .filer + .getResource(StandardLocation.SOURCE_PATH, "", "module-info.java") + .toUri() + .toString(); + try (var inputStream = new URI(resource).toURL().openStream(); + var reader = new BufferedReader(new InputStreamReader(inputStream))) { + + var noProvides = reader.lines().noneMatch(s -> s.contains(fqn)); + + if (noProvides) { + logError( + module, + "Missing \"provides io.avaje.http.client.HttpClient.GeneratedComponent with %s;\"", + fqn); + } + } + } catch (Exception e) { + // can't read module + } + } + } + + static ModuleElement getModuleElement(Element e) { + if (e == null || e instanceof ModuleElement) { + return (ModuleElement) e; + } + return getModuleElement(e.getEnclosingElement()); + } } diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index e105b5ead..c274a26d1 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -23,20 +23,13 @@ avaje-http-generator-core ${project.version} + + + io.avaje + avaje-prisms + ${avaje.prisms.version} + provided + - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.10.1 - - 20 - -proc:none - - - - - diff --git a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/NimaProcessor.java b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/NimaProcessor.java index 7d3bd3ff4..e3825f25a 100644 --- a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/NimaProcessor.java +++ b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/NimaProcessor.java @@ -6,7 +6,9 @@ import io.avaje.http.generator.core.ControllerReader; import io.avaje.http.generator.core.PlatformAdapter; import io.avaje.http.generator.core.ProcessingContext; +import io.avaje.prism.AnnotationProcessor; +@AnnotationProcessor public class NimaProcessor extends BaseProcessor { @Override diff --git a/http-generator-helidon/src/main/java/module-info.java b/http-generator-helidon/src/main/java/module-info.java index 7ef1e46c5..4888e306a 100644 --- a/http-generator-helidon/src/main/java/module-info.java +++ b/http-generator-helidon/src/main/java/module-info.java @@ -7,4 +7,5 @@ // SHADED: All content after this line will be removed at package time requires transitive io.avaje.http.generator.core; + requires io.avaje.prism; } diff --git a/http-generator-helidon/src/main/resources/META-INF/services/javax.annotation.processing.Processor b/http-generator-helidon/src/main/resources/META-INF/services/javax.annotation.processing.Processor deleted file mode 100644 index 97697d264..000000000 --- a/http-generator-helidon/src/main/resources/META-INF/services/javax.annotation.processing.Processor +++ /dev/null @@ -1 +0,0 @@ -io.avaje.http.generator.helidon.nima.NimaProcessor diff --git a/pom.xml b/pom.xml index e4e819731..5795824d3 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ true 2.2.8 2.14.2 - 1.12 + 1.13 ${project.build.directory}${file.separator}module-info.shade From fcfc4b0704063e454a3cd1b4f062666178d7e803 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Sat, 26 Aug 2023 22:40:46 +1200 Subject: [PATCH 0872/1323] Format and tidy only --- .../avaje/http/generator/client/ClientProcessor.java | 10 ++++------ .../avaje/http/generator/core/ProcessingContext.java | 2 -- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java index d2f681c98..05b14fc04 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java @@ -6,7 +6,6 @@ import static io.avaje.http.generator.core.ProcessingContext.typeElement; import java.io.IOException; -import java.security.Identity; import java.util.Objects; import java.util.Set; @@ -50,15 +49,13 @@ public synchronized void init(ProcessingEnvironment processingEnv) { @Override public boolean process(Set annotations, RoundEnvironment round) { - - ProcessingContext.findModule(annotations, round); - final var platform = platform(); + ProcessingContext.findModule(annotations, round); + final var platform = platform(); if (!(platform instanceof ClientPlatformAdapter)) { setPlatform(new ClientPlatformAdapter()); } readModule(); - for (final Element controller : - round.getElementsAnnotatedWith(typeElement(ClientPrism.PRISM_TYPE))) { + for (final Element controller : round.getElementsAnnotatedWith(typeElement(ClientPrism.PRISM_TYPE))) { if (ClientPrism.getInstanceOn(controller).generate()) { writeClient(controller); } @@ -71,6 +68,7 @@ public boolean process(Set annotations, RoundEnvironment setPlatform(platform); return false; } + /** Read the existing metadata from the generated component (if exists). */ private void readModule() { if (readModuleInfo) { diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java index 88290dbbd..f654222fe 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java @@ -227,7 +227,6 @@ static Stream superTypes(Element element) { } public static void findModule(Set annotations, RoundEnvironment roundEnv) { - if (CTX.get().module == null) { CTX.get().module = annotations.stream() @@ -255,7 +254,6 @@ public static void validateModule(String fqn) { var reader = new BufferedReader(new InputStreamReader(inputStream))) { var noProvides = reader.lines().noneMatch(s -> s.contains(fqn)); - if (noProvides) { logError( module, From 6bd291a4130e227ef247362c8a29ae99cfab83da Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Sat, 26 Aug 2023 22:41:07 +1200 Subject: [PATCH 0873/1323] Version 2.0-RC6 --- http-api/pom.xml | 2 +- http-client-gson-adapter/pom.xml | 4 ++-- http-client/pom.xml | 2 +- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 2 +- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-inject-plugin/pom.xml | 2 +- pom.xml | 2 +- tests/pom.xml | 2 +- tests/test-client-generation/pom.xml | 2 +- tests/test-client/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- 18 files changed, 19 insertions(+), 19 deletions(-) diff --git a/http-api/pom.xml b/http-api/pom.xml index 92850dcc3..181811377 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC5 + 2.0-RC6 .. diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index 0dcde04fb..aaf61c7df 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC5 + 2.0-RC6 avaje-http-client-gson @@ -20,7 +20,7 @@ io.avaje avaje-http-client - 2.0-RC5 + 2.0-RC6 provided diff --git a/http-client/pom.xml b/http-client/pom.xml index ba2e004d6..588cc86fa 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC5 + 2.0-RC6 avaje-http-client diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index 8a6268368..d0d16916d 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC5 + 2.0-RC6 avaje-http-client-generator diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 0376f3899..b3e67b23f 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC5 + 2.0-RC6 avaje-http-generator-core diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index c274a26d1..a74710848 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.0-RC5 + 2.0-RC6 avaje-http-helidon-generator diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index acf350fb0..b91170f4c 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC5 + 2.0-RC6 avaje-http-javalin-generator diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index 8a45e389a..c40089a7d 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC5 + 2.0-RC6 avaje-http-jex-generator diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index 56aa9a287..3ae72c638 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC5 + 2.0-RC6 .. diff --git a/pom.xml b/pom.xml index 5795824d3..0110762e8 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-parent - 2.0-RC5 + 2.0-RC6 pom diff --git a/tests/pom.xml b/tests/pom.xml index 5c442d90e..56e0d1c67 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.0-RC5 + 2.0-RC6 tests diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index ac9e22546..a17e3bfcc 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.0-RC5 + 2.0-RC6 test-client-generation diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index 6f23d5e26..4adc0afde 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.0-RC5 + 2.0-RC6 test-client diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 101679324..0105b18e7 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 2.0-RC5 + 2.0-RC6 test-javalin-jsonb diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index e34869f0c..a1ff7beda 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.0-RC5 + 2.0-RC6 test-javalin diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 078c50b71..6a6ec44d3 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.0-RC5 + 2.0-RC6 test-jex diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 4dcad9f96..3af47fd73 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.0-RC5 + 2.0-RC6 test-nima-jsonb diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index 2f0990916..017a7d414 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.0-RC5 + 2.0-RC6 test-nima From bda3acc8f9bbfe62d2c9a0b5c55cfb4c310aa697 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sat, 26 Aug 2023 13:12:29 -0400 Subject: [PATCH 0874/1323] back ticks for module warning --- .../java/io/avaje/http/generator/core/ProcessingContext.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java index f654222fe..f05637d36 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java @@ -257,7 +257,7 @@ public static void validateModule(String fqn) { if (noProvides) { logError( module, - "Missing \"provides io.avaje.http.client.HttpClient.GeneratedComponent with %s;\"", + "Missing `provides io.avaje.http.client.HttpClient.GeneratedComponent with %s;`", fqn); } } From 88c30547850cc3175c79f0e5ef0dae43e978d32f Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sat, 26 Aug 2023 13:40:20 -0400 Subject: [PATCH 0875/1323] split javalin annotation to their own module --- http-api-javalin/LICENSE | 201 ++++++++++++++++++ http-api-javalin/pom.xml | 17 ++ .../java/io/avaje/http/api/javalin/After.java | 0 .../io/avaje/http/api/javalin/Before.java | 0 .../src/main/java/module-info.java | 3 + http-api/src/main/java/module-info.java | 1 - .../generator/core/ProcessingContext.java | 17 +- http-generator-javalin/pom.xml | 4 +- .../src/main/java/module-info.java | 2 +- pom.xml | 1 + 10 files changed, 240 insertions(+), 6 deletions(-) create mode 100644 http-api-javalin/LICENSE create mode 100644 http-api-javalin/pom.xml rename {http-api => http-api-javalin}/src/main/java/io/avaje/http/api/javalin/After.java (100%) rename {http-api => http-api-javalin}/src/main/java/io/avaje/http/api/javalin/Before.java (100%) create mode 100644 http-api-javalin/src/main/java/module-info.java diff --git a/http-api-javalin/LICENSE b/http-api-javalin/LICENSE new file mode 100644 index 000000000..261eeb9e9 --- /dev/null +++ b/http-api-javalin/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/http-api-javalin/pom.xml b/http-api-javalin/pom.xml new file mode 100644 index 000000000..742c9766f --- /dev/null +++ b/http-api-javalin/pom.xml @@ -0,0 +1,17 @@ + + + 4.0.0 + + io.avaje + avaje-http-parent + 2.0-RC5 + .. + + + avaje-http-api-javalin + + + scm:git:git@github.com:avaje/avaje-http.git + avaje-http-parent-1.19 + + diff --git a/http-api/src/main/java/io/avaje/http/api/javalin/After.java b/http-api-javalin/src/main/java/io/avaje/http/api/javalin/After.java similarity index 100% rename from http-api/src/main/java/io/avaje/http/api/javalin/After.java rename to http-api-javalin/src/main/java/io/avaje/http/api/javalin/After.java diff --git a/http-api/src/main/java/io/avaje/http/api/javalin/Before.java b/http-api-javalin/src/main/java/io/avaje/http/api/javalin/Before.java similarity index 100% rename from http-api/src/main/java/io/avaje/http/api/javalin/Before.java rename to http-api-javalin/src/main/java/io/avaje/http/api/javalin/Before.java diff --git a/http-api-javalin/src/main/java/module-info.java b/http-api-javalin/src/main/java/module-info.java new file mode 100644 index 000000000..18f709473 --- /dev/null +++ b/http-api-javalin/src/main/java/module-info.java @@ -0,0 +1,3 @@ +module io.avaje.http.api.javalin { + exports io.avaje.http.api.javalin; +} diff --git a/http-api/src/main/java/module-info.java b/http-api/src/main/java/module-info.java index 8ca65a240..5fe2e429f 100644 --- a/http-api/src/main/java/module-info.java +++ b/http-api/src/main/java/module-info.java @@ -1,7 +1,6 @@ module io.avaje.http.api { exports io.avaje.http.api; - exports io.avaje.http.api.javalin; exports io.avaje.http.api.context; exports io.avaje.http.api.spi; } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java index f05637d36..d811806c8 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java @@ -129,6 +129,10 @@ public static void logWarn(String msg, Object... args) { CTX.get().messager.printMessage(Diagnostic.Kind.WARNING, String.format(msg, args)); } + public static void logWarn(Element e, String msg, Object... args) { + CTX.get().messager.printMessage(Diagnostic.Kind.WARNING, String.format(msg, args), e); + } + public static void logDebug(String msg, Object... args) { CTX.get().messager.printMessage(Diagnostic.Kind.NOTE, String.format(msg, args)); } @@ -253,7 +257,18 @@ public static void validateModule(String fqn) { try (var inputStream = new URI(resource).toURL().openStream(); var reader = new BufferedReader(new InputStreamReader(inputStream))) { - var noProvides = reader.lines().noneMatch(s -> s.contains(fqn)); + var noProvides = + reader + .lines() + .map( + s -> { + if (s.contains("io.avaje.http.api.javalin") && !s.contains("static")) { + logWarn( + "io.avaje.http.api.javalin only contains SOURCE retention annotations. It should added as `requires static`"); + } + return s; + }) + .noneMatch(s -> s.contains(fqn)); if (noProvides) { logError( module, diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index b91170f4c..6251ff347 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -26,10 +26,8 @@ io.avaje - avaje-http-api + avaje-http-api-javalin ${project.version} - true - provided diff --git a/http-generator-javalin/src/main/java/module-info.java b/http-generator-javalin/src/main/java/module-info.java index f05cc4f15..a993efde0 100644 --- a/http-generator-javalin/src/main/java/module-info.java +++ b/http-generator-javalin/src/main/java/module-info.java @@ -7,6 +7,6 @@ // SHADED: All content after this line will be removed at package time requires io.avaje.http.generator.core; - requires io.avaje.http.api; + requires static io.avaje.http.api.javalin; requires static io.avaje.prism; } diff --git a/pom.xml b/pom.xml index 0110762e8..3dd3ee176 100644 --- a/pom.xml +++ b/pom.xml @@ -36,6 +36,7 @@ http-api + http-api-javalin http-client http-client-gson-adapter http-inject-plugin From 47d0070174c06f5ebc3fb968611969ca8b38b63e Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sat, 26 Aug 2023 13:43:22 -0400 Subject: [PATCH 0876/1323] Update pom.xml --- http-api-javalin/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/http-api-javalin/pom.xml b/http-api-javalin/pom.xml index 742c9766f..d9503c1a4 100644 --- a/http-api-javalin/pom.xml +++ b/http-api-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC5 + 2.0-RC6 .. From e1c9e0b1095784b15b09e4efb13fed35dd92fca1 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sat, 26 Aug 2023 16:57:22 -0400 Subject: [PATCH 0877/1323] single try --- .../generator/core/ProcessingContext.java | 55 +++++++++---------- 1 file changed, 27 insertions(+), 28 deletions(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java index d811806c8..57ce557c1 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java @@ -247,34 +247,33 @@ public static void validateModule(String fqn) { if (module != null && !CTX.get().validated && !module.isUnnamed()) { CTX.get().validated = true; - try { - var resource = - CTX.get() - .filer - .getResource(StandardLocation.SOURCE_PATH, "", "module-info.java") - .toUri() - .toString(); - try (var inputStream = new URI(resource).toURL().openStream(); - var reader = new BufferedReader(new InputStreamReader(inputStream))) { - - var noProvides = - reader - .lines() - .map( - s -> { - if (s.contains("io.avaje.http.api.javalin") && !s.contains("static")) { - logWarn( - "io.avaje.http.api.javalin only contains SOURCE retention annotations. It should added as `requires static`"); - } - return s; - }) - .noneMatch(s -> s.contains(fqn)); - if (noProvides) { - logError( - module, - "Missing `provides io.avaje.http.client.HttpClient.GeneratedComponent with %s;`", - fqn); - } + + try (var inputStream = + CTX.get() + .filer + .getResource(StandardLocation.SOURCE_PATH, "", "module-info.java") + .toUri() + .toURL() + .openStream(); + var reader = new BufferedReader(new InputStreamReader(inputStream))) { + + var noProvides = + reader + .lines() + .map( + s -> { + if (s.contains("io.avaje.http.api.javalin") && !s.contains("static")) { + logWarn( + "io.avaje.http.api.javalin only contains SOURCE retention annotations. It should added as `requires static`"); + } + return s; + }) + .noneMatch(s -> s.contains(fqn)); + if (noProvides) { + logError( + module, + "Missing `provides io.avaje.http.client.HttpClient.GeneratedComponent with %s;`", + fqn); } } catch (Exception e) { // can't read module From c802462b3ff1a32a391d17dc03b785fe4346a26b Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Fri, 8 Sep 2023 21:23:44 -0400 Subject: [PATCH 0878/1323] helidon M2 --- .github/workflows/build.yml | 2 +- README.md | 6 ++-- http-generator-helidon/pom.xml | 6 ++-- .../helidon/nima/ControllerMethodWriter.java | 2 +- .../helidon/nima/ControllerWriter.java | 24 +++++++-------- ...maProcessor.java => HelidonProcessor.java} | 2 +- .../helidon/nima/NimaPlatformAdapter.java | 6 ++-- .../src/main/java/module-info.java | 2 +- tests/pom.xml | 6 ++-- tests/test-nima-jsonb/pom.xml | 22 ++++++-------- .../java/org/example/ErrorController.java | 4 +-- .../java/org/example/HelloController.java | 8 ++--- .../src/main/java/org/example/Main.java | 7 ++--- .../main/java/org/example/TestController.java | 8 ++--- .../http/generator/NimaProcessorTest.java | 6 ++-- .../src/test/java/org/example/TestPair.java | 4 +-- tests/test-nima/pom.xml | 29 ++++++------------- .../src/main/java/org/example/Main.java | 25 +++++----------- 18 files changed, 72 insertions(+), 97 deletions(-) rename http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/{NimaProcessor.java => HelidonProcessor.java} (92%) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 79f2dfe63..dde1adbfc 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -10,7 +10,7 @@ jobs: strategy: fail-fast: false matrix: - java_version: [17, 20] + java_version: [17, 21-ea] os: [ubuntu-latest] steps: diff --git a/README.md b/README.md index 462194272..11d0a8698 100644 --- a/README.md +++ b/README.md @@ -76,9 +76,9 @@ public class WidgetController { ## DI Usage The annotation processor will generate controller adapters to register routes to Javalin/Helidon. The natural way to use the generated adapters is to get a DI library to find and wire them. This is what the examples below do; they use [Avaje-Inject](https://avaje.io/inject/) to do this. The AP will automatically detect the presence of avaje-inject and generate the class to use avaje-inject's `@Component` as the DI annotation. -There isn't a hard requirement to use Avaje for dependency injection. In the absence of avaje-inject, the generated class will use `@jakarta.inject.Singleton` or `@javax.inject.Singleton` depending on what's on the classpath. Any DI library that can find and wire the generated @Singleton beans can be used. You can even use Dagger2 or Guice to wire the controllers if you so desire. +There isn't a hard requirement to use Avaje for dependency injection. In the absence of avaje-inject, the generated class will use `@jakarta.inject.Singleton` or `@javax.inject.Singleton` depending on what's on the classpath. Any DI library that can find and wire the generated @Singleton beans can be used. You can even use Dagger2 or Guice to wire the controllers if you so desire. -To force the AP to generate with `@javax.inject.Singleton`(in the case where you have both jakarta and javax on the classpath), use the compiler arg `-AuseJavax=true` +To force the AP to generate with `@javax.inject.Singleton`(in the case where you have both jakarta and javax on the classpath), use the compiler arg `-AuseJavax=true` ```xml org.apache.maven.plugins @@ -111,7 +111,7 @@ get all the services and register them with the Helidon `HttpRouting`. List routes = BeanScope.builder().build().list(HttpFeature.class); final var builder = HttpRouting.builder(); -routes.forEach(builder::register); +routes.forEach(builder::addFeature); WebServer.builder() .addRouting(builder.build()) diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index a74710848..bc7b2a58d 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -10,9 +10,9 @@ avaje-http-helidon-generator - 20 - 20 - 20 + 21 + 21 + 21 UTF-8 diff --git a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java index c2372869a..9a33f1b14 100644 --- a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java +++ b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java @@ -263,7 +263,7 @@ private void writeContextReturn() { } final var produces = producesOp.map(MediaType::parse).orElse(MediaType.APPLICATION_JSON); - final var contentTypeString = " res.headers().contentType(HttpMediaType."; + final var contentTypeString = " res.headers().contentType(MediaTypes."; switch (produces) { case APPLICATION_JSON -> writer.append(contentTypeString).append("APPLICATION_JSON);").eol(); case TEXT_HTML -> writer.append(contentTypeString).append("TEXT_HTML);").eol(); diff --git a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java index b8fb2bbc6..cf6613417 100644 --- a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java +++ b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java @@ -22,7 +22,7 @@ class ControllerWriter extends BaseControllerWriter { private static final String AT_GENERATED = "@Generated(\"avaje-helidon-generator\")"; - private static final String IMPORT_HTTP_STATUS = "import static io.helidon.common.http.Http.Status.*;"; + private static final String IMPORT_HTTP_STATUS = "import static io.helidon.http.Http.Status.*;"; private final boolean useJsonB; private final Map jsonTypes; @@ -42,22 +42,22 @@ class ControllerWriter extends BaseControllerWriter { } else { this.jsonTypes = Map.of(); } - reader.addImportType("io.helidon.common.http.HttpMediaType"); + reader.addImportType("io.helidon.common.media.type.MediaTypes"); reader.addImportType("io.helidon.common.parameters.Parameters"); - reader.addImportType("io.helidon.nima.webserver.http.HttpRouting"); - reader.addImportType("io.helidon.nima.webserver.http.ServerRequest"); - reader.addImportType("io.helidon.nima.webserver.http.ServerResponse"); - reader.addImportType("io.helidon.nima.webserver.http.HttpFeature"); - reader.addImportType("io.helidon.common.http.Http.Header"); + reader.addImportType("io.helidon.webserver.http.HttpRouting"); + reader.addImportType("io.helidon.webserver.http.ServerRequest"); + reader.addImportType("io.helidon.webserver.http.ServerResponse"); + reader.addImportType("io.helidon.webserver.http.HttpFeature"); + reader.addImportType("io.helidon.http.Http.HeaderNames"); if (reader.isIncludeValidator()) { - reader.addImportType("io.helidon.common.http.Http"); + reader.addImportType("io.helidon.http.Http"); } if (reader.methods().stream() .map(MethodReader::webMethod) .anyMatch(w -> CoreWebMethod.FILTER == w)) { - reader.addImportType("io.helidon.nima.webserver.http.FilterChain"); - reader.addImportType("io.helidon.nima.webserver.http.RoutingRequest"); - reader.addImportType("io.helidon.nima.webserver.http.RoutingResponse"); + reader.addImportType("io.helidon.webserver.http.FilterChain"); + reader.addImportType("io.helidon.webserver.http.RoutingRequest"); + reader.addImportType("io.helidon.webserver.http.RoutingResponse"); } } @@ -118,7 +118,7 @@ private void writeClassStart() { } if (reader.isIncludeValidator()) { - writer.append(" private static final Http.HeaderName HEADER_ACCEPT_LANGUAGE = Header.create(\"Accept-Language\");").eol(); + writer.append(" private static final Http.HeaderName HEADER_ACCEPT_LANGUAGE = HeaderNames.create(\"Accept-Language\");").eol(); } writer.append(" private final %s %s;", controllerType, controllerName).eol(); diff --git a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/NimaProcessor.java b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/HelidonProcessor.java similarity index 92% rename from http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/NimaProcessor.java rename to http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/HelidonProcessor.java index e3825f25a..4f08321ae 100644 --- a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/NimaProcessor.java +++ b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/HelidonProcessor.java @@ -9,7 +9,7 @@ import io.avaje.prism.AnnotationProcessor; @AnnotationProcessor -public class NimaProcessor extends BaseProcessor { +public class HelidonProcessor extends BaseProcessor { @Override protected PlatformAdapter providePlatformAdapter() { diff --git a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/NimaPlatformAdapter.java b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/NimaPlatformAdapter.java index e88a11b59..c0262ae16 100644 --- a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/NimaPlatformAdapter.java +++ b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/NimaPlatformAdapter.java @@ -10,8 +10,8 @@ class NimaPlatformAdapter implements PlatformAdapter { - static final String NIMA_REQ = "io.helidon.nima.webserver.http.ServerRequest"; - static final String NIMA_RES = "io.helidon.nima.webserver.http.ServerResponse"; + static final String NIMA_REQ = "io.helidon.webserver.http.ServerRequest"; + static final String NIMA_RES = "io.helidon.webserver.http.ServerResponse"; static final String HELIDON_FORMPARAMS = "io.helidon.common.parameters.Parameters"; @Override @@ -74,7 +74,7 @@ public void writeReadParameter(Append writer, ParamType paramType, String paramN case FORMPARAM -> writer.append("formParams.first(\"%s\").orElse(null)", paramName); case HEADER -> writer.append( - "req.headers().value(Header.create(\"%s\")).orElse(null)", paramName); + "req.headers().value(HeaderNames.create(\"%s\")).orElse(null)", paramName); case COOKIE -> writer.append("req.headers().cookies().first(\"%s\").orElse(null)", paramName); diff --git a/http-generator-helidon/src/main/java/module-info.java b/http-generator-helidon/src/main/java/module-info.java index 4888e306a..2d5ba9c18 100644 --- a/http-generator-helidon/src/main/java/module-info.java +++ b/http-generator-helidon/src/main/java/module-info.java @@ -3,7 +3,7 @@ requires java.compiler; requires java.sql; - provides javax.annotation.processing.Processor with io.avaje.http.generator.helidon.nima.NimaProcessor; + provides javax.annotation.processing.Processor with io.avaje.http.generator.helidon.nima.HelidonProcessor; // SHADED: All content after this line will be removed at package time requires transitive io.avaje.http.generator.core; diff --git a/tests/pom.xml b/tests/pom.xml index 56e0d1c67..4337470e8 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -17,7 +17,7 @@ 2.14.1 2.5 9.0 - 4.0.0-M1 + 4.0.0-M2 @@ -30,9 +30,9 @@ - jdk19plus + jdk20plus - [19,20,21] + [20,21] test-nima diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 3af47fd73..82330bcda 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -12,9 +12,9 @@ test-nima-jsonb - 20 - 20 - 20 + 21 + 21 + 21 UTF-8 false @@ -34,7 +34,7 @@ io.avaje avaje-jsonb - 1.7-RC1 + 1.8-SNAPSHOT io.avaje @@ -42,13 +42,13 @@ 3.3 - io.helidon.nima.webserver - helidon-nima-webserver + io.helidon.webserver + helidon-webserver ${nima.version} - io.helidon.nima.http.media - helidon-nima-http-media-jsonb + io.helidon.http.media + helidon-http-media-jsonb ${nima.version} @@ -78,8 +78,7 @@ org.apache.maven.plugins maven-compiler-plugin - true - 20 + 21 io.avaje @@ -103,9 +102,6 @@ org.apache.maven.plugins maven-surefire-plugin 3.0.0 - - --enable-preview - io.repaint.maven diff --git a/tests/test-nima-jsonb/src/main/java/org/example/ErrorController.java b/tests/test-nima-jsonb/src/main/java/org/example/ErrorController.java index d37595038..58ac93c82 100644 --- a/tests/test-nima-jsonb/src/main/java/org/example/ErrorController.java +++ b/tests/test-nima-jsonb/src/main/java/org/example/ErrorController.java @@ -2,8 +2,8 @@ import io.avaje.http.api.Controller; import io.avaje.http.api.ExceptionHandler; -import io.helidon.nima.webserver.http.ServerRequest; -import io.helidon.nima.webserver.http.ServerResponse; +import io.helidon.webserver.http.ServerRequest; +import io.helidon.webserver.http.ServerResponse; import java.util.Map; diff --git a/tests/test-nima-jsonb/src/main/java/org/example/HelloController.java b/tests/test-nima-jsonb/src/main/java/org/example/HelloController.java index cdea59920..c9f7c495a 100644 --- a/tests/test-nima-jsonb/src/main/java/org/example/HelloController.java +++ b/tests/test-nima-jsonb/src/main/java/org/example/HelloController.java @@ -14,9 +14,9 @@ import io.avaje.http.api.Put; import io.avaje.http.api.QueryParam; import io.avaje.http.api.Valid; -import io.helidon.common.http.HttpMediaType; -import io.helidon.nima.webserver.http.ServerRequest; -import io.helidon.nima.webserver.http.ServerResponse; +import io.helidon.common.media.type.MediaTypes; +import io.helidon.webserver.http.ServerRequest; +import io.helidon.webserver.http.ServerResponse; @Controller public class HelloController { @@ -41,7 +41,7 @@ byte[] testBytes() { @Get("/helidon") void testHelidon(ServerRequest req, ServerResponse res) { - res.headers().contentType(HttpMediaType.TEXT_PLAIN); + res.headers().contentType(MediaTypes.TEXT_PLAIN); res.send("success path:" + req.path()); } diff --git a/tests/test-nima-jsonb/src/main/java/org/example/Main.java b/tests/test-nima-jsonb/src/main/java/org/example/Main.java index e6bf5b499..dd4bf8b14 100644 --- a/tests/test-nima-jsonb/src/main/java/org/example/Main.java +++ b/tests/test-nima-jsonb/src/main/java/org/example/Main.java @@ -4,10 +4,9 @@ import io.avaje.inject.BeanScope; import io.avaje.jsonb.Jsonb; -import io.helidon.nima.webserver.WebServer; -import io.helidon.nima.webserver.http.HttpFeature; -import io.helidon.nima.webserver.http.HttpRouting; -import io.helidon.nima.webserver.http.HttpService; +import io.helidon.webserver.WebServer; +import io.helidon.webserver.http.HttpFeature; +import io.helidon.webserver.http.HttpRouting; public class Main { diff --git a/tests/test-nima-jsonb/src/main/java/org/example/TestController.java b/tests/test-nima-jsonb/src/main/java/org/example/TestController.java index 3af02dbbb..2bc9d81be 100644 --- a/tests/test-nima-jsonb/src/main/java/org/example/TestController.java +++ b/tests/test-nima-jsonb/src/main/java/org/example/TestController.java @@ -1,10 +1,10 @@ package org.example; import io.avaje.http.api.*; -import io.helidon.nima.webserver.http.FilterChain; -import io.helidon.nima.webserver.http.RoutingResponse; -import io.helidon.nima.webserver.http.ServerRequest; -import io.helidon.nima.webserver.http.ServerResponse; +import io.helidon.webserver.http.FilterChain; +import io.helidon.webserver.http.RoutingResponse; +import io.helidon.webserver.http.ServerRequest; +import io.helidon.webserver.http.ServerResponse; import java.io.InputStream; import java.util.LinkedHashMap; diff --git a/tests/test-nima-jsonb/src/test/java/io/avaje/http/generator/NimaProcessorTest.java b/tests/test-nima-jsonb/src/test/java/io/avaje/http/generator/NimaProcessorTest.java index 1bb383465..963e3b91f 100644 --- a/tests/test-nima-jsonb/src/test/java/io/avaje/http/generator/NimaProcessorTest.java +++ b/tests/test-nima-jsonb/src/test/java/io/avaje/http/generator/NimaProcessorTest.java @@ -21,7 +21,7 @@ import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; -import io.avaje.http.generator.helidon.nima.NimaProcessor; +import io.avaje.http.generator.helidon.nima.HelidonProcessor; class NimaProcessorTest { @@ -46,7 +46,7 @@ void runAnnotationProcessor() throws Exception { final var task = compiler.getTask( new PrintWriter(System.out), null, null, List.of("--release=20", "-AdisableDirectWrites=true"), null, files); - task.setProcessors(List.of(new NimaProcessor())); + task.setProcessors(List.of(new HelidonProcessor())); assertThat(task.call()).isTrue(); } @@ -62,7 +62,7 @@ void runAnnotationProcessorWithJsonB() throws Exception { final var task = compiler.getTask( new PrintWriter(System.out), null, null, List.of("--release=19"), null, files); - task.setProcessors(List.of(new NimaProcessor())); + task.setProcessors(List.of(new HelidonProcessor())); assertThat(task.call()).isTrue(); } diff --git a/tests/test-nima-jsonb/src/test/java/org/example/TestPair.java b/tests/test-nima-jsonb/src/test/java/org/example/TestPair.java index a2d8bec07..958e0b384 100644 --- a/tests/test-nima-jsonb/src/test/java/org/example/TestPair.java +++ b/tests/test-nima-jsonb/src/test/java/org/example/TestPair.java @@ -4,8 +4,8 @@ import io.avaje.http.client.HttpClient; import io.avaje.http.hibernate.validator.BeanValidator; import io.avaje.jsonb.Jsonb; -import io.helidon.nima.webserver.WebServer; -import io.helidon.nima.webserver.http.HttpRouting; +import io.helidon.webserver.WebServer; +import io.helidon.webserver.http.HttpRouting; public class TestPair { diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index 017a7d414..0e0aa6367 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -12,8 +12,8 @@ test-nima - 20 - 20 + 21 + 21 UTF-8 @@ -30,26 +30,15 @@ ${project.version} - io.helidon.nima.webserver - helidon-nima-webserver + io.helidon.webserver + helidon-webserver ${nima.version} - io.helidon.nima.http.media - helidon-nima-http-media-jsonb + io.helidon.http.media + helidon-http-media-jsonb ${nima.version} - - - - - - - - - - - @@ -59,7 +48,7 @@ maven-compiler-plugin 3.10.1 - 20 + 21 io.avaje @@ -72,8 +61,8 @@ ${avaje-inject.version} - 19 - 19 + 21 + 21 diff --git a/tests/test-nima/src/main/java/org/example/Main.java b/tests/test-nima/src/main/java/org/example/Main.java index 31f39dd9b..74768baa8 100644 --- a/tests/test-nima/src/main/java/org/example/Main.java +++ b/tests/test-nima/src/main/java/org/example/Main.java @@ -3,29 +3,20 @@ import java.util.List; import io.avaje.inject.BeanScope; -import io.helidon.nima.webserver.WebServer; -import io.helidon.nima.webserver.http.HttpRouting; -import io.helidon.nima.webserver.http.HttpService; +import io.helidon.webserver.WebServer; +import io.helidon.webserver.http.HttpFeature; +import io.helidon.webserver.http.HttpRouting; public class Main { public static void main(String[] args) { - final var scope = BeanScope.builder().build(); - final List list = scope.list(HttpService.class); + List routes = BeanScope.builder().build().list(HttpFeature.class); final var builder = HttpRouting.builder(); - for (final HttpService httpService : list) { - httpService.routing(builder); - } - final var httpRouting = builder.build(); - - - WebServer.builder() - .addRouting(httpRouting) - //.routing(Main::routing) - .port(8081) - .build() - .start(); + + routes.forEach(builder::addFeature); + + WebServer.builder().addRouting(builder.build()).build().start(); System.out.println("started"); } From b431cd0d390ab21688d90ef4c94eb568d1331d39 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Fri, 8 Sep 2023 21:26:47 -0400 Subject: [PATCH 0879/1323] Update pom.xml --- http-generator-helidon/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index bc7b2a58d..038d2bf91 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -12,7 +12,7 @@ 21 21 - 21 + 21 UTF-8 From ae63805c7f1297191ca7ae05acacc9115ae73341 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sat, 9 Sep 2023 12:23:12 -0400 Subject: [PATCH 0880/1323] Update pom.xml --- tests/test-nima-jsonb/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 82330bcda..fc4d66b03 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -34,7 +34,7 @@ io.avaje avaje-jsonb - 1.8-SNAPSHOT + 1.8-RC1 io.avaje From 86f49caa739f60cc8655d3d295e46d08569d8a9e Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sat, 9 Sep 2023 12:36:17 -0400 Subject: [PATCH 0881/1323] jdk? --- tests/pom.xml | 4 ++-- tests/test-nima/pom.xml | 6 ++++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/tests/pom.xml b/tests/pom.xml index 4337470e8..afa7270d7 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -16,7 +16,7 @@ 3.24.1 2.14.1 2.5 - 9.0 + 9.5 4.0.0-M2 @@ -32,7 +32,7 @@ jdk20plus - [20,21] + 21 test-nima diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index 0e0aa6367..bcc31b801 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -39,6 +39,12 @@ helidon-http-media-jsonb ${nima.version} + + io.avaje + avaje-http-helidon-generator + ${project.version} + test + From f4501e635ae3930ca379f96636a3de4451f6a828 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Mon, 11 Sep 2023 21:28:55 +1200 Subject: [PATCH 0882/1323] Version 2.0-RC7 --- http-api-javalin/pom.xml | 2 +- http-api/pom.xml | 2 +- http-client-gson-adapter/pom.xml | 4 ++-- http-client/pom.xml | 2 +- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 2 +- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-inject-plugin/pom.xml | 2 +- pom.xml | 2 +- tests/pom.xml | 2 +- tests/test-client-generation/pom.xml | 2 +- tests/test-client/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- 19 files changed, 20 insertions(+), 20 deletions(-) diff --git a/http-api-javalin/pom.xml b/http-api-javalin/pom.xml index d9503c1a4..16aaae1bb 100644 --- a/http-api-javalin/pom.xml +++ b/http-api-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC6 + 2.0-RC7 .. diff --git a/http-api/pom.xml b/http-api/pom.xml index 181811377..ab0ba7010 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC6 + 2.0-RC7 .. diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index aaf61c7df..2b8446a4f 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC6 + 2.0-RC7 avaje-http-client-gson @@ -20,7 +20,7 @@ io.avaje avaje-http-client - 2.0-RC6 + 2.0-RC7 provided diff --git a/http-client/pom.xml b/http-client/pom.xml index 588cc86fa..eb0492b8f 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC6 + 2.0-RC7 avaje-http-client diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index d0d16916d..9c32a8bed 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC6 + 2.0-RC7 avaje-http-client-generator diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index b3e67b23f..49d6744bd 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC6 + 2.0-RC7 avaje-http-generator-core diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index 038d2bf91..f21f9bbda 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.0-RC6 + 2.0-RC7 avaje-http-helidon-generator diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index 6251ff347..94c46ac65 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC6 + 2.0-RC7 avaje-http-javalin-generator diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index c40089a7d..7509babd2 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC6 + 2.0-RC7 avaje-http-jex-generator diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index 3ae72c638..5f3ed7e73 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC6 + 2.0-RC7 .. diff --git a/pom.xml b/pom.xml index 3dd3ee176..4642aec92 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-parent - 2.0-RC6 + 2.0-RC7 pom diff --git a/tests/pom.xml b/tests/pom.xml index afa7270d7..68bda2969 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.0-RC6 + 2.0-RC7 tests diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index a17e3bfcc..ff7959251 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.0-RC6 + 2.0-RC7 test-client-generation diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index 4adc0afde..9ccb47245 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.0-RC6 + 2.0-RC7 test-client diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 0105b18e7..ffb0a6f29 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 2.0-RC6 + 2.0-RC7 test-javalin-jsonb diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index a1ff7beda..35e13160e 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.0-RC6 + 2.0-RC7 test-javalin diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 6a6ec44d3..06014230e 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.0-RC6 + 2.0-RC7 test-jex diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index fc4d66b03..e20b842f6 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.0-RC6 + 2.0-RC7 test-nima-jsonb diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index bcc31b801..278611dc6 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.0-RC6 + 2.0-RC7 test-nima From b974244a591e11a64cfe8d98ecaa2ba7cae4a9de Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Mon, 11 Sep 2023 19:30:01 -0400 Subject: [PATCH 0883/1323] notNullPrism --- .../http/generator/core/NotNullPrism.java | 201 ++++++++++++++++++ .../http/generator/core/package-info.java | 1 - .../org/jetbrains/annotations/NotNull.java | 14 -- 3 files changed, 201 insertions(+), 15 deletions(-) create mode 100644 http-generator-core/src/main/java/io/avaje/http/generator/core/NotNullPrism.java delete mode 100644 http-generator-core/src/main/java/org/jetbrains/annotations/NotNull.java diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/NotNullPrism.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/NotNullPrism.java new file mode 100644 index 000000000..8cd71667d --- /dev/null +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/NotNullPrism.java @@ -0,0 +1,201 @@ +package io.avaje.http.generator.core; + +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; + +import javax.annotation.processing.Generated; +import javax.lang.model.element.AnnotationMirror; +import javax.lang.model.element.AnnotationValue; +import javax.lang.model.element.Element; +import javax.lang.model.element.ExecutableElement; +import javax.lang.model.element.TypeElement; +import javax.lang.model.util.ElementFilter; + +/** A Prism representing a {@link org.jetbrains.annotations.NotNull @NotNull} annotation. */ +@Generated("avaje-prism-generator") +public final class NotNullPrism { + /** store prism value of value */ + private final String _value; + + public static final String PRISM_TYPE = "org.jetbrains.annotations.NotNull"; + + /** + * An instance of the Values inner class whose methods return the AnnotationValues used to build + * this prism. Primarily intended to support using Messager. + */ + public final Values values; + + /** + * Returns true if the mirror is an instance of {@link org.jetbrains.annotations.NotNull @NotNull} + * is present on the element, else false. + * + * @param mirror mirror. + * @return true if prism is present. + */ + public static boolean isInstance(AnnotationMirror mirror) { + return getInstance(mirror) != null; + } + + /** + * Returns true if {@link org.jetbrains.annotations.NotNull @NotNull} is present on the element, + * else false. + * + * @param element element. + * @return true if annotation is present on the element. + */ + public static boolean isPresent(Element element) { + return getInstanceOn(element) != null; + } + + /** + * Return a prism representing the {@link org.jetbrains.annotations.NotNull @NotNull} annotation + * present on the given element. similar to {@code element.getAnnotation(NotNull.class)} except + * that an instance of this class rather than an instance of {@link + * org.jetbrains.annotations.NotNull @NotNull} is returned. + * + * @param element element. + * @return prism on element or null if no annotation is found. + */ + public static NotNullPrism getInstanceOn(Element element) { + final var mirror = getMirror(element); + if (mirror == null) return null; + return getInstance(mirror); + } + + /** + * Return a Optional representing a nullable {@link org.jetbrains.annotations.NotNull @NotNull} + * annotation on the given element. similar to {@link + * element.getAnnotation(org.jetbrains.annotations.NotNull.class)} except that an Optional of this + * class rather than an instance of {@link org.jetbrains.annotations.NotNull} is returned. + * + * @param element element. + * @return prism optional for element. + */ + public static Optional getOptionalOn(Element element) { + final var mirror = getMirror(element); + if (mirror == null) return Optional.empty(); + return getOptional(mirror); + } + + /** + * Return a prism of the {@link org.jetbrains.annotations.NotNull @NotNull} annotation from an + * annotation mirror. + * + * @param mirror mirror. + * @return prism for mirror or null if mirror is an incorrect type. + */ + public static NotNullPrism getInstance(AnnotationMirror mirror) { + if (mirror == null || !PRISM_TYPE.equals(mirror.getAnnotationType().toString())) return null; + + return new NotNullPrism(mirror); + } + + /** + * Return an Optional representing a nullable {@link NotNullPrism @NotNullPrism} from an + * annotation mirror. similar to {@link e.getAnnotation(org.jetbrains.annotations.NotNull.class)} + * except that an Optional of this class rather than an instance of {@link + * org.jetbrains.annotations.NotNull @NotNull} is returned. + * + * @param mirror mirror. + * @return prism optional for mirror. + */ + public static Optional getOptional(AnnotationMirror mirror) { + if (mirror == null || !PRISM_TYPE.equals(mirror.getAnnotationType().toString())) + return Optional.empty(); + + return Optional.of(new NotNullPrism(mirror)); + } + + private NotNullPrism(AnnotationMirror mirror) { + for (final ExecutableElement key : mirror.getElementValues().keySet()) { + memberValues.put(key.getSimpleName().toString(), mirror.getElementValues().get(key)); + } + for (final ExecutableElement member : + ElementFilter.methodsIn(mirror.getAnnotationType().asElement().getEnclosedElements())) { + defaults.put(member.getSimpleName().toString(), member.getDefaultValue()); + } + _value = getValue("value", String.class); + this.values = new Values(memberValues); + this.mirror = mirror; + this.isValid = valid; + } + + /** + * Returns a String representing the value of the {@code java.lang.String public abstract + * java.lang.String value() } member of the Annotation. + * + * @see org.jetbrains.annotations.NotNull#value() + */ + public String value() { + return _value; + } + + /** + * Determine whether the underlying AnnotationMirror has no errors. True if the underlying + * AnnotationMirror has no errors. When true is returned, none of the methods will return null. + * When false is returned, a least one member will either return null, or another prism that is + * not valid. + */ + public final boolean isValid; + + /** + * The underlying AnnotationMirror of the annotation represented by this Prism. Primarily intended + * to support using Messager. + */ + public final AnnotationMirror mirror; + /** + * A class whose members corespond to those of {@link org.jetbrains.annotations.NotNull @NotNull} + * but which each return the AnnotationValue corresponding to that member in the model of the + * annotations. Returns null for defaulted members. Used for Messager, so default values are not + * useful. + */ + public static final class Values { + private final Map values; + + private Values(Map values) { + this.values = values; + } + /** + * Return the AnnotationValue corresponding to the value() member of the annotation, or null + * when the default value is implied. + */ + public AnnotationValue value() { + return values.get("value"); + } + } + + private final Map defaults = new HashMap<>(10); + private final Map memberValues = + new HashMap<>(10); + private boolean valid = true; + + private T getValue(String name, Class clazz) { + final T result = NotNullPrism.getValue(memberValues, defaults, name, clazz); + if (result == null) valid = false; + return result; + } + + private static AnnotationMirror getMirror(Element target) { + for (final var m : target.getAnnotationMirrors()) { + final CharSequence mfqn = + ((TypeElement) m.getAnnotationType().asElement()).getQualifiedName(); + if (PRISM_TYPE.contentEquals(mfqn)) return m; + } + return null; + } + + private static T getValue( + Map memberValues, + Map defaults, + String name, + Class clazz) { + AnnotationValue av = memberValues.get(name); + if (av == null) av = defaults.get(name); + if (av == null) { + return null; + } + if (clazz.isInstance(av.getValue())) return clazz.cast(av.getValue()); + return null; + } +} diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/package-info.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/package-info.java index 534aad879..4149cab07 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/package-info.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/package-info.java @@ -32,7 +32,6 @@ @GeneratePrism(value = io.avaje.http.api.OpenAPIResponse.class, publicAccess = true) @GeneratePrism(value = io.avaje.http.api.OpenAPIResponses.class, publicAccess = true) @GeneratePrism(value = io.swagger.v3.oas.annotations.Hidden.class, publicAccess = true) -@GeneratePrism(value = org.jetbrains.annotations.NotNull.class, publicAccess = true) @GeneratePrism(value = io.avaje.http.api.Client.class, publicAccess = true) @GeneratePrism(value = io.avaje.http.api.Client.Import.class, publicAccess = true) @GeneratePrism(value = io.avaje.http.api.RequestTimeout.class, publicAccess = true) diff --git a/http-generator-core/src/main/java/org/jetbrains/annotations/NotNull.java b/http-generator-core/src/main/java/org/jetbrains/annotations/NotNull.java deleted file mode 100644 index 60e69f10e..000000000 --- a/http-generator-core/src/main/java/org/jetbrains/annotations/NotNull.java +++ /dev/null @@ -1,14 +0,0 @@ -package org.jetbrains.annotations; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -@Documented -@Retention(RetentionPolicy.CLASS) -@Target({ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER, ElementType.LOCAL_VARIABLE}) -public @interface NotNull { - String value() default ""; -} From aa0b638f87b7aa27899b526e4af6d5fffc29e55c Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Tue, 12 Sep 2023 08:41:41 -0400 Subject: [PATCH 0884/1323] add bigInteger --- .../java/io/avaje/http/api/PathTypeConversion.java | 13 +++++++++++++ .../java/io/avaje/http/generator/core/TypeMap.java | 7 +++++++ 2 files changed, 20 insertions(+) diff --git a/http-api/src/main/java/io/avaje/http/api/PathTypeConversion.java b/http-api/src/main/java/io/avaje/http/api/PathTypeConversion.java index 49fb16192..eff727720 100644 --- a/http-api/src/main/java/io/avaje/http/api/PathTypeConversion.java +++ b/http-api/src/main/java/io/avaje/http/api/PathTypeConversion.java @@ -2,6 +2,7 @@ import java.math.BigDecimal; import java.time.*; +import java.math.BigInteger; import java.util.List; import java.util.Set; import java.util.UUID; @@ -131,6 +132,18 @@ public static boolean asBool(String value) { return asBoolean(value); } + /** + * Convert to BigInteger (not nullable). + */ + public static BigInteger asBigInteger(String value) { + checkNull(value); + try { + return new BigInteger(value); + } catch (RuntimeException e) { + throw new InvalidPathArgumentException(e); + } + } + /** * Convert to BigDecimal (not nullable). */ diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/TypeMap.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/TypeMap.java index c092c37fa..35fa5a6cb 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/TypeMap.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/TypeMap.java @@ -34,6 +34,7 @@ private static void add(TypeHandler h) { add(new UuidHandler()); add(new BigDecimalHandler()); + add(new BigDecimalHandler()); add(new LocalDateHandler()); add(new LocalTimeHandler()); add(new LocalDateTimeHandler()); @@ -269,6 +270,12 @@ static class BigDecimalHandler extends ObjectHandler { } } + static class BigIntegerHandler extends ObjectHandler { + BigIntegerHandler() { + super("java.math.BigInteger", "BigInteger"); + } + } + static class LocalDateHandler extends ObjectHandler { LocalDateHandler() { super("java.time.LocalDate", "LocalDate"); From c556c7bd71d1db2891bf25b548ad4338182ff3b0 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Tue, 12 Sep 2023 19:35:24 -0400 Subject: [PATCH 0885/1323] Update README.md --- README.md | 57 +++++++++++++++++++++++++++++-------------------------- 1 file changed, 30 insertions(+), 27 deletions(-) diff --git a/README.md b/README.md index 11d0a8698..ebacbb423 100644 --- a/README.md +++ b/README.md @@ -74,7 +74,7 @@ public class WidgetController { } ``` ## DI Usage -The annotation processor will generate controller adapters to register routes to Javalin/Helidon. The natural way to use the generated adapters is to get a DI library to find and wire them. This is what the examples below do; they use [Avaje-Inject](https://avaje.io/inject/) to do this. The AP will automatically detect the presence of avaje-inject and generate the class to use avaje-inject's `@Component` as the DI annotation. +The annotation processor will generate controller adapters to register routes to Javalin/Helidon. The natural way to use the generated adapters is to get a DI library to find and wire them. The AP will automatically detect the presence of avaje-inject and generate the class to use avaje-inject's `@Component` as the DI annotation. There isn't a hard requirement to use Avaje for dependency injection. In the absence of avaje-inject, the generated class will use `@jakarta.inject.Singleton` or `@javax.inject.Singleton` depending on what's on the classpath. Any DI library that can find and wire the generated @Singleton beans can be used. You can even use Dagger2 or Guice to wire the controllers if you so desire. @@ -93,22 +93,20 @@ To force the AP to generate with `@javax.inject.Singleton`(in the case where you ### Usage with Javalin -The annotation processor will generate controller classes implementing the Javalin `Plugin` interface, which means we can -get all the WebRoutes and register them with Javalin using: +The annotation processor will generate controller classes implementing the Javalin `Plugin` interface, which means we can register them with Javalin using: ```java -List routes = BeanScope.builder().build().list(Plugin.class); +List routes = ...; //retrieve using a DI framework Javalin.create(cfg -> routes.forEach(cfg.plugins::register)).start(); ``` -### Usage with Helidon Nima +### Usage with Helidon SE (4.x) -The annotation processor will generate controller classes implementing the Helidon HttpService interface, which we can use -get all the services and register them with the Helidon `HttpRouting`. +The annotation processor will generate controller classes implementing the Helidon HttpFeature interface, which we can register with the Helidon `HttpRouting`. ```java -List routes = BeanScope.builder().build().list(HttpFeature.class); +List routes = ... //retrieve using a DI framework final var builder = HttpRouting.builder(); routes.forEach(builder::addFeature); @@ -153,14 +151,15 @@ public class WidgetController$Route implements Plugin { } ``` -### (Helidon Nima) The generated WidgetController$Route.java is: +### (Helidon SE) The generated WidgetController$Route.java is: ```java -@Generated("avaje-helidon-nima-generator") -@Singleton +@Generated("avaje-helidon-generator") +@Component public class WidgetController$Route implements HttpFeature { private final WidgetController controller; + public WidgetController$Route(WidgetController controller) { this.controller = controller; } @@ -172,17 +171,19 @@ public class WidgetController$Route implements HttpFeature { } private void _getById(ServerRequest req, ServerResponse res) throws Exception { + res.status(OK_200); var pathParams = req.path().pathParameters(); - int id = asInt(pathParams.first("id").get()); + var id = asInt(pathParams.first("id").get()); var result = controller.getById(id); res.send(result); } - private void _getAll(ServerRequest req, ServerResponse res) { - var pathParams = req.path().pathParameters(); + private void _getAll(ServerRequest req, ServerResponse res) throws Exception { + res.status(OK_200); var result = controller.getAll(); res.send(result); } + } ``` @@ -225,21 +226,21 @@ public class WidgetController$Route implements Plugin { } ``` -### (Helidon Nima) The generated WidgetController$Route.java is: +### (Helidon SE) The generated WidgetController$Route.java is: ```java -@Generated("avaje-helidon-nima-generator") +@Generated("avaje-helidon-generator") @Component public class WidgetController$Route implements HttpFeature { private final WidgetController controller; - private final JsonType widgetJsonType; - private final JsonType> listWidgetJsonType; + private final JsonType widgetController$WidgetJsonType; + private final JsonType> listWidgetController$WidgetJsonType; - public WidgetController$Route(WidgetController controller, Jsonb jsonB) { + public WidgetController$Route(WidgetController controller, Jsonb jsonb) { this.controller = controller; - this.widgetJsonType = jsonB.type(Widget.class); - this.listWidgetJsonType = jsonB.type(Widget.class).list(); + this.widgetController$WidgetJsonType = jsonb.type(WidgetController.Widget.class); + this.listWidgetController$WidgetJsonType = jsonb.type(WidgetController.Widget.class).list(); } @Override @@ -249,18 +250,20 @@ public class WidgetController$Route implements HttpFeature { } private void _getById(ServerRequest req, ServerResponse res) throws Exception { + res.status(OK_200); var pathParams = req.path().pathParameters(); - int id = asInt(pathParams.first("id").get()); + var id = asInt(pathParams.first("id").get()); var result = controller.getById(id); - res.headers().contentType(HttpMediaType.APPLICATION_JSON); - widgetJsonType.toJson(result, JsonOutput.of(res)); + res.headers().contentType(MediaTypes.APPLICATION_JSON); + widgetController$WidgetJsonType.toJson(result, JsonOutput.of(res)); } private void _getAll(ServerRequest req, ServerResponse res) throws Exception { - var pathParams = req.path().pathParameters(); + res.status(OK_200); var result = controller.getAll(); - res.headers().contentType(HttpMediaType.APPLICATION_JSON); - listWidgetJsonType.toJson(result, JsonOutput.of(res)); + res.headers().contentType(MediaTypes.APPLICATION_JSON); + listWidgetController$WidgetJsonType.toJson(result, JsonOutput.of(res)); } + } ``` From 0896582a386325a0bd441e795b924d8a0d122421 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Tue, 12 Sep 2023 19:35:49 -0400 Subject: [PATCH 0886/1323] move status writing higher up --- .../generator/helidon/nima/ControllerMethodWriter.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java index 9a33f1b14..e6f9c13df 100644 --- a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java +++ b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java @@ -103,7 +103,12 @@ void writeHandler(boolean requestScoped) { writer.append(" private void _%s(FilterChain chain, RoutingRequest req, RoutingResponse res) {", method.simpleName()).eol(); } else { writer.append(" private void _%s(ServerRequest req, ServerResponse res) throws Exception {", method.simpleName()).eol(); + int statusCode = method.statusCode(); + if (statusCode > 0) { + writer.append(" res.status(%s);", lookupStatusCode(statusCode)).eol(); + } } + final var bodyType = method.bodyType(); if (bodyType != null && !method.isErrorMethod() && !isFilter) { if ("InputStream".equals(bodyType)) { @@ -253,10 +258,6 @@ private boolean usesFormParams() { } private void writeContextReturn() { - int statusCode = method.statusCode(); - if (statusCode > 0) { - writer.append(" res.status(%s);", lookupStatusCode(statusCode)).eol(); - } final var producesOp = Optional.ofNullable(method.produces()); if (producesOp.isEmpty() && !useJsonB) { return; From 223afb4cba1a0d5a1ccb414880df55253e971b44 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Tue, 12 Sep 2023 19:40:37 -0400 Subject: [PATCH 0887/1323] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ebacbb423..21fbdde48 100644 --- a/README.md +++ b/README.md @@ -76,7 +76,7 @@ public class WidgetController { ## DI Usage The annotation processor will generate controller adapters to register routes to Javalin/Helidon. The natural way to use the generated adapters is to get a DI library to find and wire them. The AP will automatically detect the presence of avaje-inject and generate the class to use avaje-inject's `@Component` as the DI annotation. -There isn't a hard requirement to use Avaje for dependency injection. In the absence of avaje-inject, the generated class will use `@jakarta.inject.Singleton` or `@javax.inject.Singleton` depending on what's on the classpath. Any DI library that can find and wire the generated @Singleton beans can be used. You can even use Dagger2 or Guice to wire the controllers if you so desire. +There isn't a hard requirement to use [Avaje](https://avaje.io/inject/) for dependency injection. In the absence of avaje-inject, the generated class will use `@jakarta.inject.Singleton` or `@javax.inject.Singleton` depending on what's on the classpath. Any DI library that can find and wire the generated @Singleton beans can be used. You can even use Dagger2 or Guice to wire the controllers if you so desire. To force the AP to generate with `@javax.inject.Singleton`(in the case where you have both jakarta and javax on the classpath), use the compiler arg `-AuseJavax=true` ```xml From b60cac98b0639013a96009473d72dce42cf31770 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Tue, 12 Sep 2023 19:54:40 -0400 Subject: [PATCH 0888/1323] Update ControllerMethodWriter.java --- .../http/generator/helidon/nima/ControllerMethodWriter.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java index e6f9c13df..1d71a7491 100644 --- a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java +++ b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java @@ -103,6 +103,9 @@ void writeHandler(boolean requestScoped) { writer.append(" private void _%s(FilterChain chain, RoutingRequest req, RoutingResponse res) {", method.simpleName()).eol(); } else { writer.append(" private void _%s(ServerRequest req, ServerResponse res) throws Exception {", method.simpleName()).eol(); + } + + if (!isFilter) { int statusCode = method.statusCode(); if (statusCode > 0) { writer.append(" res.status(%s);", lookupStatusCode(statusCode)).eol(); From 5b0c0a0580f13063929338037ba4a750bf4a7c79 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Tue, 12 Sep 2023 21:42:32 -0400 Subject: [PATCH 0889/1323] Update PathTypeConversion.java --- .../java/io/avaje/http/api/PathTypeConversion.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/http-api/src/main/java/io/avaje/http/api/PathTypeConversion.java b/http-api/src/main/java/io/avaje/http/api/PathTypeConversion.java index eff727720..1cd272f20 100644 --- a/http-api/src/main/java/io/avaje/http/api/PathTypeConversion.java +++ b/http-api/src/main/java/io/avaje/http/api/PathTypeConversion.java @@ -309,6 +309,20 @@ public static BigDecimal toBigDecimal(String value) { } } + /** + * Convert to BigInteger (allowing nulls). + */ + public static BigInteger toBigInteger(String value) { + if (isNullOrEmpty(value)) { + return null; + } + try { + return new BigInteger(value); + } catch (Exception e) { + throw new InvalidTypeArgumentException(e); + } + } + /** * Convert to Boolean (allowing nulls). */ From 597bc6efecf064695d65bc64377357b851cecc07 Mon Sep 17 00:00:00 2001 From: "robin.bygrave" Date: Wed, 13 Sep 2023 17:07:02 +1200 Subject: [PATCH 0890/1323] #285 BigInteger support for path parameter --- .../io/avaje/http/generator/core/TypeMap.java | 2 +- .../http/generator/core/TypeMapTest.java | 16 ++++++++++ .../src/main/resources/public/openapi.json | 2 +- .../java/org/example/web/HelloController.java | 7 +++++ .../src/main/resources/public/openapi.json | 31 +++++++++++++++++++ .../java/org/example/HelloController.java | 5 +++ 6 files changed, 61 insertions(+), 2 deletions(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/TypeMap.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/TypeMap.java index 35fa5a6cb..c81938cf8 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/TypeMap.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/TypeMap.java @@ -34,7 +34,7 @@ private static void add(TypeHandler h) { add(new UuidHandler()); add(new BigDecimalHandler()); - add(new BigDecimalHandler()); + add(new BigIntegerHandler()); add(new LocalDateHandler()); add(new LocalTimeHandler()); add(new LocalDateTimeHandler()); diff --git a/http-generator-core/src/test/java/io/avaje/http/generator/core/TypeMapTest.java b/http-generator-core/src/test/java/io/avaje/http/generator/core/TypeMapTest.java index 5f4b9ac7c..ead716fd3 100644 --- a/http-generator-core/src/test/java/io/avaje/http/generator/core/TypeMapTest.java +++ b/http-generator-core/src/test/java/io/avaje/http/generator/core/TypeMapTest.java @@ -53,4 +53,20 @@ void get_Float() { assertThat(handler.asMethod()).isEqualTo("asFloat("); assertFalse(handler.isPrimitive()); } + + @Test + void get_BigDecimal() { + TypeHandler handler = TypeMap.get("java.math.BigDecimal"); + assertThat(handler).isInstanceOf(TypeMap.BigDecimalHandler.class); + assertThat(handler.asMethod()).isEqualTo("asBigDecimal("); + assertFalse(handler.isPrimitive()); + } + + @Test + void get_BigInt() { + TypeHandler handler = TypeMap.get("java.math.BigInteger"); + assertThat(handler).isInstanceOf(TypeMap.BigIntegerHandler.class); + assertThat(handler.asMethod()).isEqualTo("asBigInteger("); + assertFalse(handler.isPrimitive()); + } } diff --git a/tests/test-javalin-jsonb/src/main/resources/public/openapi.json b/tests/test-javalin-jsonb/src/main/resources/public/openapi.json index 9fc694f3f..26783f108 100644 --- a/tests/test-javalin-jsonb/src/main/resources/public/openapi.json +++ b/tests/test-javalin-jsonb/src/main/resources/public/openapi.json @@ -1,7 +1,7 @@ { "openapi" : "3.0.1", "info" : { - "title" : "Example service showing off the Path extension method of controller", + "title" : "Example service", "description" : "Example Javalin controllers with Java and Maven", "version" : "" }, diff --git a/tests/test-jex/src/main/java/org/example/web/HelloController.java b/tests/test-jex/src/main/java/org/example/web/HelloController.java index a630fa209..9745b9e32 100644 --- a/tests/test-jex/src/main/java/org/example/web/HelloController.java +++ b/tests/test-jex/src/main/java/org/example/web/HelloController.java @@ -9,6 +9,8 @@ import io.avaje.http.api.Valid; import io.avaje.jex.Context; +import java.math.BigInteger; + // @Roles(AppRoles.BASIC_USER) @Controller @Path("/") @@ -58,4 +60,9 @@ String splat2(String name, String nam0, String nam1) { void put(HelloDto dto) { dto.hashCode(); } + + @Get("/bigInt/{val}") + String testBigInt(BigInteger val) { + return "hi|" + val; + } } diff --git a/tests/test-jex/src/main/resources/public/openapi.json b/tests/test-jex/src/main/resources/public/openapi.json index 0a2817d9f..00da28583 100644 --- a/tests/test-jex/src/main/resources/public/openapi.json +++ b/tests/test-jex/src/main/resources/public/openapi.json @@ -48,6 +48,37 @@ } } }, + "/bigInt/{val}" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "parameters" : [ + { + "name" : "val", + "in" : "path", + "required" : true, + "schema" : { + "type" : "number" + } + } + ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, "/other/{name}" : { "get" : { "tags" : [ diff --git a/tests/test-nima-jsonb/src/main/java/org/example/HelloController.java b/tests/test-nima-jsonb/src/main/java/org/example/HelloController.java index c9f7c495a..95d7ea403 100644 --- a/tests/test-nima-jsonb/src/main/java/org/example/HelloController.java +++ b/tests/test-nima-jsonb/src/main/java/org/example/HelloController.java @@ -148,4 +148,9 @@ String form(String name, String email, String url) { String formBean(MyForm form) { return form.name + "|" + form.email + "|" + form.url; } + +// @Get("/bigInt/{val}") +// String testBigInt(BigInteger val) { +// return "hi|" + val; +// } } From e95c8189b79b9ef7a27c56d1fb09f334cbad4154 Mon Sep 17 00:00:00 2001 From: "robin.bygrave" Date: Wed, 13 Sep 2023 17:16:29 +1200 Subject: [PATCH 0891/1323] #285 BigInteger support for path parameter --- .../src/main/java/org/example/HelloController.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/tests/test-nima-jsonb/src/main/java/org/example/HelloController.java b/tests/test-nima-jsonb/src/main/java/org/example/HelloController.java index 95d7ea403..515ae0852 100644 --- a/tests/test-nima-jsonb/src/main/java/org/example/HelloController.java +++ b/tests/test-nima-jsonb/src/main/java/org/example/HelloController.java @@ -1,5 +1,6 @@ package org.example; +import java.math.BigInteger; import java.util.List; import java.util.Map; import java.util.Set; @@ -149,8 +150,8 @@ String formBean(MyForm form) { return form.name + "|" + form.email + "|" + form.url; } -// @Get("/bigInt/{val}") -// String testBigInt(BigInteger val) { -// return "hi|" + val; -// } + @Get("/bigInt/{val}") + String testBigInt(BigInteger val, BigInteger someQueryParam) { + return "hi|" + val; + } } From 1df04df985a84dfb7966ed6f08a30e5880089c7a Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Wed, 13 Sep 2023 22:12:26 +1200 Subject: [PATCH 0892/1323] Version 2.0-RC8 --- http-api-javalin/pom.xml | 2 +- http-api/pom.xml | 2 +- http-client-gson-adapter/pom.xml | 4 ++-- http-client/pom.xml | 2 +- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 2 +- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-inject-plugin/pom.xml | 2 +- pom.xml | 2 +- tests/pom.xml | 2 +- tests/test-client-generation/pom.xml | 2 +- tests/test-client/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- .../test-javalin-jsonb/src/main/resources/public/openapi.json | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- 20 files changed, 21 insertions(+), 21 deletions(-) diff --git a/http-api-javalin/pom.xml b/http-api-javalin/pom.xml index 16aaae1bb..d5616b258 100644 --- a/http-api-javalin/pom.xml +++ b/http-api-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC7 + 2.0-RC8 .. diff --git a/http-api/pom.xml b/http-api/pom.xml index ab0ba7010..089a6c02a 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC7 + 2.0-RC8 .. diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index 2b8446a4f..f58b77c3e 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC7 + 2.0-RC8 avaje-http-client-gson @@ -20,7 +20,7 @@ io.avaje avaje-http-client - 2.0-RC7 + 2.0-RC8 provided diff --git a/http-client/pom.xml b/http-client/pom.xml index eb0492b8f..4d6ab7c98 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC7 + 2.0-RC8 avaje-http-client diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index 9c32a8bed..805cb7809 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC7 + 2.0-RC8 avaje-http-client-generator diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 49d6744bd..e3ba1f5ed 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC7 + 2.0-RC8 avaje-http-generator-core diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index f21f9bbda..765e21bb5 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.0-RC7 + 2.0-RC8 avaje-http-helidon-generator diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index 94c46ac65..609323968 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC7 + 2.0-RC8 avaje-http-javalin-generator diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index 7509babd2..3a3d5222e 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC7 + 2.0-RC8 avaje-http-jex-generator diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index 5f3ed7e73..dad0d27a9 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC7 + 2.0-RC8 .. diff --git a/pom.xml b/pom.xml index 4642aec92..6ae21c084 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-parent - 2.0-RC7 + 2.0-RC8 pom diff --git a/tests/pom.xml b/tests/pom.xml index 68bda2969..35f7bbc39 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.0-RC7 + 2.0-RC8 tests diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index ff7959251..fd0073afd 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.0-RC7 + 2.0-RC8 test-client-generation diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index 9ccb47245..7ab7e2f4c 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.0-RC7 + 2.0-RC8 test-client diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index ffb0a6f29..c056df89f 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 2.0-RC7 + 2.0-RC8 test-javalin-jsonb diff --git a/tests/test-javalin-jsonb/src/main/resources/public/openapi.json b/tests/test-javalin-jsonb/src/main/resources/public/openapi.json index 26783f108..9fc694f3f 100644 --- a/tests/test-javalin-jsonb/src/main/resources/public/openapi.json +++ b/tests/test-javalin-jsonb/src/main/resources/public/openapi.json @@ -1,7 +1,7 @@ { "openapi" : "3.0.1", "info" : { - "title" : "Example service", + "title" : "Example service showing off the Path extension method of controller", "description" : "Example Javalin controllers with Java and Maven", "version" : "" }, diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 35e13160e..491b5c093 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.0-RC7 + 2.0-RC8 test-javalin diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 06014230e..9b392659a 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.0-RC7 + 2.0-RC8 test-jex diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index e20b842f6..006605cf1 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.0-RC7 + 2.0-RC8 test-nima-jsonb diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index 278611dc6..89193015d 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.0-RC7 + 2.0-RC8 test-nima From 433c96a16d27fea085c8d1435057747b33178a55 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Thu, 14 Sep 2023 00:03:24 -0400 Subject: [PATCH 0893/1323] Update ClientMethodWriter.java --- .../http/generator/client/ClientMethodWriter.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java index 741b8f65e..303815c6f 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java @@ -4,7 +4,6 @@ import io.avaje.http.generator.core.*; import javax.lang.model.element.TypeElement; -import javax.lang.model.type.TypeMirror; import javax.lang.model.util.ElementFilter; import java.util.List; @@ -42,6 +41,10 @@ class ClientMethodWriter { void addImportTypes(ControllerReader reader) { reader.addImportTypes(returnType.importTypes()); + method.throwsList().stream() + .map(UType::parse) + .map(UType::importTypes) + .forEach(reader::addImportTypes); for (final MethodParam param : method.params()) { reader.addImportTypes(param.utype().importTypes()); } @@ -295,10 +298,13 @@ private void writeErrorMapper() { .map(Util::trimAnnotations) .anyMatch("io.avaje.http.client.HttpException"::equals)) .findFirst() + .map(TypeElement::getQualifiedName) + .map(Object::toString) + .map(Util::shortName) .ifPresent( exception -> writer - .append(" .errorMapper(%s::new)", exception.getQualifiedName().toString()) + .append(" .errorMapper(%s::new)", exception) .eol()); } From 833792c780d0843fc31a33d2569d62a5390869b3 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Tue, 19 Sep 2023 14:13:57 -0400 Subject: [PATCH 0894/1323] 21 --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index dde1adbfc..5cc2e69cd 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -10,7 +10,7 @@ jobs: strategy: fail-fast: false matrix: - java_version: [17, 21-ea] + java_version: [17, 21] os: [ubuntu-latest] steps: From a871e82e03484b00c7a1d7ba51bb8d4ffc9eb532 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Mon, 25 Sep 2023 22:47:32 +1300 Subject: [PATCH 0895/1323] [http client] When building default underlying HttpClient create each time That is, do not store/keep the underlying HttpClient if it is being created as part of build(). This means that the build() method can be called multiple times to create multiple clients with different underlying HttpClient instances. --- .../io/avaje/http/client/DBaseBuilder.java | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/http-client/src/main/java/io/avaje/http/client/DBaseBuilder.java b/http-client/src/main/java/io/avaje/http/client/DBaseBuilder.java index 678730c18..194d3beea 100644 --- a/http-client/src/main/java/io/avaje/http/client/DBaseBuilder.java +++ b/http-client/src/main/java/io/avaje/http/client/DBaseBuilder.java @@ -10,13 +10,13 @@ import java.net.CookieHandler; import java.net.CookieManager; import java.net.ProxySelector; +import java.net.http.HttpClient; import java.time.Duration; import java.util.ArrayList; import java.util.List; import java.util.Optional; import java.util.concurrent.Executor; import java.util.function.Function; -import java.net.http.HttpClient; import static java.util.Objects.requireNonNull; @@ -97,9 +97,9 @@ private RequestIntercept buildIntercept() { private HttpClient defaultClient() { final var builder = - HttpClient.newBuilder() - .followRedirects(redirect) - .connectTimeout(connectionTimeout); + HttpClient.newBuilder() + .followRedirects(redirect) + .connectTimeout(connectionTimeout); if (cookieHandler != null) { builder.cookieHandler(cookieHandler); } @@ -127,7 +127,9 @@ private HttpClient defaultClient() { return builder.build(); } - /** Create a reasonable default BodyAdapter if avaje-jsonb or Jackson are present. */ + /** + * Create a reasonable default BodyAdapter if avaje-jsonb or Jackson are present. + */ private BodyAdapter defaultBodyAdapter() { if (detectJsonb()) { bodyAdapter = new JsonbBodyAdapter(); @@ -157,9 +159,7 @@ private boolean detectTypeExists(String className) { DHttpClientContext buildClient() { requireNonNull(baseUrl, "baseUrl is not specified"); requireNonNull(requestTimeout, "requestTimeout is not specified"); - if (client == null) { - client = defaultClient(); - } + final var httpClient = client != null ? client : defaultClient(); if (requestLogging) { // register the built-in request/response logging this.listeners.add(new RequestLogger()); @@ -168,14 +168,14 @@ DHttpClientContext buildClient() { bodyAdapter = defaultBodyAdapter(); } return new DHttpClientContext( - client, - baseUrl, - requestTimeout, - bodyAdapter, - retryHandler, - errorHandler, - buildListener(), - authTokenProvider, - buildIntercept()); + httpClient, + baseUrl, + requestTimeout, + bodyAdapter, + retryHandler, + errorHandler, + buildListener(), + authTokenProvider, + buildIntercept()); } } From a4647f8b520ec2ee4896608dcb33749c4498e300 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Mon, 25 Sep 2023 23:01:28 +1300 Subject: [PATCH 0896/1323] [http client] Refactor move DBaseBuilder code into DHttpClientBuilder --- .../io/avaje/http/client/DBaseBuilder.java | 181 ------------------ .../avaje/http/client/DHttpClientBuilder.java | 165 +++++++++++++++- 2 files changed, 163 insertions(+), 183 deletions(-) delete mode 100644 http-client/src/main/java/io/avaje/http/client/DBaseBuilder.java diff --git a/http-client/src/main/java/io/avaje/http/client/DBaseBuilder.java b/http-client/src/main/java/io/avaje/http/client/DBaseBuilder.java deleted file mode 100644 index 194d3beea..000000000 --- a/http-client/src/main/java/io/avaje/http/client/DBaseBuilder.java +++ /dev/null @@ -1,181 +0,0 @@ -package io.avaje.http.client; - -import com.fasterxml.jackson.databind.ObjectMapper; -import io.avaje.inject.BeanScope; -import io.avaje.jsonb.Jsonb; - -import javax.net.ssl.SSLContext; -import javax.net.ssl.SSLParameters; -import java.net.Authenticator; -import java.net.CookieHandler; -import java.net.CookieManager; -import java.net.ProxySelector; -import java.net.http.HttpClient; -import java.time.Duration; -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; -import java.util.concurrent.Executor; -import java.util.function.Function; - -import static java.util.Objects.requireNonNull; - -abstract class DBaseBuilder { - - HttpClient client; - String baseUrl; - boolean requestLogging = true; - Duration connectionTimeout = Duration.ofSeconds(20); - Duration requestTimeout = Duration.ofSeconds(20); - BodyAdapter bodyAdapter; - RetryHandler retryHandler; - Function errorHandler; - AuthTokenProvider authTokenProvider; - - CookieHandler cookieHandler = new CookieManager(); - HttpClient.Redirect redirect = HttpClient.Redirect.NORMAL; - HttpClient.Version version; - Executor executor; - ProxySelector proxy; - SSLContext sslContext; - SSLParameters sslParameters; - Authenticator authenticator; - int priority; - - final List interceptors = new ArrayList<>(); - final List listeners = new ArrayList<>(); - - void configureFromScope(BeanScope beanScope) { - if (bodyAdapter == null) { - configureBodyAdapter(beanScope); - } - if (retryHandler == null) { - configureRetryHandler(beanScope); - } - } - - private void configureRetryHandler(BeanScope beanScope) { - beanScope.getOptional(RetryHandler.class) - .ifPresent(this::setRetryHandler); - } - - private void setRetryHandler(RetryHandler retryHandler) { - this.retryHandler = retryHandler; - } - - private void configureBodyAdapter(BeanScope beanScope) { - Optional body = beanScope.getOptional(BodyAdapter.class); - if (body.isPresent()) { - bodyAdapter = body.get(); - } else if (beanScope.contains("io.avaje.jsonb.Jsonb")) { - bodyAdapter = new JsonbBodyAdapter(beanScope.get(Jsonb.class)); - } else if (beanScope.contains("com.fasterxml.jackson.databind.ObjectMapper")) { - ObjectMapper objectMapper = beanScope.get(ObjectMapper.class); - bodyAdapter = new JacksonBodyAdapter(objectMapper); - } - } - - private RequestListener buildListener() { - if (listeners.isEmpty()) { - return null; - } else if (listeners.size() == 1) { - return listeners.get(0); - } else { - return new DRequestListeners(listeners); - } - } - - private RequestIntercept buildIntercept() { - if (interceptors.isEmpty()) { - return null; - } else if (interceptors.size() == 1) { - return interceptors.get(0); - } else { - return new DRequestInterceptors(interceptors); - } - } - - private HttpClient defaultClient() { - final var builder = - HttpClient.newBuilder() - .followRedirects(redirect) - .connectTimeout(connectionTimeout); - if (cookieHandler != null) { - builder.cookieHandler(cookieHandler); - } - if (version != null) { - builder.version(version); - } - if (executor != null) { - builder.executor(executor); - } - if (proxy != null) { - builder.proxy(proxy); - } - if (sslContext != null) { - builder.sslContext(sslContext); - } - if (sslParameters != null) { - builder.sslParameters(sslParameters); - } - if (authenticator != null) { - builder.authenticator(authenticator); - } - if (priority > 0) { - builder.priority(priority); - } - return builder.build(); - } - - /** - * Create a reasonable default BodyAdapter if avaje-jsonb or Jackson are present. - */ - private BodyAdapter defaultBodyAdapter() { - if (detectJsonb()) { - bodyAdapter = new JsonbBodyAdapter(); - } else if (detectJackson()) { - bodyAdapter = new JacksonBodyAdapter(); - } - return bodyAdapter; - } - - private boolean detectJsonb() { - return detectTypeExists("io.avaje.jsonb.Jsonb"); - } - - private boolean detectJackson() { - return detectTypeExists("com.fasterxml.jackson.databind.ObjectMapper"); - } - - private boolean detectTypeExists(String className) { - try { - Class.forName(className); - return true; - } catch (ClassNotFoundException | IllegalAccessError e) { - return false; - } - } - - DHttpClientContext buildClient() { - requireNonNull(baseUrl, "baseUrl is not specified"); - requireNonNull(requestTimeout, "requestTimeout is not specified"); - final var httpClient = client != null ? client : defaultClient(); - if (requestLogging) { - // register the built-in request/response logging - this.listeners.add(new RequestLogger()); - } - if (bodyAdapter == null) { - bodyAdapter = defaultBodyAdapter(); - } - return new DHttpClientContext( - httpClient, - baseUrl, - requestTimeout, - bodyAdapter, - retryHandler, - errorHandler, - buildListener(), - authTokenProvider, - buildIntercept()); - } -} diff --git a/http-client/src/main/java/io/avaje/http/client/DHttpClientBuilder.java b/http-client/src/main/java/io/avaje/http/client/DHttpClientBuilder.java index 5b855883a..ecb898046 100644 --- a/http-client/src/main/java/io/avaje/http/client/DHttpClientBuilder.java +++ b/http-client/src/main/java/io/avaje/http/client/DHttpClientBuilder.java @@ -1,18 +1,174 @@ package io.avaje.http.client; +import com.fasterxml.jackson.databind.ObjectMapper; import io.avaje.inject.BeanScope; +import io.avaje.jsonb.Jsonb; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLParameters; import java.net.Authenticator; import java.net.CookieHandler; +import java.net.CookieManager; import java.net.ProxySelector; import java.time.Duration; +import java.util.ArrayList; import java.util.Collections; +import java.util.List; +import java.util.Optional; import java.util.concurrent.Executor; import java.util.function.Function; -final class DHttpClientBuilder extends DBaseBuilder implements HttpClient.Builder, HttpClient.Builder.State { +import static java.util.Objects.requireNonNull; + +final class DHttpClientBuilder implements HttpClient.Builder, HttpClient.Builder.State { + + private java.net.http.HttpClient client; + private String baseUrl; + private boolean requestLogging = true; + private Duration connectionTimeout = Duration.ofSeconds(20); + private Duration requestTimeout = Duration.ofSeconds(20); + private BodyAdapter bodyAdapter; + private RetryHandler retryHandler; + private Function errorHandler; + private AuthTokenProvider authTokenProvider; + + private CookieHandler cookieHandler = new CookieManager(); + private java.net.http.HttpClient.Redirect redirect = java.net.http.HttpClient.Redirect.NORMAL; + private java.net.http.HttpClient.Version version; + private Executor executor; + private ProxySelector proxy; + private SSLContext sslContext; + private SSLParameters sslParameters; + private Authenticator authenticator; + private int priority; + + private final List interceptors = new ArrayList<>(); + private final List listeners = new ArrayList<>(); + + private void configureRetryHandler(BeanScope beanScope) { + beanScope.getOptional(RetryHandler.class) + .ifPresent(this::setRetryHandler); + } + + private void setRetryHandler(RetryHandler retryHandler) { + this.retryHandler = retryHandler; + } + + private void configureBodyAdapter(BeanScope beanScope) { + Optional body = beanScope.getOptional(BodyAdapter.class); + if (body.isPresent()) { + bodyAdapter = body.get(); + } else if (beanScope.contains("io.avaje.jsonb.Jsonb")) { + bodyAdapter = new JsonbBodyAdapter(beanScope.get(Jsonb.class)); + } else if (beanScope.contains("com.fasterxml.jackson.databind.ObjectMapper")) { + ObjectMapper objectMapper = beanScope.get(ObjectMapper.class); + bodyAdapter = new JacksonBodyAdapter(objectMapper); + } + } + + private RequestListener buildListener() { + if (listeners.isEmpty()) { + return null; + } else if (listeners.size() == 1) { + return listeners.get(0); + } else { + return new DRequestListeners(listeners); + } + } + + private RequestIntercept buildIntercept() { + if (interceptors.isEmpty()) { + return null; + } else if (interceptors.size() == 1) { + return interceptors.get(0); + } else { + return new DRequestInterceptors(interceptors); + } + } + + private java.net.http.HttpClient defaultClient() { + final var builder = java.net.http.HttpClient.newBuilder() + .followRedirects(redirect) + .connectTimeout(connectionTimeout); + + if (cookieHandler != null) { + builder.cookieHandler(cookieHandler); + } + if (version != null) { + builder.version(version); + } + if (executor != null) { + builder.executor(executor); + } + if (proxy != null) { + builder.proxy(proxy); + } + if (sslContext != null) { + builder.sslContext(sslContext); + } + if (sslParameters != null) { + builder.sslParameters(sslParameters); + } + if (authenticator != null) { + builder.authenticator(authenticator); + } + if (priority > 0) { + builder.priority(priority); + } + return builder.build(); + } + + /** + * Create a reasonable default BodyAdapter if avaje-jsonb or Jackson are present. + */ + private BodyAdapter defaultBodyAdapter() { + if (detectJsonb()) { + bodyAdapter = new JsonbBodyAdapter(); + } else if (detectJackson()) { + bodyAdapter = new JacksonBodyAdapter(); + } + return bodyAdapter; + } + + private boolean detectJsonb() { + return detectTypeExists("io.avaje.jsonb.Jsonb"); + } + + private boolean detectJackson() { + return detectTypeExists("com.fasterxml.jackson.databind.ObjectMapper"); + } + + private boolean detectTypeExists(String className) { + try { + Class.forName(className); + return true; + } catch (ClassNotFoundException | IllegalAccessError e) { + return false; + } + } + + private DHttpClientContext buildClient() { + requireNonNull(baseUrl, "baseUrl is not specified"); + requireNonNull(requestTimeout, "requestTimeout is not specified"); + final var httpClient = client != null ? client : defaultClient(); + if (requestLogging) { + // register the built-in request/response logging + this.listeners.add(new RequestLogger()); + } + if (bodyAdapter == null) { + bodyAdapter = defaultBodyAdapter(); + } + return new DHttpClientContext( + httpClient, + baseUrl, + requestTimeout, + bodyAdapter, + retryHandler, + errorHandler, + buildListener(), + authTokenProvider, + buildIntercept()); + } DHttpClientBuilder() { } @@ -144,7 +300,12 @@ public HttpClient.Builder.State state() { @Override public HttpClient.Builder configureWith(BeanScope beanScope) { - super.configureFromScope(beanScope); + if (bodyAdapter == null) { + configureBodyAdapter(beanScope); + } + if (retryHandler == null) { + configureRetryHandler(beanScope); + } return this; } From 5ab0dd365691a27325a991f3a0d37dff061e3db0 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 26 Sep 2023 00:10:36 +1300 Subject: [PATCH 0897/1323] [http client] Generation for @Client.Import when argument names lost When the interface has been previously compiled then the method arg names are effectively lost - become arg0, arg1, arg2 etc. In this case the generation can get the implied arg names for path parameters from the segments but for @QueryParam and @Header parameters we now need explicitly named arguments. This change handles the path segments and gives a reasonable error for QueryParams and Headers etc that are not explicitly named. --- .../generator/client/ClientMethodWriter.java | 29 +++++++++-- .../client/ClientPlatformAdapter.java | 3 +- .../http/generator/core/ElementReader.java | 40 +++++++++------ .../http/generator/core/MethodParam.java | 13 ++++- .../http/generator/core/MethodReader.java | 49 +++++++++++++++++-- .../http/generator/core/PlatformAdapter.java | 3 +- .../helidon/nima/NimaPlatformAdapter.java | 3 +- .../generator/javalin/JavalinAdapter.java | 3 +- tests/test-client-generation/pom.xml | 4 +- .../src/main/java/org/example/CommonApi.java | 3 +- .../java/org/example/client/package-info.java | 1 - .../test/java/org/example/CommonApiTest.java | 2 + 12 files changed, 117 insertions(+), 36 deletions(-) diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java index 303815c6f..4473ec15e 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java @@ -54,6 +54,7 @@ private void methodStart(Append writer) { for (MethodParam param : method.params()) { checkBodyHandler(param); } + method.checkArgumentNames(); writer.append(" // %s %s", webMethod, method.webMethodPath()).eol(); writer.append(" @Override").eol(); AnnotationUtil.writeAnnotations(writer, method.element()); @@ -72,8 +73,10 @@ private void methodStart(Append writer) { ? "Supplier" : param.utype().shortType(); - final var finalType = - isVarArg ? paramType.substring(0, paramType.length() - 2) + "..." : paramType; + if (param.overrideVarNameError()) { + writer.append("/** !Error! */ "); + } + final var finalType = isVarArg ? paramType.substring(0, paramType.length() - 2) + "..." : paramType; writer.append(finalType).append(" "); writer.append(param.name()); } @@ -203,16 +206,34 @@ void writeGeneric(UType type) { } private void writeQueryParams(PathSegments pathSegments) { + boolean clientImportError = false; for (final MethodParam param : method.params()) { final ParamType paramType = param.paramType(); if (paramType == ParamType.QUERYPARAM && pathSegments.segment(param.paramName()) == null) { if (isMap(param)) { - writer.append(" .queryParam(%s)", param.name()).eol(); + writer.append(" .queryParam(%s)", param.name()); } else { - writer.append(" .queryParam(\"%s\", %s)", param.paramName(), param.name()).eol(); + writer.append(" .queryParam(\"%s\", %s)", param.paramName(), param.name()); + } + if (param.overrideVarNameError()) { + clientImportError = true; + writer.append(" // !Error!"); } + writer.eol(); } } + if (clientImportError) { + writer.eol(); + writer.append(" ; !Error! // Explicit @QueryParam(\"...\") required with @Client.Import").eol(); + writer.append(" // generation when using @Client.Import on on interface that has already been compiled.").eol(); + writer.append(" // We effectively lose the method argument names, they become arg0, arg1, arg2, arg3 etc.").eol(); + writer.append(" // We need to use explicit @QueryParam(\"...\") on the interface method parameters").eol(); + writer.append(" // to explicitly name the query parameters and header parameters etc and can no").eol(); + writer.append(" // longer rely on the implied names [when the interface type has already been compiled].").eol(); + writer.append(" //").eol(); + writer.append(" // Refer to: https://avaje.io/http/client/import#error").eol(); + writer.eol(); + } } private void writeHeaders() { diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientPlatformAdapter.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientPlatformAdapter.java index 509dc1ab4..1e1cb04dd 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientPlatformAdapter.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientPlatformAdapter.java @@ -45,8 +45,7 @@ public void methodRoles(List roles, ControllerReader controller) {} public void writeReadParameter(Append writer, ParamType paramType, String paramName) {} @Override - public void writeReadParameter( - Append writer, ParamType paramType, String paramName, String paramDefault) {} + public void writeReadParameter(Append writer, ParamType paramType, String paramName, String paramDefault) {} @Override public void writeAcceptLanguage(Append writer) {} diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java index d43de744f..a9e91d53b 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java @@ -24,13 +24,14 @@ public class ElementReader { private final String rawType; private final String shortType; private final TypeHandler typeHandler; - private final String varName; private final String snakeName; private final boolean formMarker; private final boolean contextType; private final boolean useValidation; private final boolean specialParam; + private boolean overrideVarNameError; + private String varName; private String paramName; private ParamType paramType; private String matrixParamName; @@ -100,11 +101,8 @@ private void beanParamImports(String rawType) { } TypeHandler initTypeHandler() { - if (specialParam) { - - final var typeOp = - Optional.ofNullable(type).or(() -> Optional.of(UType.parse(element.asType()))); + final var typeOp = Optional.ofNullable(type).or(() -> Optional.of(UType.parse(element.asType()))); final var mainTypeEnum = typeOp @@ -135,7 +133,6 @@ TypeHandler initTypeHandler() { return TypeMap.collectionHandler(typeOp.orElseThrow(), isEnumCollection); } else if (isMap) { this.isParamMap = true; - return new TypeMap.StringHandler(); } } @@ -152,7 +149,6 @@ private boolean useValidation() { } private void readAnnotations(Element element, ParamType defaultType) { - notNullKotlin = NotNullPrism.getInstanceOn(element) != null; final var defaultVal = DefaultPrism.getInstanceOn(element); @@ -202,8 +198,7 @@ private void readAnnotations(Element element, ParamType defaultType) { return; } - if ("java.lang.String".equals(element.asType().toString()) - && BodyStringPrism.isPresent(element)) { + if ("java.lang.String".equals(element.asType().toString()) && BodyStringPrism.isPresent(element)) { this.paramType = ParamType.BODY; return; } @@ -235,6 +230,24 @@ public String varName() { return varName; } + public boolean overrideVarNameError() { + return overrideVarNameError; + } + + public void overrideVarName(String name, ParamType paramType) { + this.varName = name; + this.paramType = paramType; + } + + public void overrideVarName(int position) { + if (paramName.equals("arg" + position)) { + overrideVarNameError = true; + // varName += " /** @QueryParam(name=...) required */ "; + } else { + varName = paramName; + } + } + private boolean hasParamDefault() { return paramDefault != null && !paramDefault.isEmpty(); } @@ -256,7 +269,6 @@ private String handlerShortType() { } void addImports(ControllerReader bean) { - bean.addImportTypes(imports); } @@ -295,8 +307,7 @@ void writeValidate(Append writer) { } void writeCtxGet(Append writer, PathSegments segments) { - if (isPlatformContext() - || (paramType == ParamType.BODY && platform().isBodyMethodParam())) { + if (isPlatformContext() || (paramType == ParamType.BODY && platform().isBodyMethodParam())) { // body passed as method parameter (Helidon) return; } @@ -316,7 +327,6 @@ void setValue(Append writer) { } private boolean setValue(Append writer, PathSegments segments, String shortType) { - if (ParamType.FORM == paramType) { writeForm(writer, shortType, varName, ParamType.FORMPARAM); return false; @@ -367,13 +377,11 @@ private boolean setValue(Append writer, PathSegments segments, String shortType) } else if (hasParamDefault()) { platform().writeReadParameter(writer, paramType, paramName, paramDefault.get(0)); } else { - final var checkNull = - notNullKotlin || (paramType == ParamType.FORMPARAM && typeHandler.isPrimitive()); + final var checkNull = notNullKotlin || (paramType == ParamType.FORMPARAM && typeHandler.isPrimitive()); if (checkNull) { writer.append("checkNull("); } platform().writeReadParameter(writer, paramType, paramName); - // writer.append("%s(\"%s\")", paramType, paramName); if (checkNull) { writer.append(", \"%s\")", paramName); } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodParam.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodParam.java index 431773b70..7e741140e 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodParam.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodParam.java @@ -2,7 +2,6 @@ import static io.avaje.http.generator.core.ProcessingContext.asElement; -import javax.lang.model.element.Element; import javax.lang.model.element.ElementKind; import javax.lang.model.element.VariableElement; @@ -69,6 +68,18 @@ public String name() { return elementParam.varName(); } + public boolean overrideVarNameError() { + return elementParam.overrideVarNameError(); + } + + public void overrideVarName(String name, ParamType paramType) { + elementParam.overrideVarName(name, paramType); + } + + public void overrideVarName(int position) { + elementParam.overrideVarName(position); + } + public String paramName() { return elementParam.paramName(); } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java index 5be2ead05..d7140d6b6 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java @@ -5,10 +5,7 @@ import static io.avaje.http.generator.core.ProcessingContext.platform; import static io.avaje.http.generator.core.ProcessingContext.superMethods; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Optional; +import java.util.*; import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Predicate; @@ -468,4 +465,48 @@ public String exceptionShortName() { public List throwsList() { return throwsList; } + + /** + * Check if all the argument names have been lost which occurs if the + * imported API was previously compiled. All the argument names are + * arg0, arg1, arg2 etc. + */ + public void checkArgumentNames() { + if (!params.isEmpty() && pathSegments != null) { + if (allArgParamNames()) { + final var namedSegments = namedSegments(); + if (params.size() >= namedSegments.size()) { + // path params, take the names from the segments + for (int i = 0; i < namedSegments.size(); i++) { + MethodParam pathParam = params.get(i); + pathParam.overrideVarName(namedSegments.get(i).name(), ParamType.PATHPARAM); + } + // QueryParam and Headers which now require explicit names + for (int i = namedSegments.size(); i < params.size(); i++) { + MethodParam param = params.get(i); + param.overrideVarName(i); + } + } + } + } + } + + private List namedSegments() { + final var namedSegments = new ArrayList(); + for (PathSegments.Segment segment : pathSegments.segments()) { + if (!segment.isLiteral()) { + namedSegments.add(segment); + } + } + return namedSegments; + } + + private boolean allArgParamNames() { + for (int i = 0; i < params.size(); i++) { + if (!params.get(i).name().equals("arg" + i)) { + return false; + } + } + return true; + } } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/PlatformAdapter.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/PlatformAdapter.java index 7bddea839..6d9ce0f60 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/PlatformAdapter.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/PlatformAdapter.java @@ -35,8 +35,7 @@ public interface PlatformAdapter { void writeReadParameter(Append writer, ParamType paramType, String paramName); - void writeReadParameter( - Append writer, ParamType paramType, String paramName, String paramDefault); + void writeReadParameter(Append writer, ParamType paramType, String paramName, String paramDefault); void writeAcceptLanguage(Append writer); diff --git a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/NimaPlatformAdapter.java b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/NimaPlatformAdapter.java index c0262ae16..83790aefc 100644 --- a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/NimaPlatformAdapter.java +++ b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/NimaPlatformAdapter.java @@ -83,8 +83,7 @@ public void writeReadParameter(Append writer, ParamType paramType, String paramN } @Override - public void writeReadParameter( - Append writer, ParamType paramType, String paramName, String paramDefault) { + public void writeReadParameter(Append writer, ParamType paramType, String paramName, String paramDefault) { switch (paramType) { case PATHPARAM -> writer.append( "pathParams.first(\"%s\").orElse(\"%s\")", paramName, paramDefault); diff --git a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinAdapter.java b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinAdapter.java index 9abf8f421..28cffffe1 100644 --- a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinAdapter.java +++ b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinAdapter.java @@ -77,8 +77,7 @@ public void writeReadParameter(Append writer, ParamType paramType, String paramN } @Override - public void writeReadParameter( - Append writer, ParamType paramType, String paramName, String paramDefault) { + public void writeReadParameter(Append writer, ParamType paramType, String paramName, String paramDefault) { writer.append("withDefault(ctx.%s(\"%s\"), \"%s\")", paramType, paramName, paramDefault); } diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index fd0073afd..cca585e38 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -11,6 +11,8 @@ true + UTF-8 + false @@ -96,7 +98,7 @@ org.apache.maven.plugins maven-compiler-plugin - 3.10.1 + 3.11.0 diff --git a/tests/test-client-generation/src/main/java/org/example/CommonApi.java b/tests/test-client-generation/src/main/java/org/example/CommonApi.java index fd204148e..1f1982bee 100644 --- a/tests/test-client-generation/src/main/java/org/example/CommonApi.java +++ b/tests/test-client-generation/src/main/java/org/example/CommonApi.java @@ -3,6 +3,7 @@ import io.avaje.http.api.Get; import io.avaje.http.api.Path; import io.avaje.http.api.Produces; +import io.avaje.http.api.QueryParam; import java.time.LocalDate; @@ -19,6 +20,6 @@ public interface CommonApi { @Produces("text/plain") @Get("{id}/{name}") - String p2(long id, String name, LocalDate after, Boolean more); + String p2(long id, String name, @QueryParam("after") LocalDate after, @QueryParam("more") Boolean more); } diff --git a/tests/test-client-generation/src/main/java/org/example/client/package-info.java b/tests/test-client-generation/src/main/java/org/example/client/package-info.java index 65acc3114..6cdc0c463 100644 --- a/tests/test-client-generation/src/main/java/org/example/client/package-info.java +++ b/tests/test-client-generation/src/main/java/org/example/client/package-info.java @@ -1,4 +1,3 @@ -@Client.Import(types = CommonApi.class) package org.example.client; import io.avaje.http.api.Client; diff --git a/tests/test-client-generation/src/test/java/org/example/CommonApiTest.java b/tests/test-client-generation/src/test/java/org/example/CommonApiTest.java index 86783388b..28eab4660 100644 --- a/tests/test-client-generation/src/test/java/org/example/CommonApiTest.java +++ b/tests/test-client-generation/src/test/java/org/example/CommonApiTest.java @@ -1,5 +1,6 @@ package org.example; +import io.avaje.http.api.Client; import io.avaje.http.client.HttpClient; import io.avaje.http.client.JacksonBodyAdapter; import org.example.server.Main; @@ -11,6 +12,7 @@ import static org.assertj.core.api.Assertions.assertThat; +@Client.Import(types = CommonApi.class) class CommonApiTest { static CommonApi client; From 1bb89454d4c2b4282fe989ed967b568d0a4a6658 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Mon, 25 Sep 2023 23:57:21 -0400 Subject: [PATCH 0898/1323] use log error for the clinet import compilation message --- .../http/generator/client/ClientMethodWriter.java | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java index 4473ec15e..687083061 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java @@ -223,16 +223,9 @@ private void writeQueryParams(PathSegments pathSegments) { } } if (clientImportError) { - writer.eol(); - writer.append(" ; !Error! // Explicit @QueryParam(\"...\") required with @Client.Import").eol(); - writer.append(" // generation when using @Client.Import on on interface that has already been compiled.").eol(); - writer.append(" // We effectively lose the method argument names, they become arg0, arg1, arg2, arg3 etc.").eol(); - writer.append(" // We need to use explicit @QueryParam(\"...\") on the interface method parameters").eol(); - writer.append(" // to explicitly name the query parameters and header parameters etc and can no").eol(); - writer.append(" // longer rely on the implied names [when the interface type has already been compiled].").eol(); - writer.append(" //").eol(); - writer.append(" // Refer to: https://avaje.io/http/client/import#error").eol(); - writer.eol(); + logError( + "Explicit @QueryParam(\\\"...\\\") required when using @Client.Import on an interface that has already been compiled.", + method.element()); } } From 55402c80fc1be4cc0fe8132bd1801a52d51e7a36 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Tue, 26 Sep 2023 00:01:44 -0400 Subject: [PATCH 0899/1323] Update ClientMethodWriter.java --- .../java/io/avaje/http/generator/client/ClientMethodWriter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java index 687083061..a0e258646 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java @@ -224,7 +224,7 @@ private void writeQueryParams(PathSegments pathSegments) { } if (clientImportError) { logError( - "Explicit @QueryParam(\\\"...\\\") required when using @Client.Import on an interface that has already been compiled.", + "Explicit @QueryParam/@Header annotations required when using @Client.Import on an interface that has already been compiled.", method.element()); } } From 55a4c57dc007ad65e0d6538f563f65cf3318cf7e Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 26 Sep 2023 23:37:36 +1300 Subject: [PATCH 0900/1323] [http client] Generation for @Client.Import when argument names lost Will create an actual syntax error which could help users identify where the error is. --- .../io/avaje/http/generator/client/ClientMethodWriter.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java index a0e258646..956431ac9 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java @@ -217,12 +217,17 @@ private void writeQueryParams(PathSegments pathSegments) { } if (param.overrideVarNameError()) { clientImportError = true; - writer.append(" // !Error!"); + writer.append(" // !Error! with %s", param.name()); } writer.eol(); } } if (clientImportError) { + writer.append(" ; !Error!").eol(); + writer.eol(); + writer.append(" // Explicit @QueryParam(\"...\") required with @Client.Import").eol(); + writer.append(" // Refer to: https://avaje.io/http/client/import#error").eol(); + writer.eol(); logError( "Explicit @QueryParam/@Header annotations required when using @Client.Import on an interface that has already been compiled.", method.element()); From d0dfbdd11b8981ecd24aa53498ca761341a4f61e Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 26 Sep 2023 23:52:26 +1300 Subject: [PATCH 0901/1323] Version 2.0-RC9 --- http-api-javalin/pom.xml | 2 +- http-api/pom.xml | 2 +- http-client-gson-adapter/pom.xml | 4 ++-- http-client/pom.xml | 2 +- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 2 +- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-inject-plugin/pom.xml | 2 +- pom.xml | 2 +- tests/pom.xml | 2 +- tests/test-client-generation/pom.xml | 2 +- tests/test-client/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- 19 files changed, 20 insertions(+), 20 deletions(-) diff --git a/http-api-javalin/pom.xml b/http-api-javalin/pom.xml index d5616b258..e9dd54c65 100644 --- a/http-api-javalin/pom.xml +++ b/http-api-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC8 + 2.0-RC9 .. diff --git a/http-api/pom.xml b/http-api/pom.xml index 089a6c02a..88b89b48f 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC8 + 2.0-RC9 .. diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index f58b77c3e..680c547fd 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC8 + 2.0-RC9 avaje-http-client-gson @@ -20,7 +20,7 @@ io.avaje avaje-http-client - 2.0-RC8 + 2.0-RC9 provided diff --git a/http-client/pom.xml b/http-client/pom.xml index 4d6ab7c98..c52aa630b 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC8 + 2.0-RC9 avaje-http-client diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index 805cb7809..3e5804eaa 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC8 + 2.0-RC9 avaje-http-client-generator diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index e3ba1f5ed..cc1171843 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC8 + 2.0-RC9 avaje-http-generator-core diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index 765e21bb5..19ad2dc47 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.0-RC8 + 2.0-RC9 avaje-http-helidon-generator diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index 609323968..1372ddd05 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC8 + 2.0-RC9 avaje-http-javalin-generator diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index 3a3d5222e..177429463 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC8 + 2.0-RC9 avaje-http-jex-generator diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index dad0d27a9..800cbbdaf 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC8 + 2.0-RC9 .. diff --git a/pom.xml b/pom.xml index 6ae21c084..ee3a8dc9e 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-parent - 2.0-RC8 + 2.0-RC9 pom diff --git a/tests/pom.xml b/tests/pom.xml index 35f7bbc39..fd51a3e29 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.0-RC8 + 2.0-RC9 tests diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index cca585e38..d2ab18e99 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.0-RC8 + 2.0-RC9 test-client-generation diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index 7ab7e2f4c..76056185f 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.0-RC8 + 2.0-RC9 test-client diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index c056df89f..2c86cab40 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 2.0-RC8 + 2.0-RC9 test-javalin-jsonb diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 491b5c093..edef1931b 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.0-RC8 + 2.0-RC9 test-javalin diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 9b392659a..91751f809 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.0-RC8 + 2.0-RC9 test-jex diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 006605cf1..4de5d054b 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.0-RC8 + 2.0-RC9 test-nima-jsonb diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index 89193015d..143c61715 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.0-RC8 + 2.0-RC9 test-nima From 9d56140ff3e83aaadaf432c280427256ba8be5db Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Thu, 28 Sep 2023 14:19:47 -0400 Subject: [PATCH 0902/1323] helidon-rc1 --- .../http/generator/helidon/nima/ControllerWriter.java | 8 ++++---- tests/pom.xml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java index cf6613417..e192f9d05 100644 --- a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java +++ b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java @@ -22,7 +22,7 @@ class ControllerWriter extends BaseControllerWriter { private static final String AT_GENERATED = "@Generated(\"avaje-helidon-generator\")"; - private static final String IMPORT_HTTP_STATUS = "import static io.helidon.http.Http.Status.*;"; + private static final String IMPORT_HTTP_STATUS = "import static io.helidon.http.Status.*;"; private final boolean useJsonB; private final Map jsonTypes; @@ -48,9 +48,9 @@ class ControllerWriter extends BaseControllerWriter { reader.addImportType("io.helidon.webserver.http.ServerRequest"); reader.addImportType("io.helidon.webserver.http.ServerResponse"); reader.addImportType("io.helidon.webserver.http.HttpFeature"); - reader.addImportType("io.helidon.http.Http.HeaderNames"); + reader.addImportType("io.helidon.http.HeaderNames"); if (reader.isIncludeValidator()) { - reader.addImportType("io.helidon.http.Http"); + reader.addImportType("io.helidon.http.HeaderName"); } if (reader.methods().stream() .map(MethodReader::webMethod) @@ -118,7 +118,7 @@ private void writeClassStart() { } if (reader.isIncludeValidator()) { - writer.append(" private static final Http.HeaderName HEADER_ACCEPT_LANGUAGE = HeaderNames.create(\"Accept-Language\");").eol(); + writer.append(" private static final HeaderName HEADER_ACCEPT_LANGUAGE = HeaderNames.create(\"Accept-Language\");").eol(); } writer.append(" private final %s %s;", controllerType, controllerName).eol(); diff --git a/tests/pom.xml b/tests/pom.xml index fd51a3e29..e539a691d 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -17,7 +17,7 @@ 2.14.1 2.5 9.5 - 4.0.0-M2 + 4.0.0-RC1 From 7494ede19069186e994278f94df9f7507085a931 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 3 Oct 2023 22:31:36 +1300 Subject: [PATCH 0903/1323] Version 2.0-RC10 --- http-api-javalin/pom.xml | 2 +- http-api/pom.xml | 2 +- http-client-gson-adapter/pom.xml | 4 ++-- http-client/pom.xml | 2 +- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 2 +- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-inject-plugin/pom.xml | 2 +- pom.xml | 2 +- tests/pom.xml | 2 +- tests/test-client-generation/pom.xml | 2 +- tests/test-client/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- 19 files changed, 20 insertions(+), 20 deletions(-) diff --git a/http-api-javalin/pom.xml b/http-api-javalin/pom.xml index e9dd54c65..5bf74889c 100644 --- a/http-api-javalin/pom.xml +++ b/http-api-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC9 + 2.0-RC10 .. diff --git a/http-api/pom.xml b/http-api/pom.xml index 88b89b48f..7271d1065 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC9 + 2.0-RC10 .. diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index 680c547fd..914e0d913 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC9 + 2.0-RC10 avaje-http-client-gson @@ -20,7 +20,7 @@ io.avaje avaje-http-client - 2.0-RC9 + 2.0-RC10 provided diff --git a/http-client/pom.xml b/http-client/pom.xml index c52aa630b..de139ba86 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC9 + 2.0-RC10 avaje-http-client diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index 3e5804eaa..6ddde9d65 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC9 + 2.0-RC10 avaje-http-client-generator diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index cc1171843..9cf07ae92 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC9 + 2.0-RC10 avaje-http-generator-core diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index 19ad2dc47..d1fa0dbeb 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.0-RC9 + 2.0-RC10 avaje-http-helidon-generator diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index 1372ddd05..55d7fa370 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC9 + 2.0-RC10 avaje-http-javalin-generator diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index 177429463..edd78b5db 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC9 + 2.0-RC10 avaje-http-jex-generator diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index 800cbbdaf..b21cacbd4 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC9 + 2.0-RC10 .. diff --git a/pom.xml b/pom.xml index ee3a8dc9e..86731fb02 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-parent - 2.0-RC9 + 2.0-RC10 pom diff --git a/tests/pom.xml b/tests/pom.xml index e539a691d..d77897bd4 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.0-RC9 + 2.0-RC10 tests diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index d2ab18e99..1c11f8f76 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.0-RC9 + 2.0-RC10 test-client-generation diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index 76056185f..196688a9c 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.0-RC9 + 2.0-RC10 test-client diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 2c86cab40..93cb0168d 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 2.0-RC9 + 2.0-RC10 test-javalin-jsonb diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index edef1931b..65247dded 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.0-RC9 + 2.0-RC10 test-javalin diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 91751f809..d944d8532 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.0-RC9 + 2.0-RC10 test-jex diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 4de5d054b..101065969 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.0-RC9 + 2.0-RC10 test-nima-jsonb diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index 143c61715..4f46df84a 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.0-RC9 + 2.0-RC10 test-nima From c7730f2167cb3e420f79a109482b8d411a148792 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Wed, 4 Oct 2023 18:10:35 -0400 Subject: [PATCH 0904/1323] expose client details --- http-api-javalin/pom.xml | 2 +- http-api/pom.xml | 2 +- http-client-gson-adapter/pom.xml | 4 +- http-client/pom.xml | 2 +- .../avaje/http/client/DHttpClientRequest.java | 39 +++++++++++++++++-- .../avaje/http/client/HttpClientRequest.java | 33 ++++++++++++++++ http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 2 +- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-inject-plugin/pom.xml | 2 +- pom.xml | 2 +- tests/pom.xml | 2 +- tests/test-client-generation/pom.xml | 2 +- tests/test-client/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- 21 files changed, 88 insertions(+), 24 deletions(-) diff --git a/http-api-javalin/pom.xml b/http-api-javalin/pom.xml index e9dd54c65..5bf74889c 100644 --- a/http-api-javalin/pom.xml +++ b/http-api-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC9 + 2.0-RC10 .. diff --git a/http-api/pom.xml b/http-api/pom.xml index 88b89b48f..7271d1065 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC9 + 2.0-RC10 .. diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index 680c547fd..914e0d913 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC9 + 2.0-RC10 avaje-http-client-gson @@ -20,7 +20,7 @@ io.avaje avaje-http-client - 2.0-RC9 + 2.0-RC10 provided diff --git a/http-client/pom.xml b/http-client/pom.xml index c52aa630b..de139ba86 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC9 + 2.0-RC10 avaje-http-client diff --git a/http-client/src/main/java/io/avaje/http/client/DHttpClientRequest.java b/http-client/src/main/java/io/avaje/http/client/DHttpClientRequest.java index 8a480ad93..43e997b45 100644 --- a/http-client/src/main/java/io/avaje/http/client/DHttpClientRequest.java +++ b/http-client/src/main/java/io/avaje/http/client/DHttpClientRequest.java @@ -26,6 +26,9 @@ class DHttpClientRequest implements HttpClientRequest, HttpClientResponse { private static final String CONTENT_TYPE = "Content-Type"; private static final String CONTENT_ENCODING = "Content-Encoding"; + private static final String VERB_GET = "GET"; + private static final String VERB_POST = "POST"; + private static final String VERB_PUT = "PUT"; private static final String VERB_DELETE = "DELETE"; private static final String VERB_HEAD = "HEAD"; private static final String VERB_PATCH = "PATCH"; @@ -58,6 +61,7 @@ class DHttpClientRequest implements HttpClientRequest, HttpClientResponse { private Map customAttributes; protected Function errorMapper; protected boolean isRetry; + private String method; DHttpClientRequest(DHttpClientContext context, Duration requestTimeout) { this.context = context; @@ -66,6 +70,20 @@ class DHttpClientRequest implements HttpClientRequest, HttpClientResponse { this.errorMapper = context.errorMapper(); } + public String method() { + return method; + } + + @Override + public UrlBuilder url() { + return url; + } + + @Override + public Optional bodyContent() { + return Optional.ofNullable(encodedRequestBody); + } + @Override public HttpClientRequest skipAuthToken() { this.skipAuthToken = true; @@ -164,10 +182,18 @@ public HttpClientRequest header(Map headers) { @Override public List header(String name) { if (headers == null) { - return Collections.emptyList(); + return List.of(); } final List values = headers.get(name); - return values == null ? Collections.emptyList() : values; + return values == null ? List.of() : values; + } + + @Override + public Map> headers() { + if (headers == null) { + return Map.of(); + } + return headers; } @Override @@ -421,7 +447,8 @@ public HttpClientResponse HEAD() { return this; } - public HttpClientResponse GET() { + @Override +public HttpClientResponse GET() { httpRequest = newGet(url.build()); return this; } @@ -731,14 +758,17 @@ private HttpRequest.Builder newHead(String url) { } private HttpRequest.Builder newGet(String url) { + this.method = VERB_GET; return newReq(url).GET(); } private HttpRequest.Builder newPost(String url, HttpRequest.BodyPublisher body) { + this.method = VERB_POST; return newReq(url).POST(body); } private HttpRequest.Builder newPut(String url, HttpRequest.BodyPublisher body) { + this.method = VERB_PUT; return newReq(url).PUT(body); } @@ -759,6 +789,7 @@ protected HttpRequest.Builder newRequest(String method, String url, HttpRequest. if (body == null) { throw new IllegalArgumentException("body is null but required for " + method + " to " + url); } + this.method = method; return HttpRequest.newBuilder() .uri(URI.create(url)) .timeout(requestTimeout) @@ -777,7 +808,7 @@ boolean isSkipAuthToken() { return skipAuthToken; } - private class ListenerEvent implements RequestListener.Event { +private class ListenerEvent implements RequestListener.Event { @Override public long responseTimeMicros() { diff --git a/http-client/src/main/java/io/avaje/http/client/HttpClientRequest.java b/http-client/src/main/java/io/avaje/http/client/HttpClientRequest.java index 7ac392521..246c69909 100644 --- a/http-client/src/main/java/io/avaje/http/client/HttpClientRequest.java +++ b/http-client/src/main/java/io/avaje/http/client/HttpClientRequest.java @@ -9,6 +9,7 @@ import java.util.Collection; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.function.Function; import java.util.function.Supplier; @@ -145,6 +146,13 @@ public interface HttpClientRequest { */ List header(String name); + /** + * Return the header values that have been set for this request. + * + * @return The headers values or an empty map if no headers have been specified yet. + */ + Map> headers(); + /** * Set if body content should be gzip encoded. * @@ -171,6 +179,24 @@ public interface HttpClientRequest { */ HttpClientRequest url(String url); + /** + * Set the URL to use replacing the base URL. + *

    {code
    +   *
    +   *  HttpResponse res = client.request()
    +   *       .url("http://127.0.0.1:8889")
    +   *       .path("hello")
    +   *       .GET()
    +   *       .asString();
    +   *
    +   * }
    + * + * @param url The url effectively replacing the base url. + * @return The request being built + * @see HttpClient.Builder#baseUrl(String) + */ + UrlBuilder url(); + /** * Add a path segment to the URL. * @@ -389,6 +415,13 @@ default HttpClientRequest queryParam(String name, Collection values) { */ HttpClientRequest body(HttpRequest.BodyPublisher body); + /** + * Get the body content for this request if available. Will return an empty optional for streaming calls + * + * @return The request body + */ + Optional bodyContent(); + /** * Set the mapper used to transform {@link HttpException} into a different kind of exception. * diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index 3e5804eaa..6ddde9d65 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC9 + 2.0-RC10 avaje-http-client-generator diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index cc1171843..9cf07ae92 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC9 + 2.0-RC10 avaje-http-generator-core diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index 19ad2dc47..d1fa0dbeb 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.0-RC9 + 2.0-RC10 avaje-http-helidon-generator diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index 1372ddd05..55d7fa370 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC9 + 2.0-RC10 avaje-http-javalin-generator diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index 177429463..edd78b5db 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC9 + 2.0-RC10 avaje-http-jex-generator diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index 800cbbdaf..b21cacbd4 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC9 + 2.0-RC10 .. diff --git a/pom.xml b/pom.xml index ee3a8dc9e..86731fb02 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-parent - 2.0-RC9 + 2.0-RC10 pom diff --git a/tests/pom.xml b/tests/pom.xml index e539a691d..d77897bd4 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.0-RC9 + 2.0-RC10 tests diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index d2ab18e99..1c11f8f76 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.0-RC9 + 2.0-RC10 test-client-generation diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index 76056185f..196688a9c 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.0-RC9 + 2.0-RC10 test-client diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 2c86cab40..93cb0168d 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 2.0-RC9 + 2.0-RC10 test-javalin-jsonb diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index edef1931b..65247dded 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.0-RC9 + 2.0-RC10 test-javalin diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 91751f809..d944d8532 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.0-RC9 + 2.0-RC10 test-jex diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 4de5d054b..101065969 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.0-RC9 + 2.0-RC10 test-nima-jsonb diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index 143c61715..4f46df84a 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.0-RC9 + 2.0-RC10 test-nima From 767c441eb31e1374cd93b785ca51c5d3ccd3ae2b Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Wed, 4 Oct 2023 18:15:37 -0400 Subject: [PATCH 0905/1323] Update DHttpClientRequest.java --- .../src/main/java/io/avaje/http/client/DHttpClientRequest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/http-client/src/main/java/io/avaje/http/client/DHttpClientRequest.java b/http-client/src/main/java/io/avaje/http/client/DHttpClientRequest.java index 43e997b45..b03e27db5 100644 --- a/http-client/src/main/java/io/avaje/http/client/DHttpClientRequest.java +++ b/http-client/src/main/java/io/avaje/http/client/DHttpClientRequest.java @@ -448,7 +448,7 @@ public HttpClientResponse HEAD() { } @Override -public HttpClientResponse GET() { + public HttpClientResponse GET() { httpRequest = newGet(url.build()); return this; } From ddf91e26760c55ed07008bb6df306ee0cded9ce4 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Wed, 4 Oct 2023 18:48:28 -0400 Subject: [PATCH 0906/1323] doc --- .../avaje/http/client/DHttpClientRequest.java | 5 +++-- .../io/avaje/http/client/HttpClientRequest.java | 17 +++-------------- 2 files changed, 6 insertions(+), 16 deletions(-) diff --git a/http-client/src/main/java/io/avaje/http/client/DHttpClientRequest.java b/http-client/src/main/java/io/avaje/http/client/DHttpClientRequest.java index b03e27db5..382723262 100644 --- a/http-client/src/main/java/io/avaje/http/client/DHttpClientRequest.java +++ b/http-client/src/main/java/io/avaje/http/client/DHttpClientRequest.java @@ -47,6 +47,7 @@ class DHttpClientRequest implements HttpClientRequest, HttpClientResponse { private Map> formParams; private Map> headers; + private Map> queryParams; private boolean bodyFormEncoded; private long responseTimeNanos; @@ -75,8 +76,8 @@ public String method() { } @Override - public UrlBuilder url() { - return url; + public String url() { + return url.build(); } @Override diff --git a/http-client/src/main/java/io/avaje/http/client/HttpClientRequest.java b/http-client/src/main/java/io/avaje/http/client/HttpClientRequest.java index 246c69909..a760e2e61 100644 --- a/http-client/src/main/java/io/avaje/http/client/HttpClientRequest.java +++ b/http-client/src/main/java/io/avaje/http/client/HttpClientRequest.java @@ -180,22 +180,11 @@ public interface HttpClientRequest { HttpClientRequest url(String url); /** - * Set the URL to use replacing the base URL. - *
    {code
    +   * The URL for this request including the query parameters.
        *
    -   *  HttpResponse res = client.request()
    -   *       .url("http://127.0.0.1:8889")
    -   *       .path("hello")
    -   *       .GET()
    -   *       .asString();
    -   *
    -   * }
    - * - * @param url The url effectively replacing the base url. - * @return The request being built - * @see HttpClient.Builder#baseUrl(String) + * @return The url for this request */ - UrlBuilder url(); + String url(); /** * Add a path segment to the URL. From bbb159394b0fe9807d90448dee4ec4f691b9f854 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Wed, 4 Oct 2023 19:36:17 -0400 Subject: [PATCH 0907/1323] add path to @Client value --- .../main/java/io/avaje/http/api/Client.java | 23 +++++----------- .../main/java/io/avaje/http/api/Cookie.java | 4 +-- .../main/java/io/avaje/http/api/Default.java | 4 +-- .../src/main/java/io/avaje/http/api/Form.java | 4 +-- .../java/io/avaje/http/api/FormParam.java | 4 +-- .../main/java/io/avaje/http/api/Header.java | 4 +-- .../java/io/avaje/http/api/MatrixParam.java | 4 +-- .../src/main/java/io/avaje/http/api/Path.java | 6 +++-- .../java/io/avaje/http/api/QueryParam.java | 4 +-- .../io/avaje/http/api/RequestTimeout.java | 3 +++ .../generator/core/BaseControllerWriter.java | 1 - .../http/generator/core/ControllerReader.java | 6 ++--- .../http/generator/core/WebAPIPrism.java | 17 ++++++++++++ .../http/generator/core/package-info.java | 26 ++++++++++++++----- 14 files changed, 67 insertions(+), 43 deletions(-) create mode 100644 http-generator-core/src/main/java/io/avaje/http/generator/core/WebAPIPrism.java diff --git a/http-api/src/main/java/io/avaje/http/api/Client.java b/http-api/src/main/java/io/avaje/http/api/Client.java index 334cf65fe..a3409a353 100644 --- a/http-api/src/main/java/io/avaje/http/api/Client.java +++ b/http-api/src/main/java/io/avaje/http/api/Client.java @@ -22,25 +22,14 @@ * } * * } - * - *

    Client.Import

    - * - *

    When the client interface already exists in another module we use Client.Import - * to generate the client. - * - *

    Specify the @Client.Import on the package or class to refer to the client - * interface we want to generate. - * - *

    {@code
    - * @Client.Import(types = OtherApi.class)
    - * package org.example;
    - *
    - * }
    */ -@Target(value = TYPE) -@Retention(value = RUNTIME) +@Target(TYPE) +@Retention(RUNTIME) public @interface Client { + /** Specify the path mapping request to the controller. */ + String value() default ""; + /** * Flag to set whether to generate a Client Implementation. Set false if the interface exists merely to be extended by * other client interfaces @@ -57,7 +46,7 @@ * * } */ - @Target(value = {TYPE, PACKAGE}) + @Target({TYPE, PACKAGE}) @Retention(RUNTIME) @interface Import { diff --git a/http-api/src/main/java/io/avaje/http/api/Cookie.java b/http-api/src/main/java/io/avaje/http/api/Cookie.java index f28c0041c..32970b562 100644 --- a/http-api/src/main/java/io/avaje/http/api/Cookie.java +++ b/http-api/src/main/java/io/avaje/http/api/Cookie.java @@ -14,8 +14,8 @@ *

    * */ -@Target(value={PARAMETER, FIELD}) -@Retention(value=RUNTIME) +@Target({PARAMETER, FIELD}) +@Retention(RUNTIME) public @interface Cookie { /** diff --git a/http-api/src/main/java/io/avaje/http/api/Default.java b/http-api/src/main/java/io/avaje/http/api/Default.java index 3dc421744..e66b52acf 100644 --- a/http-api/src/main/java/io/avaje/http/api/Default.java +++ b/http-api/src/main/java/io/avaje/http/api/Default.java @@ -21,8 +21,8 @@ * * } */ -@Target(value = {PARAMETER, FIELD}) -@Retention(value = RUNTIME) +@Target({PARAMETER, FIELD}) +@Retention(RUNTIME) public @interface Default { /** The default values. */ diff --git a/http-api/src/main/java/io/avaje/http/api/Form.java b/http-api/src/main/java/io/avaje/http/api/Form.java index 75dc4b16a..296e1ba13 100644 --- a/http-api/src/main/java/io/avaje/http/api/Form.java +++ b/http-api/src/main/java/io/avaje/http/api/Form.java @@ -66,8 +66,8 @@ * * } */ -@Target(value={PARAMETER,METHOD}) -@Retention(value=RUNTIME) +@Target({PARAMETER,METHOD}) +@Retention(RUNTIME) public @interface Form { } diff --git a/http-api/src/main/java/io/avaje/http/api/FormParam.java b/http-api/src/main/java/io/avaje/http/api/FormParam.java index 9605a2463..5810c630b 100644 --- a/http-api/src/main/java/io/avaje/http/api/FormParam.java +++ b/http-api/src/main/java/io/avaje/http/api/FormParam.java @@ -10,8 +10,8 @@ /** * Marks a method parameter to be a form parameter. */ -@Target(value={PARAMETER,FIELD}) -@Retention(value=RUNTIME) +@Target({PARAMETER,FIELD}) +@Retention(RUNTIME) public @interface FormParam { /** diff --git a/http-api/src/main/java/io/avaje/http/api/Header.java b/http-api/src/main/java/io/avaje/http/api/Header.java index aa003cf9a..594dc3661 100644 --- a/http-api/src/main/java/io/avaje/http/api/Header.java +++ b/http-api/src/main/java/io/avaje/http/api/Header.java @@ -22,8 +22,8 @@ * * } */ -@Target(value={PARAMETER,FIELD}) -@Retention(value=RUNTIME) +@Target({PARAMETER,FIELD}) +@Retention(RUNTIME) public @interface Header { /** diff --git a/http-api/src/main/java/io/avaje/http/api/MatrixParam.java b/http-api/src/main/java/io/avaje/http/api/MatrixParam.java index 71d0ad500..97560e899 100644 --- a/http-api/src/main/java/io/avaje/http/api/MatrixParam.java +++ b/http-api/src/main/java/io/avaje/http/api/MatrixParam.java @@ -7,8 +7,8 @@ import java.lang.annotation.Target; /** Marks a method parameter to be a matrix parameter. */ -@Target(value = {PARAMETER}) -@Retention(value = RUNTIME) +@Target({PARAMETER}) +@Retention(RUNTIME) public @interface MatrixParam { /** diff --git a/http-api/src/main/java/io/avaje/http/api/Path.java b/http-api/src/main/java/io/avaje/http/api/Path.java index 59b97a3e2..d9ca96a91 100644 --- a/http-api/src/main/java/io/avaje/http/api/Path.java +++ b/http-api/src/main/java/io/avaje/http/api/Path.java @@ -3,6 +3,8 @@ import java.lang.annotation.Retention; import java.lang.annotation.Target; +import static java.lang.annotation.ElementType.MODULE; +import static java.lang.annotation.ElementType.PACKAGE; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; @@ -26,8 +28,8 @@ * include a path as well. *

    */ -@Target(value=TYPE) -@Retention(value=RUNTIME) +@Target({TYPE, PACKAGE, MODULE}) +@Retention(RUNTIME) public @interface Path { String value(); } diff --git a/http-api/src/main/java/io/avaje/http/api/QueryParam.java b/http-api/src/main/java/io/avaje/http/api/QueryParam.java index 5337d7850..d95b5b2af 100644 --- a/http-api/src/main/java/io/avaje/http/api/QueryParam.java +++ b/http-api/src/main/java/io/avaje/http/api/QueryParam.java @@ -10,8 +10,8 @@ /** * Marks a method parameter to be a query parameter. */ -@Target(value={PARAMETER,FIELD}) -@Retention(value=RUNTIME) +@Target({PARAMETER,FIELD}) +@Retention(RUNTIME) public @interface QueryParam { /** diff --git a/http-api/src/main/java/io/avaje/http/api/RequestTimeout.java b/http-api/src/main/java/io/avaje/http/api/RequestTimeout.java index 201b21865..5525e07bf 100644 --- a/http-api/src/main/java/io/avaje/http/api/RequestTimeout.java +++ b/http-api/src/main/java/io/avaje/http/api/RequestTimeout.java @@ -23,7 +23,10 @@ @Target(METHOD) @Retention(RUNTIME) public @interface RequestTimeout { + + /** How long the timeout should be */ long value(); + /** Unit of time of the timeout value */ ChronoUnit chronoUnit() default ChronoUnit.MILLIS; } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseControllerWriter.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseControllerWriter.java index aa6479278..7f9053116 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseControllerWriter.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseControllerWriter.java @@ -5,7 +5,6 @@ import javax.tools.JavaFileObject; import java.io.IOException; import java.io.Writer; -import java.util.Map; /** * Common controller writer. diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java index f6c1667f3..822933cda 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java @@ -152,7 +152,7 @@ private Optional findAnnotation(Function> func) { } Optional findMethodAnnotation(Function> func, ExecutableElement element) { - for (final ExecutableElement interfaceMethod : interfaceMethods) { + for (final var interfaceMethod : interfaceMethods) { if (matchMethod(interfaceMethod, element)) { final var annotation = func.apply(interfaceMethod); if (annotation.isPresent()) { @@ -318,8 +318,8 @@ public List openApiResponses() { public String path() { - return findAnnotation(ControllerPrism::getOptionalOn) - .map(ControllerPrism::value) + return findAnnotation(WebAPIPrism::getOptionalOn) + .map(WebAPIPrism::value) .filter(not(String::isBlank)) .or(() -> findAnnotation(PathPrism::getOptionalOn).map(PathPrism::value)) .map(Util::trimPath) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/WebAPIPrism.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/WebAPIPrism.java new file mode 100644 index 000000000..b68302c49 --- /dev/null +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/WebAPIPrism.java @@ -0,0 +1,17 @@ +package io.avaje.http.generator.core; + +import java.util.Optional; + +import javax.lang.model.element.Element; + +public interface WebAPIPrism { + + String value(); + + static Optional getOptionalOn(Element e) { + + return Optional.empty() + .or(() -> ControllerPrism.getOptionalOn(e)) + .or(() -> ClientPrism.getOptionalOn(e)); + } +} diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/package-info.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/package-info.java index 4149cab07..815cb3169 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/package-info.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/package-info.java @@ -1,5 +1,8 @@ /** Generate the prisms to access annotation info */ -@GeneratePrism(value = io.avaje.http.api.Controller.class, publicAccess = true) +@GeneratePrism( + value = io.avaje.http.api.Controller.class, + publicAccess = true, + superInterfaces = WebAPIPrism.class) @GeneratePrism(value = io.avaje.http.api.BeanParam.class, publicAccess = true) @GeneratePrism(value = io.avaje.http.api.Ignore.class, publicAccess = true) @GeneratePrism(value = io.avaje.http.api.QueryParam.class, publicAccess = true) @@ -25,14 +28,25 @@ @GeneratePrism(value = io.swagger.v3.oas.annotations.OpenAPIDefinition.class, publicAccess = true) @GeneratePrism(value = io.swagger.v3.oas.annotations.tags.Tag.class, publicAccess = true) @GeneratePrism(value = io.swagger.v3.oas.annotations.tags.Tags.class, publicAccess = true) -@GeneratePrism(value = io.swagger.v3.oas.annotations.security.SecurityScheme.class, publicAccess = true) -@GeneratePrism(value = io.swagger.v3.oas.annotations.security.SecuritySchemes.class, publicAccess = true) -@GeneratePrism(value = io.swagger.v3.oas.annotations.security.SecurityRequirement.class, publicAccess = true) -@GeneratePrism(value = io.swagger.v3.oas.annotations.security.SecurityRequirements.class, publicAccess = true) +@GeneratePrism( + value = io.swagger.v3.oas.annotations.security.SecurityScheme.class, + publicAccess = true) +@GeneratePrism( + value = io.swagger.v3.oas.annotations.security.SecuritySchemes.class, + publicAccess = true) +@GeneratePrism( + value = io.swagger.v3.oas.annotations.security.SecurityRequirement.class, + publicAccess = true) +@GeneratePrism( + value = io.swagger.v3.oas.annotations.security.SecurityRequirements.class, + publicAccess = true) @GeneratePrism(value = io.avaje.http.api.OpenAPIResponse.class, publicAccess = true) @GeneratePrism(value = io.avaje.http.api.OpenAPIResponses.class, publicAccess = true) @GeneratePrism(value = io.swagger.v3.oas.annotations.Hidden.class, publicAccess = true) -@GeneratePrism(value = io.avaje.http.api.Client.class, publicAccess = true) +@GeneratePrism( + value = io.avaje.http.api.Client.class, + publicAccess = true, + superInterfaces = WebAPIPrism.class) @GeneratePrism(value = io.avaje.http.api.Client.Import.class, publicAccess = true) @GeneratePrism(value = io.avaje.http.api.RequestTimeout.class, publicAccess = true) package io.avaje.http.generator.core; From 3e44b4a786d8b511878c69441d1dc8791ab0c416 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Wed, 4 Oct 2023 19:41:31 -0400 Subject: [PATCH 0908/1323] Update package-info.java --- .../java/io/avaje/http/generator/core/package-info.java | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/package-info.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/package-info.java index 815cb3169..fa52792d0 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/package-info.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/package-info.java @@ -3,10 +3,13 @@ value = io.avaje.http.api.Controller.class, publicAccess = true, superInterfaces = WebAPIPrism.class) +@GeneratePrism( + value = io.avaje.http.api.Client.class, + publicAccess = true, + superInterfaces = WebAPIPrism.class) @GeneratePrism(value = io.avaje.http.api.BeanParam.class, publicAccess = true) @GeneratePrism(value = io.avaje.http.api.Ignore.class, publicAccess = true) @GeneratePrism(value = io.avaje.http.api.QueryParam.class, publicAccess = true) -@GeneratePrism(value = io.avaje.http.api.Client.class, publicAccess = true) @GeneratePrism(value = io.avaje.http.api.Cookie.class, publicAccess = true) @GeneratePrism(value = io.avaje.http.api.BodyString.class, publicAccess = true) @GeneratePrism(value = io.avaje.http.api.Default.class, publicAccess = true) @@ -43,10 +46,6 @@ @GeneratePrism(value = io.avaje.http.api.OpenAPIResponse.class, publicAccess = true) @GeneratePrism(value = io.avaje.http.api.OpenAPIResponses.class, publicAccess = true) @GeneratePrism(value = io.swagger.v3.oas.annotations.Hidden.class, publicAccess = true) -@GeneratePrism( - value = io.avaje.http.api.Client.class, - publicAccess = true, - superInterfaces = WebAPIPrism.class) @GeneratePrism(value = io.avaje.http.api.Client.Import.class, publicAccess = true) @GeneratePrism(value = io.avaje.http.api.RequestTimeout.class, publicAccess = true) package io.avaje.http.generator.core; From 1dcb9e47f4993c62eb857f51a7f99087f9bfc68f Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Wed, 4 Oct 2023 20:42:24 -0400 Subject: [PATCH 0909/1323] contextPath --- .../http/generator/core/BaseProcessor.java | 35 +++++++++++++++++-- .../http/generator/core/ControllerReader.java | 20 +++++++---- .../generator/core/ProcessingContext.java | 4 +++ pom.xml | 2 +- tests/test-nima-jsonb/.classpath | 15 +++++++- .../org/example/path/PathTestController.java | 17 +++++++++ .../java/org/example/path/package-info.java | 5 +++ 7 files changed, 88 insertions(+), 10 deletions(-) create mode 100644 tests/test-nima-jsonb/src/main/java/org/example/path/PathTestController.java create mode 100644 tests/test-nima-jsonb/src/main/java/org/example/path/package-info.java diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java index 050aa4f9d..cb81b495a 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java @@ -1,7 +1,11 @@ package io.avaje.http.generator.core; import static io.avaje.http.generator.core.ProcessingContext.*; +import static java.util.stream.Collectors.toMap; + import java.io.IOException; +import java.util.HashMap; +import java.util.Map; import java.util.Set; import javax.annotation.processing.AbstractProcessor; import javax.annotation.processing.ProcessingEnvironment; @@ -10,10 +14,15 @@ import javax.lang.model.SourceVersion; import javax.lang.model.element.Element; import javax.lang.model.element.TypeElement; +import javax.lang.model.util.ElementFilter; @SupportedOptions({"useJavax", "useSingleton", "instrumentRequests","disableDirectWrites"}) public abstract class BaseProcessor extends AbstractProcessor { + String contextPathString; + + Map packagePaths= new HashMap<>(); + @Override public SourceVersion getSupportedSourceVersion() { return SourceVersion.latest(); @@ -21,7 +30,7 @@ public SourceVersion getSupportedSourceVersion() { @Override public Set getSupportedAnnotationTypes() { - return Set.of(ControllerPrism.PRISM_TYPE, OpenAPIDefinitionPrism.PRISM_TYPE); + return Set.of(PathPrism.PRISM_TYPE, ControllerPrism.PRISM_TYPE, OpenAPIDefinitionPrism.PRISM_TYPE); } @Override @@ -36,6 +45,22 @@ public synchronized void init(ProcessingEnvironment processingEnv) { @Override public boolean process(Set annotations, RoundEnvironment round) { + var pathElements = round.getElementsAnnotatedWith(typeElement(PathPrism.PRISM_TYPE)); + + if (contextPathString == null) { + contextPathString = + ElementFilter.modulesIn(pathElements).stream() + .map(PathPrism::getInstanceOn) + .map(PathPrism::value) + .findFirst() + .orElse(""); + } + packagePaths.putAll( + ElementFilter.packagesIn(pathElements).stream() + .collect( + toMap( + p -> p.getQualifiedName().toString(), + p -> PathPrism.getInstanceOn(p).value()))); if (isOpenApiAvailable()) { readOpenApiDefinition(round); @@ -94,7 +119,13 @@ private void writeOpenAPI() { private void writeAdapter(Element controller) { if (controller instanceof TypeElement) { - final ControllerReader reader = new ControllerReader((TypeElement) controller); + var contextPath = + Util.combinePath( + contextPathString, + packagePaths.get( + elements().getPackageOf(controller).getQualifiedName().toString())); + + final ControllerReader reader = new ControllerReader((TypeElement) controller, contextPath); reader.read(true); try { writeControllerAdapter(reader); diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java index 822933cda..3aebc0126 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java @@ -41,6 +41,7 @@ public final class ControllerReader { private final Set staticImportTypes = new TreeSet<>(); private final Set importTypes = new TreeSet<>(); private final List apiResponses; + private final String contextPath; /** The producesPrism media type for the controller. Null implies JSON. */ private final String producesPrism; @@ -56,7 +57,12 @@ public final class ControllerReader { private final boolean hasInstrument; public ControllerReader(TypeElement beanType) { + this(beanType, ""); + } + + public ControllerReader(TypeElement beanType, String contextPath) { this.beanType = beanType; + this.contextPath=contextPath; this.interfaces = initInterfaces(beanType); this.interfaceMethods = initInterfaceMethods(); this.roles = buildRoles(); @@ -318,12 +324,14 @@ public List openApiResponses() { public String path() { - return findAnnotation(WebAPIPrism::getOptionalOn) - .map(WebAPIPrism::value) - .filter(not(String::isBlank)) - .or(() -> findAnnotation(PathPrism::getOptionalOn).map(PathPrism::value)) - .map(Util::trimPath) - .orElse(null); + var path = + findAnnotation(WebAPIPrism::getOptionalOn) + .map(WebAPIPrism::value) + .filter(not(String::isBlank)) + .or(() -> findAnnotation(PathPrism::getOptionalOn).map(PathPrism::value)) + .map(Util::trimPath) + .orElse(null); + return Util.combinePath(contextPath, path); } public void addImportType(String rawType) { diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java index 57ce557c1..4646a0834 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java @@ -287,4 +287,8 @@ static ModuleElement getModuleElement(Element e) { } return getModuleElement(e.getEnclosingElement()); } + + static Elements elements() { + return CTX.get().elementUtils; + } } diff --git a/pom.xml b/pom.xml index 86731fb02..adcda2bdf 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ true 2.2.8 2.14.2 - 1.13 + 1.16 ${project.build.directory}${file.separator}module-info.shade diff --git a/tests/test-nima-jsonb/.classpath b/tests/test-nima-jsonb/.classpath index cb7d8e80b..b636cdf6d 100644 --- a/tests/test-nima-jsonb/.classpath +++ b/tests/test-nima-jsonb/.classpath @@ -13,7 +13,7 @@ - + @@ -23,6 +23,19 @@ + + + + + + + + + + + + + diff --git a/tests/test-nima-jsonb/src/main/java/org/example/path/PathTestController.java b/tests/test-nima-jsonb/src/main/java/org/example/path/PathTestController.java new file mode 100644 index 000000000..d1787fdf9 --- /dev/null +++ b/tests/test-nima-jsonb/src/main/java/org/example/path/PathTestController.java @@ -0,0 +1,17 @@ +package org.example.path; + +import io.avaje.http.api.Controller; +import io.avaje.http.api.Get; +import io.avaje.http.api.Path; +import io.avaje.http.api.Produces; + +@Path("test") +@Controller +public class PathTestController { + + @Produces("text/plain") + @Get + String hello() { + return "hi"; + } +} diff --git a/tests/test-nima-jsonb/src/main/java/org/example/path/package-info.java b/tests/test-nima-jsonb/src/main/java/org/example/path/package-info.java new file mode 100644 index 000000000..8db032c99 --- /dev/null +++ b/tests/test-nima-jsonb/src/main/java/org/example/path/package-info.java @@ -0,0 +1,5 @@ + +@Path("package-info") +package org.example.path; + +import io.avaje.http.api.Path; From 125447dd702bf0f8a68aa3586201ebacc27e5220 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Wed, 4 Oct 2023 20:58:14 -0400 Subject: [PATCH 0910/1323] Update Path.java --- .../src/main/java/io/avaje/http/api/Path.java | 27 +++++++++---------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/http-api/src/main/java/io/avaje/http/api/Path.java b/http-api/src/main/java/io/avaje/http/api/Path.java index d9ca96a91..dcf42b1ba 100644 --- a/http-api/src/main/java/io/avaje/http/api/Path.java +++ b/http-api/src/main/java/io/avaje/http/api/Path.java @@ -9,24 +9,23 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME; /** - * Specify the path mapping request to the controller. + * Specify the path mapping request to a controller. When placed on a package-info or a module-info + * file, all routes in the package/module will have value added as a prefix * *
    {@code
    - *
    - *  @Controller
    - *  @Path("/customers")
    - *  class CustomerController {
    - *    ...
    - *  }
    - *
    + * @Controller
    + * @Path("/customers")
    + * class CustomerController {
    + *   ...
    + * }
      * }
    + *
    {@code
    + * @Path("/customers") // all routes in this module will have a customers prefix
    + * module example.module {
    + *   ...
    + * }
      *
    - * 

    JAX-RS note

    - *

    - * Note that unlike JAX-RS we only use @Path on the controller type and don't - * use it on the methods. This is because the @Get, @Post etc annotations - * include a path as well. - *

    + * }
    */ @Target({TYPE, PACKAGE, MODULE}) @Retention(RUNTIME) From 9805e7846785a5eb35760bc7072d83deabd2204d Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Wed, 4 Oct 2023 21:23:20 -0400 Subject: [PATCH 0911/1323] nested packages --- .../http/generator/core/BaseProcessor.java | 21 +++++++++++++++---- .../example/path/nest/PathNestController.java | 17 +++++++++++++++ .../org/example/path/nest/package-info.java | 5 +++++ 3 files changed, 39 insertions(+), 4 deletions(-) create mode 100644 tests/test-nima-jsonb/src/main/java/org/example/path/nest/PathNestController.java create mode 100644 tests/test-nima-jsonb/src/main/java/org/example/path/nest/package-info.java diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java index cb81b495a..a83cbe74e 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java @@ -1,12 +1,20 @@ package io.avaje.http.generator.core; -import static io.avaje.http.generator.core.ProcessingContext.*; +import static io.avaje.http.generator.core.ProcessingContext.doc; +import static io.avaje.http.generator.core.ProcessingContext.elements; +import static io.avaje.http.generator.core.ProcessingContext.isOpenApiAvailable; +import static io.avaje.http.generator.core.ProcessingContext.logError; +import static io.avaje.http.generator.core.ProcessingContext.typeElement; import static java.util.stream.Collectors.toMap; import java.io.IOException; import java.util.HashMap; +import java.util.HashSet; import java.util.Map; import java.util.Set; +import java.util.TreeMap; +import java.util.Map.Entry; + import javax.annotation.processing.AbstractProcessor; import javax.annotation.processing.ProcessingEnvironment; import javax.annotation.processing.RoundEnvironment; @@ -21,7 +29,7 @@ public abstract class BaseProcessor extends AbstractProcessor { String contextPathString; - Map packagePaths= new HashMap<>(); + Map packagePaths= new TreeMap<>(); @Override public SourceVersion getSupportedSourceVersion() { @@ -119,11 +127,16 @@ private void writeOpenAPI() { private void writeAdapter(Element controller) { if (controller instanceof TypeElement) { + + var packageFQN = elements().getPackageOf(controller).getQualifiedName().toString(); var contextPath = Util.combinePath( contextPathString, - packagePaths.get( - elements().getPackageOf(controller).getQualifiedName().toString())); + packagePaths.entrySet().stream() + .filter(k -> packageFQN.contains(k.getKey())) + .map(Entry::getValue) + .reduce(Util::combinePath) + .orElse(null)); final ControllerReader reader = new ControllerReader((TypeElement) controller, contextPath); reader.read(true); diff --git a/tests/test-nima-jsonb/src/main/java/org/example/path/nest/PathNestController.java b/tests/test-nima-jsonb/src/main/java/org/example/path/nest/PathNestController.java new file mode 100644 index 000000000..bdd49b65e --- /dev/null +++ b/tests/test-nima-jsonb/src/main/java/org/example/path/nest/PathNestController.java @@ -0,0 +1,17 @@ +package org.example.path.nest; + +import io.avaje.http.api.Controller; +import io.avaje.http.api.Get; +import io.avaje.http.api.Path; +import io.avaje.http.api.Produces; + +@Path("test") +@Controller +public class PathNestController { + + @Produces("text/plain") + @Get + String hello() { + return "hi"; + } +} diff --git a/tests/test-nima-jsonb/src/main/java/org/example/path/nest/package-info.java b/tests/test-nima-jsonb/src/main/java/org/example/path/nest/package-info.java new file mode 100644 index 000000000..73f306ff6 --- /dev/null +++ b/tests/test-nima-jsonb/src/main/java/org/example/path/nest/package-info.java @@ -0,0 +1,5 @@ + +@Path("nested") +package org.example.path.nest; + +import io.avaje.http.api.Path; From 58e076e2c69328e193efa3fb6bbad1587be6df1d Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Wed, 4 Oct 2023 21:29:26 -0400 Subject: [PATCH 0912/1323] Update BaseProcessor.java --- .../java/io/avaje/http/generator/core/BaseProcessor.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java index a83cbe74e..d8f1ce2d0 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java @@ -9,11 +9,9 @@ import java.io.IOException; import java.util.HashMap; -import java.util.HashSet; import java.util.Map; -import java.util.Set; -import java.util.TreeMap; import java.util.Map.Entry; +import java.util.Set; import javax.annotation.processing.AbstractProcessor; import javax.annotation.processing.ProcessingEnvironment; @@ -29,7 +27,7 @@ public abstract class BaseProcessor extends AbstractProcessor { String contextPathString; - Map packagePaths= new TreeMap<>(); + Map packagePaths= new HashMap<>(); @Override public SourceVersion getSupportedSourceVersion() { From 24220a0ea6301c639f48565aea0c0b5be27bbfd2 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Wed, 4 Oct 2023 22:52:50 -0400 Subject: [PATCH 0913/1323] Update BaseProcessor.java --- .../main/java/io/avaje/http/generator/core/BaseProcessor.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java index d8f1ce2d0..b898ddabe 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java @@ -131,7 +131,7 @@ private void writeAdapter(Element controller) { Util.combinePath( contextPathString, packagePaths.entrySet().stream() - .filter(k -> packageFQN.contains(k.getKey())) + .filter(k -> packageFQN.startsWith(k.getKey())) .map(Entry::getValue) .reduce(Util::combinePath) .orElse(null)); From 35d486ad89bfe9b34173eda29544733a61014bf5 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Wed, 4 Oct 2023 23:25:31 -0400 Subject: [PATCH 0914/1323] Update DHttpClientRequest.java --- .../src/main/java/io/avaje/http/client/DHttpClientRequest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/http-client/src/main/java/io/avaje/http/client/DHttpClientRequest.java b/http-client/src/main/java/io/avaje/http/client/DHttpClientRequest.java index 382723262..a6c22bdf6 100644 --- a/http-client/src/main/java/io/avaje/http/client/DHttpClientRequest.java +++ b/http-client/src/main/java/io/avaje/http/client/DHttpClientRequest.java @@ -47,7 +47,6 @@ class DHttpClientRequest implements HttpClientRequest, HttpClientResponse { private Map> formParams; private Map> headers; - private Map> queryParams; private boolean bodyFormEncoded; private long responseTimeNanos; From b7993ccdf8c2fba4e3144051acce24dea9f8546e Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Thu, 5 Oct 2023 22:24:38 +1300 Subject: [PATCH 0915/1323] HttpClientRequest.method() + format + tidy --- .../avaje/http/client/DHttpClientRequest.java | 3 +- .../avaje/http/client/HttpClientRequest.java | 7 +++ .../http/generator/core/BaseProcessor.java | 56 +++++++------------ .../http/generator/core/ControllerReader.java | 41 ++++++-------- .../http/generator/core/package-info.java | 26 ++------- 5 files changed, 53 insertions(+), 80 deletions(-) diff --git a/http-client/src/main/java/io/avaje/http/client/DHttpClientRequest.java b/http-client/src/main/java/io/avaje/http/client/DHttpClientRequest.java index a6c22bdf6..9e6526eb8 100644 --- a/http-client/src/main/java/io/avaje/http/client/DHttpClientRequest.java +++ b/http-client/src/main/java/io/avaje/http/client/DHttpClientRequest.java @@ -70,6 +70,7 @@ class DHttpClientRequest implements HttpClientRequest, HttpClientResponse { this.errorMapper = context.errorMapper(); } + @Override public String method() { return method; } @@ -808,7 +809,7 @@ boolean isSkipAuthToken() { return skipAuthToken; } -private class ListenerEvent implements RequestListener.Event { + private class ListenerEvent implements RequestListener.Event { @Override public long responseTimeMicros() { diff --git a/http-client/src/main/java/io/avaje/http/client/HttpClientRequest.java b/http-client/src/main/java/io/avaje/http/client/HttpClientRequest.java index a760e2e61..7e6ed9768 100644 --- a/http-client/src/main/java/io/avaje/http/client/HttpClientRequest.java +++ b/http-client/src/main/java/io/avaje/http/client/HttpClientRequest.java @@ -179,6 +179,13 @@ public interface HttpClientRequest { */ HttpClientRequest url(String url); + /** + * The Http Verb (GET, POST, PUT etc) of this request. + * + * @return The Http Verb of this request. + */ + String method(); + /** * The URL for this request including the query parameters. * diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java index b898ddabe..595014b7a 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java @@ -25,9 +25,9 @@ @SupportedOptions({"useJavax", "useSingleton", "instrumentRequests","disableDirectWrites"}) public abstract class BaseProcessor extends AbstractProcessor { - String contextPathString; + protected String contextPathString; - Map packagePaths= new HashMap<>(); + protected Map packagePaths = new HashMap<>(); @Override public SourceVersion getSupportedSourceVersion() { @@ -50,7 +50,6 @@ public synchronized void init(ProcessingEnvironment processingEnv) { @Override public boolean process(Set annotations, RoundEnvironment round) { - var pathElements = round.getElementsAnnotatedWith(typeElement(PathPrism.PRISM_TYPE)); if (contextPathString == null) { @@ -74,9 +73,7 @@ public boolean process(Set annotations, RoundEnvironment readSecuritySchemes(round); } - final Set controllers = - round.getElementsAnnotatedWith(typeElement(ControllerPrism.PRISM_TYPE)); - for (final Element controller : controllers) { + for (final Element controller : round.getElementsAnnotatedWith(typeElement(ControllerPrism.PRISM_TYPE))) { writeAdapter(controller); } @@ -87,35 +84,26 @@ public boolean process(Set annotations, RoundEnvironment } private void readOpenApiDefinition(RoundEnvironment round) { - final Set elements = - round.getElementsAnnotatedWith(typeElement(OpenAPIDefinitionPrism.PRISM_TYPE)); - for (final Element element : elements) { + for (final Element element : round.getElementsAnnotatedWith(typeElement(OpenAPIDefinitionPrism.PRISM_TYPE))) { doc().readApiDefinition(element); } } private void readTagDefinitions(RoundEnvironment round) { - Set elements = - round.getElementsAnnotatedWith(typeElement(TagPrism.PRISM_TYPE)); - for (final Element element : elements) { + for (final Element element : round.getElementsAnnotatedWith(typeElement(TagPrism.PRISM_TYPE))) { doc().addTagDefinition(element); } - - elements = round.getElementsAnnotatedWith(typeElement(TagsPrism.PRISM_TYPE)); - for (final Element element : elements) { + for (final Element element : round.getElementsAnnotatedWith(typeElement(TagsPrism.PRISM_TYPE))) { doc().addTagsDefinition(element); } } private void readSecuritySchemes(RoundEnvironment round) { - Set elements = round.getElementsAnnotatedWith(typeElement(SecuritySchemePrism.PRISM_TYPE)); - for (final Element element : elements) { - doc().addSecurityScheme(element); + for (final Element element : round.getElementsAnnotatedWith(typeElement(SecuritySchemePrism.PRISM_TYPE))) { + doc().addSecurityScheme(element); } - - elements = round.getElementsAnnotatedWith(typeElement(SecuritySchemesPrism.PRISM_TYPE)); - for (final Element element : elements) { - doc().addSecuritySchemes(element); + for (final Element element : round.getElementsAnnotatedWith(typeElement(SecuritySchemesPrism.PRISM_TYPE))) { + doc().addSecuritySchemes(element); } } @@ -125,28 +113,26 @@ private void writeOpenAPI() { private void writeAdapter(Element controller) { if (controller instanceof TypeElement) { - - var packageFQN = elements().getPackageOf(controller).getQualifiedName().toString(); - var contextPath = - Util.combinePath( - contextPathString, - packagePaths.entrySet().stream() - .filter(k -> packageFQN.startsWith(k.getKey())) - .map(Entry::getValue) - .reduce(Util::combinePath) - .orElse(null)); - - final ControllerReader reader = new ControllerReader((TypeElement) controller, contextPath); + final var packageFQN = elements().getPackageOf(controller).getQualifiedName().toString(); + final var contextPath = Util.combinePath(contextPathString, packagePath(packageFQN)); + final var reader = new ControllerReader((TypeElement) controller, contextPath); reader.read(true); try { writeControllerAdapter(reader); } catch (final Throwable e) { - e.printStackTrace(); logError(reader.beanType(), "Failed to write $Route class " + e); } } } + private String packagePath(String packageFQN) { + return packagePaths.entrySet().stream() + .filter(k -> packageFQN.startsWith(k.getKey())) + .map(Entry::getValue) + .reduce(Util::combinePath) + .orElse(null); + } + /** * Write the adapter code for the given controller. */ diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java index 3aebc0126..3914821cc 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java @@ -11,7 +11,6 @@ import java.util.ArrayList; import java.util.HashSet; -import java.util.Iterator; import java.util.List; import java.util.Optional; import java.util.Set; @@ -27,6 +26,7 @@ import javax.lang.model.type.TypeKind; import javax.lang.model.type.TypeMirror; import javax.lang.model.util.ElementFilter; + /** * Reads the type information for the Controller (bean). */ @@ -62,7 +62,7 @@ public ControllerReader(TypeElement beanType) { public ControllerReader(TypeElement beanType, String contextPath) { this.beanType = beanType; - this.contextPath=contextPath; + this.contextPath = contextPath; this.interfaces = initInterfaces(beanType); this.interfaceMethods = initInterfaceMethods(); this.roles = buildRoles(); @@ -73,10 +73,10 @@ public ControllerReader(TypeElement beanType, String contextPath) { this.producesPrism = initProduces(); this.apiResponses = buildApiResponses(); hasInstrument = - instrumentAllWebMethods() - || findAnnotation(InstrumentServerContextPrism::getOptionalOn) - .map(x -> true) - .orElse(false); + instrumentAllWebMethods() + || findAnnotation(InstrumentServerContextPrism::getOptionalOn) + .map(x -> true) + .orElse(false); } private List buildApiResponses() { @@ -89,11 +89,10 @@ private List buildApiResponses() { } private void buildApiResponsesFor(Element element, ArrayList responses) { - OpenAPIResponsesPrism.getOptionalOn(element).stream() - .map(OpenAPIResponsesPrism::value) - .flatMap(List::stream) - .forEach(responses::add); + .map(OpenAPIResponsesPrism::value) + .flatMap(List::stream) + .forEach(responses::add); responses.addAll(OpenAPIResponsePrism.getAllInstancesOn(element)); } @@ -182,7 +181,6 @@ private boolean initDocHidden() { } private boolean initHasValid() { - return findAnnotation(ValidPrism::getOptionalOn).isPresent(); } @@ -263,7 +261,7 @@ private void readSuper(TypeElement beanType) { final TypeMirror superclass = beanType.getSuperclass(); if (superclass.getKind() != TypeKind.NONE) { final DeclaredType declaredType = (DeclaredType) superclass; - final Element superElement = asElement(superclass); + final TypeElement superElement = asElement(superclass); if (!"java.lang.Object".equals(superElement.toString())) { for (final Element element : superElement.getEnclosedElements()) { if (element.getKind() == ElementKind.METHOD) { @@ -272,17 +270,13 @@ private void readSuper(TypeElement beanType) { readField(element); } } - if (superElement instanceof TypeElement) { - readSuper((TypeElement) superElement); - } + readSuper(superElement); } } } /** * Read methods from interfaces taking into account generics. - * - * @param interfaceElement */ private void readInterfaces(TypeElement interfaceElement) { for (final var element : ElementFilter.methodsIn(interfaceElement.getEnclosedElements())) { @@ -323,14 +317,13 @@ public List openApiResponses() { } public String path() { - var path = - findAnnotation(WebAPIPrism::getOptionalOn) - .map(WebAPIPrism::value) - .filter(not(String::isBlank)) - .or(() -> findAnnotation(PathPrism::getOptionalOn).map(PathPrism::value)) - .map(Util::trimPath) - .orElse(null); + findAnnotation(WebAPIPrism::getOptionalOn) + .map(WebAPIPrism::value) + .filter(not(String::isBlank)) + .or(() -> findAnnotation(PathPrism::getOptionalOn).map(PathPrism::value)) + .map(Util::trimPath) + .orElse(null); return Util.combinePath(contextPath, path); } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/package-info.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/package-info.java index fa52792d0..129ae8cc7 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/package-info.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/package-info.java @@ -1,12 +1,6 @@ /** Generate the prisms to access annotation info */ -@GeneratePrism( - value = io.avaje.http.api.Controller.class, - publicAccess = true, - superInterfaces = WebAPIPrism.class) -@GeneratePrism( - value = io.avaje.http.api.Client.class, - publicAccess = true, - superInterfaces = WebAPIPrism.class) +@GeneratePrism(value = io.avaje.http.api.Controller.class, publicAccess = true, superInterfaces = WebAPIPrism.class) +@GeneratePrism(value = io.avaje.http.api.Client.class, publicAccess = true, superInterfaces = WebAPIPrism.class) @GeneratePrism(value = io.avaje.http.api.BeanParam.class, publicAccess = true) @GeneratePrism(value = io.avaje.http.api.Ignore.class, publicAccess = true) @GeneratePrism(value = io.avaje.http.api.QueryParam.class, publicAccess = true) @@ -31,18 +25,10 @@ @GeneratePrism(value = io.swagger.v3.oas.annotations.OpenAPIDefinition.class, publicAccess = true) @GeneratePrism(value = io.swagger.v3.oas.annotations.tags.Tag.class, publicAccess = true) @GeneratePrism(value = io.swagger.v3.oas.annotations.tags.Tags.class, publicAccess = true) -@GeneratePrism( - value = io.swagger.v3.oas.annotations.security.SecurityScheme.class, - publicAccess = true) -@GeneratePrism( - value = io.swagger.v3.oas.annotations.security.SecuritySchemes.class, - publicAccess = true) -@GeneratePrism( - value = io.swagger.v3.oas.annotations.security.SecurityRequirement.class, - publicAccess = true) -@GeneratePrism( - value = io.swagger.v3.oas.annotations.security.SecurityRequirements.class, - publicAccess = true) +@GeneratePrism(value = io.swagger.v3.oas.annotations.security.SecurityScheme.class, publicAccess = true) +@GeneratePrism(value = io.swagger.v3.oas.annotations.security.SecuritySchemes.class, publicAccess = true) +@GeneratePrism(value = io.swagger.v3.oas.annotations.security.SecurityRequirement.class, publicAccess = true) +@GeneratePrism(value = io.swagger.v3.oas.annotations.security.SecurityRequirements.class, publicAccess = true) @GeneratePrism(value = io.avaje.http.api.OpenAPIResponse.class, publicAccess = true) @GeneratePrism(value = io.avaje.http.api.OpenAPIResponses.class, publicAccess = true) @GeneratePrism(value = io.swagger.v3.oas.annotations.Hidden.class, publicAccess = true) From 9302ef9fe9d93cb0190cd6eda2dcd2e8efbc2bcd Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Thu, 5 Oct 2023 23:05:03 +1300 Subject: [PATCH 0916/1323] [HttpClient] For POST byte[] use BodyContent + tests for returned BodyContent --- .../avaje/http/client/DHttpClientRequest.java | 6 +- .../http/client/RequestListenerTest.java | 62 +++++++++++++++++-- 2 files changed, 61 insertions(+), 7 deletions(-) diff --git a/http-client/src/main/java/io/avaje/http/client/DHttpClientRequest.java b/http-client/src/main/java/io/avaje/http/client/DHttpClientRequest.java index 9e6526eb8..1c2ae9b17 100644 --- a/http-client/src/main/java/io/avaje/http/client/DHttpClientRequest.java +++ b/http-client/src/main/java/io/avaje/http/client/DHttpClientRequest.java @@ -82,6 +82,9 @@ public String url() { @Override public Optional bodyContent() { + if (rawRequestBody != null) { + return Optional.of(new BodyContent(null, rawRequestBody.getBytes(StandardCharsets.UTF_8))); + } return Optional.ofNullable(encodedRequestBody); } @@ -303,7 +306,6 @@ public HttpClientRequest body(Object bean) { @Override public HttpClientRequest body(Object bean, String contentType) { - return body(bean, bean.getClass(), contentType); } @@ -333,7 +335,7 @@ public HttpClientRequest body(String body) { @Override public HttpClientRequest body(byte[] bytes) { - this.body = HttpRequest.BodyPublishers.ofByteArray(bytes); + this.encodedRequestBody = new BodyContent(null, bytes); return this; } diff --git a/http-client/src/test/java/io/avaje/http/client/RequestListenerTest.java b/http-client/src/test/java/io/avaje/http/client/RequestListenerTest.java index 7382d0f3f..f6c44fb10 100644 --- a/http-client/src/test/java/io/avaje/http/client/RequestListenerTest.java +++ b/http-client/src/test/java/io/avaje/http/client/RequestListenerTest.java @@ -3,6 +3,9 @@ import org.junit.jupiter.api.Test; import java.net.http.HttpResponse; +import java.nio.charset.StandardCharsets; +import java.util.List; +import java.util.Map; import static org.assertj.core.api.Assertions.assertThat; @@ -33,12 +36,17 @@ public void response(Event event) { } private HttpClient createClient(TDRequestListener tdRequestListener) { + return createClient(tdRequestListener, new TDReqIntercept()); + } + + private HttpClient createClient(RequestListener tdRequestListener, RequestIntercept intercept) { return HttpClient.builder() .baseUrl(baseUrl) .requestLogging(false) .requestListener(new RequestLogger()) .bodyAdapter(new JacksonBodyAdapter()) .requestListener(tdRequestListener) + .requestIntercept(intercept) .build(); } @@ -56,17 +64,61 @@ void get_no_request_body() { } @Test - void post() { - final TDRequestListener tdRequestListener = new TDRequestListener(true); - final HttpClient client = createClient(tdRequestListener); + void post_bytes() { + var tdRequestListener = new TDRequestListener(true); + var intercept = new TDReqIntercept(); + var httpClient = createClient(tdRequestListener, intercept); - final HttpResponse hres = client.request() + final HttpResponse hres = httpClient.request() + .path("post") + .body("post-request-body".getBytes(StandardCharsets.UTF_8)) + .POST().asString(); + + assertThat(hres.body()).contains("post"); + assertThat(hres.statusCode()).isEqualTo(200); + + assertThat(intercept.method).isEqualTo("POST"); + assertThat(intercept.url).isEqualTo("http://localhost:8889/post"); + assertThat(intercept.bodyContent).isNotNull(); + + var asString = new String(intercept.bodyContent.content(), StandardCharsets.UTF_8); + assertThat(asString).isEqualTo("post-request-body"); + } + + @Test + void post_string() { + var intercept = new TDReqIntercept(); + var httpClient = createClient(event -> {}, intercept); + + final HttpResponse hres = httpClient.request() .path("post") - .body("post-request-body") + .body("post-string-body") .POST().asString(); assertThat(hres.body()).contains("post"); assertThat(hres.statusCode()).isEqualTo(200); + + assertThat(intercept.method).isEqualTo("POST"); + assertThat(intercept.url).isEqualTo("http://localhost:8889/post"); + assertThat(intercept.bodyContent).isNotNull(); + + var asString = new String(intercept.bodyContent.content(), StandardCharsets.UTF_8); + assertThat(asString).isEqualTo("post-string-body"); } + static class TDReqIntercept implements RequestIntercept { + + Map> headers; + String method; + String url; + BodyContent bodyContent; + + @Override + public void beforeRequest(HttpClientRequest request) { + headers = request.headers(); + method = request.method(); + url = request.url(); + bodyContent = request.bodyContent().orElse(null); + } + } } From 574d47729e9ca7524789082a20e7294adb49ec26 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Thu, 5 Oct 2023 23:37:16 +1300 Subject: [PATCH 0917/1323] [HttpClient] Refactor BodyContent to be an interface --- .../http/client/gson/GsonBodyAdapter.java | 5 +- .../http/client/gson/GsonBodyAdapterTest.java | 2 +- .../io/avaje/http/client/BodyContent.java | 51 ++++++++++++------- .../io/avaje/http/client/DBodyContent.java | 43 ++++++++++++++++ .../io/avaje/http/client/DBodyContentS.java | 32 ++++++++++++ .../avaje/http/client/DHttpClientContext.java | 6 +-- .../avaje/http/client/DHttpClientRequest.java | 12 ++--- .../src/main/resources/public/openapi.json | 2 +- 8 files changed, 117 insertions(+), 36 deletions(-) create mode 100644 http-client/src/main/java/io/avaje/http/client/DBodyContent.java create mode 100644 http-client/src/main/java/io/avaje/http/client/DBodyContentS.java diff --git a/http-client-gson-adapter/src/main/java/io/avaje/http/client/gson/GsonBodyAdapter.java b/http-client-gson-adapter/src/main/java/io/avaje/http/client/gson/GsonBodyAdapter.java index 405d7852b..9538edf0b 100644 --- a/http-client-gson-adapter/src/main/java/io/avaje/http/client/gson/GsonBodyAdapter.java +++ b/http-client-gson-adapter/src/main/java/io/avaje/http/client/gson/GsonBodyAdapter.java @@ -5,10 +5,7 @@ import com.google.gson.reflect.TypeToken; import com.google.gson.stream.JsonReader; import com.google.gson.stream.JsonWriter; -import io.avaje.http.client.BodyAdapter; -import io.avaje.http.client.BodyContent; -import io.avaje.http.client.BodyReader; -import io.avaje.http.client.BodyWriter; +import io.avaje.http.client.*; import java.io.*; import java.util.List; diff --git a/http-client-gson-adapter/src/test/java/io/avaje/http/client/gson/GsonBodyAdapterTest.java b/http-client-gson-adapter/src/test/java/io/avaje/http/client/gson/GsonBodyAdapterTest.java index e8ff31587..f5c74284e 100644 --- a/http-client-gson-adapter/src/test/java/io/avaje/http/client/gson/GsonBodyAdapterTest.java +++ b/http-client-gson-adapter/src/test/java/io/avaje/http/client/gson/GsonBodyAdapterTest.java @@ -52,6 +52,6 @@ void listReader() { } BodyContent content(String raw) { - return new BodyContent("not-used", raw.getBytes()); + return BodyContent.of(raw.getBytes()); } } diff --git a/http-client/src/main/java/io/avaje/http/client/BodyContent.java b/http-client/src/main/java/io/avaje/http/client/BodyContent.java index eb4427d09..2f95d166a 100644 --- a/http-client/src/main/java/io/avaje/http/client/BodyContent.java +++ b/http-client/src/main/java/io/avaje/http/client/BodyContent.java @@ -5,40 +5,55 @@ *

    * This is not used for streaming content. */ -public class BodyContent { +public interface BodyContent { - public static final String JSON_UTF8 = "application/json; charset=UTF-8"; + /** + * Create BodyContent with the given byte[] content. + */ + static BodyContent of(byte[] content) { + return new DBodyContent(content); + } - private final String contentType; + /** + * Create BodyContent with the given string content. + */ + static BodyContent of(String content) { + return new DBodyContentS(null, content); + } - private final byte[] content; + /** + * Create BodyContent with the given the content type and string content. + */ + static BodyContent of(String contentType, String content) { + return new DBodyContentS(contentType, content); + } /** - * Create and return as JSON body content given raw content. + * Create BodyContent with the given the content type and byte[] content. */ - public static BodyContent asJson(byte[] content) { - return new BodyContent(JSON_UTF8, content); + static BodyContent of(String contentType, byte[] content) { + return new DBodyContent(contentType, content); } /** - * Create with content type and content. + * Create BodyContent for JSON byte[] content. */ - public BodyContent(String contentType, byte[] content) { - this.contentType = contentType; - this.content = content; + static BodyContent asJson(byte[] content) { + return DBodyContent.asJson(content); } /** * Return the content type. */ - public String contentType() { - return contentType; - } + String contentType(); /** - * Return the raw content. + * Return the content as bytes. */ - public byte[] content() { - return content; - } + byte[] content(); + + /** + * Return the content as UTF8 string. + */ + String contentAsUtf8(); } diff --git a/http-client/src/main/java/io/avaje/http/client/DBodyContent.java b/http-client/src/main/java/io/avaje/http/client/DBodyContent.java new file mode 100644 index 000000000..eec7affaa --- /dev/null +++ b/http-client/src/main/java/io/avaje/http/client/DBodyContent.java @@ -0,0 +1,43 @@ +package io.avaje.http.client; + +import java.nio.charset.StandardCharsets; + +/** + * Bytes based body content. + */ +final class DBodyContent implements BodyContent { + + private static final String JSON_UTF8 = "application/json; charset=UTF-8"; + + private final String contentType; + private final byte[] content; + + static BodyContent asJson(byte[] content) { + return new DBodyContent(JSON_UTF8, content); + } + + DBodyContent(byte[] content) { + this.content = content; + this.contentType = null; + } + + DBodyContent(String contentType, byte[] content) { + this.contentType = contentType; + this.content = content; + } + + @Override + public String contentType() { + return contentType; + } + + @Override + public byte[] content() { + return content; + } + + @Override + public String contentAsUtf8() { + return new String(content, StandardCharsets.UTF_8); + } +} diff --git a/http-client/src/main/java/io/avaje/http/client/DBodyContentS.java b/http-client/src/main/java/io/avaje/http/client/DBodyContentS.java new file mode 100644 index 000000000..c553a3721 --- /dev/null +++ b/http-client/src/main/java/io/avaje/http/client/DBodyContentS.java @@ -0,0 +1,32 @@ +package io.avaje.http.client; + +import java.nio.charset.StandardCharsets; + +/** + * String based body content. + */ +final class DBodyContentS implements BodyContent { + + private final String contentType; + private final String content; + + DBodyContentS(String contentType, String content) { + this.contentType = contentType; + this.content = content; + } + + @Override + public String contentType() { + return contentType; + } + + @Override + public byte[] content() { + return content.getBytes(StandardCharsets.UTF_8); + } + + @Override + public String contentAsUtf8() { + return content; + } +} diff --git a/http-client/src/main/java/io/avaje/http/client/DHttpClientContext.java b/http-client/src/main/java/io/avaje/http/client/DHttpClientContext.java index 82883908e..c06007a5f 100644 --- a/http-client/src/main/java/io/avaje/http/client/DHttpClientContext.java +++ b/http-client/src/main/java/io/avaje/http/client/DHttpClientContext.java @@ -173,14 +173,14 @@ BodyContent readErrorContent(boolean responseAsBytes, HttpResponse httpRespon final String contentType = getContentType(httpResponse); final Object body = httpResponse.body(); if (body instanceof String) { - return new BodyContent(contentType, ((String) body).getBytes(StandardCharsets.UTF_8)); + return BodyContent.of(contentType, (String) body); } if (body instanceof Stream) { var sb = new StringBuilder(50); for (Object line : ((Stream) body).collect(Collectors.toList())) { sb.append(line); } - return new BodyContent(contentType, sb.toString().getBytes(StandardCharsets.UTF_8)); + return BodyContent.of(contentType, sb.toString()); } final String type = (body == null) ? "null" : body.getClass().toString(); throw new IllegalStateException("Unable to translate response body to bytes? Maybe use HttpResponse directly instead? Response body type: " + type); @@ -194,7 +194,7 @@ public BodyContent readContent(HttpResponse httpResponse) { } final byte[] bodyBytes = decodeContent(httpResponse); final String contentType = getContentType(httpResponse); - return new BodyContent(contentType, bodyBytes); + return BodyContent.of(contentType, bodyBytes); } String getContentType(HttpResponse httpResponse) { diff --git a/http-client/src/main/java/io/avaje/http/client/DHttpClientRequest.java b/http-client/src/main/java/io/avaje/http/client/DHttpClientRequest.java index 1c2ae9b17..00f536b27 100644 --- a/http-client/src/main/java/io/avaje/http/client/DHttpClientRequest.java +++ b/http-client/src/main/java/io/avaje/http/client/DHttpClientRequest.java @@ -41,7 +41,6 @@ class DHttpClientRequest implements HttpClientRequest, HttpClientResponse { private BodyContent encodedRequestBody; private HttpRequest.BodyPublisher body; - private String rawRequestBody; private HttpRequest.Builder httpRequest; @@ -82,9 +81,6 @@ public String url() { @Override public Optional bodyContent() { - if (rawRequestBody != null) { - return Optional.of(new BodyContent(null, rawRequestBody.getBytes(StandardCharsets.UTF_8))); - } return Optional.ofNullable(encodedRequestBody); } @@ -328,14 +324,14 @@ public HttpClientRequest body(Object bean, Class type, String contentType) { @Override public HttpClientRequest body(String body) { - this.rawRequestBody = body; + this.encodedRequestBody = BodyContent.of(body); this.body = HttpRequest.BodyPublishers.ofString(body); return this; } @Override public HttpClientRequest body(byte[] bytes) { - this.encodedRequestBody = new BodyContent(null, bytes); + this.encodedRequestBody = BodyContent.of(bytes); return this; } @@ -838,11 +834,9 @@ public String requestBody() { if (suppressLogging) { return ""; } else if (encodedRequestBody != null) { - return new String(encodedRequestBody.content(), StandardCharsets.UTF_8); + return encodedRequestBody.contentAsUtf8(); } else if (bodyFormEncoded) { return buildEncodedFormContent(); - } else if (rawRequestBody != null) { - return rawRequestBody; } else if (body != null) { return body.toString(); } else { diff --git a/tests/test-jex/src/main/resources/public/openapi.json b/tests/test-jex/src/main/resources/public/openapi.json index 00da28583..ac5b2453c 100644 --- a/tests/test-jex/src/main/resources/public/openapi.json +++ b/tests/test-jex/src/main/resources/public/openapi.json @@ -5,7 +5,7 @@ "version" : "" }, "paths" : { - "/" : { + "" : { "get" : { "tags" : [ From ff5bba97244144e8b9bb5168374dab7a41e26631 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Thu, 5 Oct 2023 23:39:33 +1300 Subject: [PATCH 0918/1323] [HttpClient] Refactor rename internal methods --- .../java/io/avaje/http/client/DHttpClientContext.java | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/http-client/src/main/java/io/avaje/http/client/DHttpClientContext.java b/http-client/src/main/java/io/avaje/http/client/DHttpClientContext.java index c06007a5f..65888c9c4 100644 --- a/http-client/src/main/java/io/avaje/http/client/DHttpClientContext.java +++ b/http-client/src/main/java/io/avaje/http/client/DHttpClientContext.java @@ -4,7 +4,6 @@ import java.net.http.HttpHeaders; import java.net.http.HttpRequest; import java.net.http.HttpResponse; -import java.nio.charset.StandardCharsets; import java.time.Duration; import java.util.List; import java.util.Map; @@ -170,7 +169,7 @@ BodyContent readErrorContent(boolean responseAsBytes, HttpResponse httpRespon if (responseAsBytes) { return readContent((HttpResponse) httpResponse); } - final String contentType = getContentType(httpResponse); + final String contentType = contentType(httpResponse); final Object body = httpResponse.body(); if (body instanceof String) { return BodyContent.of(contentType, (String) body); @@ -193,15 +192,15 @@ public BodyContent readContent(HttpResponse httpResponse) { metricResBytes.add(body.length); } final byte[] bodyBytes = decodeContent(httpResponse); - final String contentType = getContentType(httpResponse); + final String contentType = contentType(httpResponse); return BodyContent.of(contentType, bodyBytes); } - String getContentType(HttpResponse httpResponse) { + String contentType(HttpResponse httpResponse) { return firstHeader(httpResponse.headers(), "Content-Type", "content-type"); } - String getContentEncoding(HttpResponse httpResponse) { + String contentEncoding(HttpResponse httpResponse) { return firstHeader(httpResponse.headers(), "Content-Encoding", "content-encoding"); } @@ -216,7 +215,7 @@ public byte[] decodeContent(String encoding, byte[] body) { @Override public byte[] decodeContent(HttpResponse httpResponse) { - final String encoding = getContentEncoding(httpResponse); + final String encoding = contentEncoding(httpResponse); return encoding == null ? httpResponse.body() : decodeContent(encoding, httpResponse.body()); } From 1d727c332a79938de129cec1729ad212d68ede64 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Fri, 6 Oct 2023 00:17:01 +1300 Subject: [PATCH 0919/1323] [HttpClient] Refactor UrlBuilder to be an interface --- .../avaje/http/client/DHttpClientContext.java | 2 +- .../io/avaje/http/client/DUrlBuilder.java | 104 ++++++++++++++++++ .../java/io/avaje/http/client/UrlBuilder.java | 104 ++++-------------- .../io/avaje/http/client/UrlBuilderTest.java | 2 +- 4 files changed, 127 insertions(+), 85 deletions(-) create mode 100644 http-client/src/main/java/io/avaje/http/client/DUrlBuilder.java diff --git a/http-client/src/main/java/io/avaje/http/client/DHttpClientContext.java b/http-client/src/main/java/io/avaje/http/client/DHttpClientContext.java index 65888c9c4..f7a240be3 100644 --- a/http-client/src/main/java/io/avaje/http/client/DHttpClientContext.java +++ b/http-client/src/main/java/io/avaje/http/client/DHttpClientContext.java @@ -82,7 +82,7 @@ public BodyAdapter bodyAdapter() { @Override public UrlBuilder url() { - return new UrlBuilder(baseUrl); + return UrlBuilder.of(baseUrl); } public Function errorMapper() { diff --git a/http-client/src/main/java/io/avaje/http/client/DUrlBuilder.java b/http-client/src/main/java/io/avaje/http/client/DUrlBuilder.java new file mode 100644 index 000000000..9fdadde10 --- /dev/null +++ b/http-client/src/main/java/io/avaje/http/client/DUrlBuilder.java @@ -0,0 +1,104 @@ +package io.avaje.http.client; + +import java.util.Collection; +import java.util.Map; + +final class DUrlBuilder implements UrlBuilder { + + private final StringBuilder buffer = new StringBuilder(100); + + private boolean hasParams; + + DUrlBuilder(String base) { + buffer.append(base); + } + + @Override + public UrlBuilder url(String url) { + buffer.delete(0, buffer.length()); + buffer.append(url); + return this; + } + + @Override + public UrlBuilder path(String path) { + buffer.append("/").append(path); + return this; + } + + @Override + public UrlBuilder path(int val) { + return path(Integer.toString(val)); + } + + @Override + public UrlBuilder path(long val) { + return path(Long.toString(val)); + } + + @Override + public UrlBuilder path(Object val) { + return path(val.toString()); + } + + private void addQueryParam(String name, String safeValue) { + buffer.append(hasParams ? '&' : '?'); + hasParams = true; + buffer.append(UrlBuilder.enc(name)).append("=").append(safeValue); + } + + @Override + public UrlBuilder queryParam(String name, String value) { + if (value != null) { + addQueryParam(name, UrlBuilder.enc(value)); + } + return this; + } + + @Override + public UrlBuilder queryParam(String name, Object value) { + if (value instanceof Collection) { + for (var e : (Collection) value) { + queryParam(name, e); + } + return this; + } + + if (value != null) { + addQueryParam(name, value.toString()); + } + return this; + } + + @Override + public UrlBuilder queryParam(Map params) { + if (params != null) { + for (Map.Entry entry : params.entrySet()) { + queryParam(entry.getKey(), entry.getValue()); + } + } + return this; + } + + @Override + public UrlBuilder matrixParam(String name, String value) { + if (value != null) { + buffer.append(';').append(UrlBuilder.enc(name)).append("=").append(UrlBuilder.enc(value)); + } + return this; + } + + @Override + public UrlBuilder matrixParam(String name, Object value) { + if (value != null) { + buffer.append(';').append(UrlBuilder.enc(name)).append("=").append(UrlBuilder.enc(value.toString())); + } + return this; + } + + @Override + public String build() { + return buffer.toString(); + } + +} diff --git a/http-client/src/main/java/io/avaje/http/client/UrlBuilder.java b/http-client/src/main/java/io/avaje/http/client/UrlBuilder.java index 2ed93e78d..eca4cc103 100644 --- a/http-client/src/main/java/io/avaje/http/client/UrlBuilder.java +++ b/http-client/src/main/java/io/avaje/http/client/UrlBuilder.java @@ -2,151 +2,89 @@ import java.net.URLEncoder; import java.nio.charset.StandardCharsets; -import java.util.Collection; import java.util.Map; /** * Build a URL typically using a base url and adding path and query parameters. */ -public final class UrlBuilder { +public interface UrlBuilder { - private final StringBuilder buffer = new StringBuilder(100); - - private boolean hasParams; + /** + * URL encode the value. + */ + static String enc(String val) { + return URLEncoder.encode(val, StandardCharsets.UTF_8); + } /** - * Create with a base url. + * Create a UrlBuilder with a base url. */ - public UrlBuilder(String base) { - buffer.append(base); + static UrlBuilder of(String baseUrl) { + return new DUrlBuilder(baseUrl); } /** * Set the url. This effectively replaces a base url. */ - public UrlBuilder url(String url) { - buffer.delete(0, buffer.length()); - buffer.append(url); - return this; - } + UrlBuilder url(String url); /** * Add a path segment to the url. *

    * This includes appending a "/" prefix with the path. */ - public UrlBuilder path(String path) { - buffer.append("/").append(path); - return this; - } + UrlBuilder path(String path); /** * Add a path segment to the url. */ - public UrlBuilder path(int val) { - return path(Integer.toString(val)); - } + UrlBuilder path(int val); /** * Add a path segment to the url. */ - public UrlBuilder path(long val) { - return path(Long.toString(val)); - } + UrlBuilder path(long val); /** * Add a path segment to the url. */ - public UrlBuilder path(Object val) { - return path(val.toString()); - } - - private void addQueryParam(String name, String safeValue) { - buffer.append(hasParams ? '&' : '?'); - hasParams = true; - buffer.append(enc(name)).append("=").append(safeValue); - } + UrlBuilder path(Object val); /** * Append a query parameter. *

    * The name and value parameters are url encoded. */ - public UrlBuilder queryParam(String name, String value) { - if (value != null) { - addQueryParam(name, enc(value)); - } - return this; - } + UrlBuilder queryParam(String name, String value); /** * Append a query parameter. *

    * The name and value parameters are url encoded. */ - public UrlBuilder queryParam(String name, Object value) { - - if (value instanceof Collection) { - for (var e : (Collection) value) { - queryParam(name, e); - } - return this; - } - - if (value != null) { - addQueryParam(name, value.toString()); - } - return this; - } + UrlBuilder queryParam(String name, Object value); /** * Append a query parameters. */ - public UrlBuilder queryParam(Map params) { - if (params != null) { - for (Map.Entry entry : params.entrySet()) { - queryParam(entry.getKey(), entry.getValue()); - } - } - return this; - } + UrlBuilder queryParam(Map params); /** * Append a matrix parameter. *

    * The name and value parameters are url encoded. */ - public UrlBuilder matrixParam(String name, String value) { - if (value != null) { - buffer.append(';').append(enc(name)).append("=").append(enc(value)); - } - return this; - } + UrlBuilder matrixParam(String name, String value); /** * Append a matrix parameter. *

    * The name and value parameters are url encoded. */ - public UrlBuilder matrixParam(String name, Object value) { - if (value != null) { - buffer.append(';').append(enc(name)).append("=").append(enc(value.toString())); - } - return this; - } - - /** - * URL encode the value. - */ - public static String enc(String val) { - return URLEncoder.encode(val, StandardCharsets.UTF_8); - } + UrlBuilder matrixParam(String name, Object value); /** * Return the full URL. */ - public String build() { - return buffer.toString(); - } - + String build(); } diff --git a/http-client/src/test/java/io/avaje/http/client/UrlBuilderTest.java b/http-client/src/test/java/io/avaje/http/client/UrlBuilderTest.java index 5d627e08e..0259d249f 100644 --- a/http-client/src/test/java/io/avaje/http/client/UrlBuilderTest.java +++ b/http-client/src/test/java/io/avaje/http/client/UrlBuilderTest.java @@ -149,7 +149,7 @@ void queryParam_when_instant() { @NotNull private UrlBuilder foo() { - return new UrlBuilder("https://foo"); + return UrlBuilder.of("https://foo"); } @Test From 2b9f3cc566f2dac7f00caa5a989d1778fe6641c9 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Thu, 5 Oct 2023 10:58:17 -0400 Subject: [PATCH 0920/1323] bold --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 21fbdde48..9ccaf3966 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ Use source code generation to adapt annotated REST controllers `@Path, @Get, @Po ${avaje.http.version} ``` -#### Add the generator module for your desired microframework as an annotation processor. +**Add the generator module for your desired microframework as an annotation processor.** ```xml From 19e5677ea5a286104f8eda9a315c3102f0ed6c6b Mon Sep 17 00:00:00 2001 From: Rob Bygrave <130515035+rob-bygrave@users.noreply.github.com> Date: Tue, 17 Oct 2023 11:36:59 +1300 Subject: [PATCH 0921/1323] Fix the GH workflow build for JDK 21 plus to include Helidon (#303) * Fix the GH workflow build for JDK 21 plus to include Helidon --- pom.xml | 4 ++-- tests/pom.xml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index adcda2bdf..d9b11faa2 100644 --- a/pom.xml +++ b/pom.xml @@ -57,9 +57,9 @@ - jdk19plus + jdk21plus - [20,21] + [21,22] http-generator-helidon diff --git a/tests/pom.xml b/tests/pom.xml index d77897bd4..6096c0c2a 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -30,9 +30,9 @@ - jdk20plus + jdk21plus - 21 + [21,22] test-nima From fb65de60b488505a6f070faf7f274a8c8df81a5e Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Mon, 16 Oct 2023 18:46:36 -0400 Subject: [PATCH 0922/1323] Enable annotation processors in JDK 22 (#302) * enable processors in JDK 22 * Update README.md * Update README.md * Update pom.xml * dependabot * Update dependabot-merge.yml * Update pom.xml --------- Co-authored-by: Rob Bygrave <130515035+rob-bygrave@users.noreply.github.com> --- .github/dependabot.yml | 7 +++++ .github/workflows/dependabot-merge.yml | 28 +++++++++++++++++++ README.md | 13 +++++++++ http-generator-jex/pom.xml | 28 ++++++------------- .../http/generator/jex/JexProcessor.java | 2 ++ .../src/main/java/module-info.java | 1 + .../javax.annotation.processing.Processor | 1 - 7 files changed, 59 insertions(+), 21 deletions(-) create mode 100644 .github/dependabot.yml create mode 100644 .github/workflows/dependabot-merge.yml delete mode 100644 http-generator-jex/src/main/resources/META-INF/services/javax.annotation.processing.Processor diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 000000000..6da8cf94c --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,7 @@ +version: 2 +updates: +- package-ecosystem: maven + directory: "/" + schedule: + interval: "daily" + open-pull-requests-limit: 10 diff --git a/.github/workflows/dependabot-merge.yml b/.github/workflows/dependabot-merge.yml new file mode 100644 index 000000000..f70f7d91d --- /dev/null +++ b/.github/workflows/dependabot-merge.yml @@ -0,0 +1,28 @@ +name: Dependabot auto-merge +on: pull_request + +permissions: + contents: write + pull-requests: write + +jobs: + dependabot: + runs-on: ubuntu-latest + if: ${{ github.actor == 'dependabot[bot]' }} + steps: + - name: Dependabot metadata + id: metadata + uses: dependabot/fetch-metadata@v1 + with: + github-token: "${{ secrets.GITHUB_TOKEN }}" + - name: Approve a PR + run: gh pr review --approve "$PR_URL" + env: + PR_URL: ${{github.event.pull_request.html_url}} + GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} + # - name: Enable auto-merge for Dependabot PRs + # if: ${{contains(steps.metadata.outputs.dependency-names, 'my-dependency') && steps.metadata.outputs.update-type == 'version-update:semver-patch'}} + # run: gh pr merge --auto --merge "$PR_URL" + # env: + # PR_URL: ${{github.event.pull_request.html_url}} + # GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} diff --git a/README.md b/README.md index 9ccaf3966..6b63dafb2 100644 --- a/README.md +++ b/README.md @@ -45,6 +45,19 @@ Use source code generation to adapt annotated REST controllers `@Path, @Get, @Po ``` +### JDK 22+ + +In JDK 22+, annotation processors are disabled by default, you will need to add a flag to re-enable. +```xml + + org.apache.maven.plugins + maven-compiler-plugin + + -proc:full + + +``` + ## Define a Controller (These APT processors work with Java and Kotlin.) ```java package org.example.hello; diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index edd78b5db..2710eb86c 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -16,25 +16,13 @@ avaje-http-generator-core ${project.version} - + + + io.avaje + avaje-prisms + ${avaje.prisms.version} + provided + + - - - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.10.1 - - 11 - 11 - - -proc:none - - - - - - diff --git a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/JexProcessor.java b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/JexProcessor.java index 922a23565..95f4712fa 100644 --- a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/JexProcessor.java +++ b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/JexProcessor.java @@ -3,9 +3,11 @@ import io.avaje.http.generator.core.BaseProcessor; import io.avaje.http.generator.core.ControllerReader; import io.avaje.http.generator.core.PlatformAdapter; +import io.avaje.prism.AnnotationProcessor; import java.io.IOException; +@AnnotationProcessor public class JexProcessor extends BaseProcessor { @Override diff --git a/http-generator-jex/src/main/java/module-info.java b/http-generator-jex/src/main/java/module-info.java index c87618944..e833e3579 100644 --- a/http-generator-jex/src/main/java/module-info.java +++ b/http-generator-jex/src/main/java/module-info.java @@ -7,4 +7,5 @@ // SHADED: All content after this line will be removed at package time requires transitive io.avaje.http.generator.core; + requires static io.avaje.prism; } diff --git a/http-generator-jex/src/main/resources/META-INF/services/javax.annotation.processing.Processor b/http-generator-jex/src/main/resources/META-INF/services/javax.annotation.processing.Processor deleted file mode 100644 index 040915f08..000000000 --- a/http-generator-jex/src/main/resources/META-INF/services/javax.annotation.processing.Processor +++ /dev/null @@ -1 +0,0 @@ -io.avaje.http.generator.jex.JexProcessor From 5b7144eeeb54a3b032cb4b9dacab23fcc97e717b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Oct 2023 22:47:02 +0000 Subject: [PATCH 0923/1323] Bump junit.version from 5.9.2 to 5.10.0 Bumps `junit.version` from 5.9.2 to 5.10.0. Updates `org.junit.jupiter:junit-jupiter-api` from 5.9.2 to 5.10.0 - [Release notes](https://github.com/junit-team/junit5/releases) - [Commits](https://github.com/junit-team/junit5/compare/r5.9.2...r5.10.0) Updates `org.junit.jupiter:junit-jupiter-engine` from 5.9.2 to 5.10.0 - [Release notes](https://github.com/junit-team/junit5/releases) - [Commits](https://github.com/junit-team/junit5/compare/r5.9.2...r5.10.0) --- updated-dependencies: - dependency-name: org.junit.jupiter:junit-jupiter-api dependency-type: direct:development update-type: version-update:semver-minor - dependency-name: org.junit.jupiter:junit-jupiter-engine dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- tests/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/pom.xml b/tests/pom.xml index 6096c0c2a..cd69310e5 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -12,7 +12,7 @@ true - 5.9.2 + 5.10.0 3.24.1 2.14.1 2.5 From f4ebbd21ef27708c2c654e6e06f3a3173612cf5d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Oct 2023 22:47:07 +0000 Subject: [PATCH 0924/1323] Bump io.avaje:avaje-jsonb from 1.7 to 1.8 Bumps [io.avaje:avaje-jsonb](https://github.com/avaje/avaje-jsonb) from 1.7 to 1.8. - [Release notes](https://github.com/avaje/avaje-jsonb/releases) - [Commits](https://github.com/avaje/avaje-jsonb/compare/1.7...1.8) --- updated-dependencies: - dependency-name: io.avaje:avaje-jsonb dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- http-client/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/http-client/pom.xml b/http-client/pom.xml index de139ba86..bca8cfc03 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -36,7 +36,7 @@ io.avaje avaje-jsonb - 1.7 + 1.8 true diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 101065969..8f92fc934 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -34,7 +34,7 @@ io.avaje avaje-jsonb - 1.8-RC1 + 1.8 io.avaje From 44f33353912cf148332b254304a66786e5fc20eb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Oct 2023 22:47:12 +0000 Subject: [PATCH 0925/1323] Bump io.avaje:validator-constraints from 0.15 to 1.1 Bumps io.avaje:validator-constraints from 0.15 to 1.1. --- updated-dependencies: - dependency-name: io.avaje:validator-constraints dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- http-generator-core/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 9cf07ae92..333311b4c 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -47,7 +47,7 @@ io.avaje validator-constraints - 0.15 + 1.1 true provided From 7864e1ca0b1f5a77c9aa7f6667d2147d0ef88671 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Oct 2023 22:47:18 +0000 Subject: [PATCH 0926/1323] Bump avaje-inject.version from 9.0 to 9.7 Bumps `avaje-inject.version` from 9.0 to 9.7. Updates `io.avaje:avaje-inject` from 9.0 to 9.7 - [Release notes](https://github.com/avaje/avaje-inject/releases) - [Commits](https://github.com/avaje/avaje-inject/compare/9.0...9.7) Updates `io.avaje:avaje-inject-generator` from 9.4 to 9.7 --- updated-dependencies: - dependency-name: io.avaje:avaje-inject dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: io.avaje:avaje-inject-generator dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- http-client/pom.xml | 4 ++-- http-inject-plugin/pom.xml | 2 +- tests/pom.xml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/http-client/pom.xml b/http-client/pom.xml index de139ba86..40dadea2d 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -43,7 +43,7 @@ io.avaje avaje-inject - 9.5 + 9.7 true @@ -106,7 +106,7 @@ io.avaje avaje-inject-generator - 9.4 + 9.7 diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index b21cacbd4..7b614af27 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -19,7 +19,7 @@ io.avaje avaje-inject - 9.0 + 9.7 provided true diff --git a/tests/pom.xml b/tests/pom.xml index 6096c0c2a..d7a166f69 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -16,7 +16,7 @@ 3.24.1 2.14.1 2.5 - 9.5 + 9.7 4.0.0-RC1 From e56c8206a256b60cbd9636701c9d7219d114c583 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Oct 2023 22:47:26 +0000 Subject: [PATCH 0927/1323] Bump com.fasterxml.jackson.core:jackson-databind from 2.14.1 to 2.15.3 Bumps [com.fasterxml.jackson.core:jackson-databind](https://github.com/FasterXML/jackson) from 2.14.1 to 2.15.3. - [Commits](https://github.com/FasterXML/jackson/commits) --- updated-dependencies: - dependency-name: com.fasterxml.jackson.core:jackson-databind dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- http-client/pom.xml | 2 +- tests/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/http-client/pom.xml b/http-client/pom.xml index de139ba86..282854dae 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -29,7 +29,7 @@ com.fasterxml.jackson.core jackson-databind - 2.14.2 + 2.15.3 true diff --git a/tests/pom.xml b/tests/pom.xml index 6096c0c2a..64a90c3b3 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -14,7 +14,7 @@ true 5.9.2 3.24.1 - 2.14.1 + 2.15.3 2.5 9.5 4.0.0-RC1 From 9925bd10c62bd28659a24b60071dd9b89f3d0051 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Oct 2023 22:47:29 +0000 Subject: [PATCH 0928/1323] Bump io.javalin:javalin from 5.2.0 to 5.6.3 Bumps [io.javalin:javalin](https://github.com/javalin/javalin) from 5.2.0 to 5.6.3. - [Commits](https://github.com/javalin/javalin/compare/javalin-parent-5.2.0...javalin-parent-5.6.3) --- updated-dependencies: - dependency-name: io.javalin:javalin dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- http-client/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/http-client/pom.xml b/http-client/pom.xml index de139ba86..e90bd7aed 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -66,7 +66,7 @@ io.javalin javalin - 5.6.1 + 5.6.3 test diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 93cb0168d..7d40f861f 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -13,7 +13,7 @@ true org.example.myapp.Main - 5.2.0 + 5.6.3 2.0.8 1.3.71 diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 65247dded..e7870dd1d 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -12,7 +12,7 @@ true org.example.myapp.Main - 5.2.0 + 5.6.3 2.0.8 1.3.71 From 88ba92389c912f02ccc83bfb2f12949d9f920476 Mon Sep 17 00:00:00 2001 From: "robin.bygrave" Date: Tue, 17 Oct 2023 11:55:18 +1300 Subject: [PATCH 0929/1323] Support JDK 22 compile with annotation processing change --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index d9b11faa2..f0451e542 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ org.avaje java11-oss - 3.10 + 3.12 io.avaje From a2613f4f8a8b59bd27eded62ebd2ee2db53a0884 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Oct 2023 22:57:09 +0000 Subject: [PATCH 0930/1323] Bump swagger.version from 2.0.8 to 2.2.17 Bumps `swagger.version` from 2.0.8 to 2.2.17. Updates `io.swagger.core.v3:swagger-annotations` from 2.0.8 to 2.2.17 Updates `io.swagger.core.v3:swagger-models` from 2.2.8 to 2.2.17 --- updated-dependencies: - dependency-name: io.swagger.core.v3:swagger-annotations dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: io.swagger.core.v3:swagger-models dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index f0451e542..b15c9dadc 100644 --- a/pom.xml +++ b/pom.xml @@ -19,7 +19,7 @@ true - 2.2.8 + 2.2.17 2.14.2 1.16 ${project.build.directory}${file.separator}module-info.shade diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 7d40f861f..ebba2cd07 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -14,7 +14,7 @@ true org.example.myapp.Main 5.6.3 - 2.0.8 + 2.2.17 1.3.71 diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index e7870dd1d..080cbf42c 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -13,7 +13,7 @@ true org.example.myapp.Main 5.6.3 - 2.0.8 + 2.2.17 1.3.71 diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index d944d8532..4806960c9 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -13,7 +13,7 @@ true org.example.myapp.Main 2.5 - 2.0.8 + 2.2.17 From 443808c14dd3d2b72d2bf7c5a03f1df52ec775a4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Oct 2023 22:58:18 +0000 Subject: [PATCH 0931/1323] Bump org.assertj:assertj-core from 3.24.1 to 3.24.2 Bumps org.assertj:assertj-core from 3.24.1 to 3.24.2. --- updated-dependencies: - dependency-name: org.assertj:assertj-core dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- tests/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/pom.xml b/tests/pom.xml index 3487f415f..998f157ca 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -13,7 +13,7 @@ true 5.10.0 - 3.24.1 + 3.24.2 2.15.3 2.5 9.7 From 355edee427e9eaaaa289d581c5511fe94c36658d Mon Sep 17 00:00:00 2001 From: "robin.bygrave" Date: Tue, 17 Oct 2023 12:11:05 +1300 Subject: [PATCH 0932/1323] Test dependency bump avaje-jsonb --- tests/test-javalin-jsonb/pom.xml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index ebba2cd07..f02593d50 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -78,10 +78,16 @@ provided + + io.avaje + avaje-jsonb + 1.8 + + io.avaje avaje-jsonb-generator - 1.4 + 1.8 provided From 4f6544796e23fa54372a4cd676767bc9a6436cd7 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Mon, 16 Oct 2023 20:22:50 -0400 Subject: [PATCH 0933/1323] Enable Dependabot auto-merge Branch protections should be enabled --- .github/workflows/dependabot-merge.yml | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/.github/workflows/dependabot-merge.yml b/.github/workflows/dependabot-merge.yml index f70f7d91d..4a35210c2 100644 --- a/.github/workflows/dependabot-merge.yml +++ b/.github/workflows/dependabot-merge.yml @@ -20,9 +20,8 @@ jobs: env: PR_URL: ${{github.event.pull_request.html_url}} GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} - # - name: Enable auto-merge for Dependabot PRs - # if: ${{contains(steps.metadata.outputs.dependency-names, 'my-dependency') && steps.metadata.outputs.update-type == 'version-update:semver-patch'}} - # run: gh pr merge --auto --merge "$PR_URL" - # env: - # PR_URL: ${{github.event.pull_request.html_url}} - # GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} + - name: Enable auto-merge for Dependabot PRs + run: gh pr merge --auto --merge "$PR_URL" + env: + PR_URL: ${{github.event.pull_request.html_url}} + GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} From 0a22ab9ac3f68808fc0c4d6a195ef5fcdf914c55 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 17 Oct 2023 19:57:55 +0000 Subject: [PATCH 0934/1323] Bump io.repaint.maven:tiles-maven-plugin from 2.22 to 2.37 Bumps [io.repaint.maven:tiles-maven-plugin](https://github.com/repaint-io/maven-tiles) from 2.22 to 2.37. - [Changelog](https://github.com/repaint-io/maven-tiles/blob/master/CHANGELOG.adoc) - [Commits](https://github.com/repaint-io/maven-tiles/compare/tiles-maven-plugin-2.22...tiles-maven-plugin-2.37) --- updated-dependencies: - dependency-name: io.repaint.maven:tiles-maven-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index f02593d50..80a4ebd05 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -137,7 +137,7 @@ io.repaint.maven tiles-maven-plugin - 2.22 + 2.37 true diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 080cbf42c..2675e29b4 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -130,7 +130,7 @@ io.repaint.maven tiles-maven-plugin - 2.22 + 2.37 true diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 4806960c9..8743ae540 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -122,7 +122,7 @@ io.repaint.maven tiles-maven-plugin - 2.22 + 2.37 true diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 8f92fc934..ff660fa82 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -106,7 +106,7 @@ io.repaint.maven tiles-maven-plugin - 2.34 + 2.37 true diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index 4f46df84a..750f77797 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -74,7 +74,7 @@ io.repaint.maven tiles-maven-plugin - 2.22 + 2.37 true From ace3cc31214a0d5c17525d777d303d37af2d37b3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 17 Oct 2023 20:01:09 +0000 Subject: [PATCH 0935/1323] Bump io.rest-assured:rest-assured from 5.0.1 to 5.3.2 Bumps [io.rest-assured:rest-assured](https://github.com/rest-assured/rest-assured) from 5.0.1 to 5.3.2. - [Changelog](https://github.com/rest-assured/rest-assured/blob/master/changelog.txt) - [Commits](https://github.com/rest-assured/rest-assured/commits) --- updated-dependencies: - dependency-name: io.rest-assured:rest-assured dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 80a4ebd05..f12d34646 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -102,7 +102,7 @@ io.rest-assured rest-assured - 5.3.0 + 5.3.2 test diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 2675e29b4..d48ddf34d 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -95,7 +95,7 @@ io.rest-assured rest-assured - 5.0.1 + 5.3.2 test From 4c54119d78e04fae191626b9525134de8e0d63b0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 17 Oct 2023 20:03:57 +0000 Subject: [PATCH 0936/1323] Bump org.apache.maven.plugins:maven-antrun-plugin from 1.7 to 3.1.0 Bumps [org.apache.maven.plugins:maven-antrun-plugin](https://github.com/apache/maven-antrun-plugin) from 1.7 to 3.1.0. - [Commits](https://github.com/apache/maven-antrun-plugin/compare/maven-antrun-plugin-1.7...maven-antrun-plugin-3.1.0) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-antrun-plugin dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index b15c9dadc..caca4cdaf 100644 --- a/pom.xml +++ b/pom.xml @@ -77,7 +77,7 @@ maven-antrun-plugin - 1.7 + 3.1.0 process-resources From 72815091b1cbee0505c9d903f1d7c821cd849540 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Tue, 17 Oct 2023 16:04:31 -0400 Subject: [PATCH 0937/1323] Update AnnotationUtil.java --- .../java/io/avaje/http/generator/client/AnnotationUtil.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/AnnotationUtil.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/AnnotationUtil.java index 1f3769381..aeb31c6b3 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/AnnotationUtil.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/AnnotationUtil.java @@ -20,7 +20,7 @@ public static void writeAnnotations(Append writer, Element element) { continue; } final String annotationName = annotationMirror.getAnnotationType().toString(); - final StringBuilder sb = new StringBuilder("@").append(annotationName).append("("); + final StringBuilder sb = new StringBuilder(" @").append(annotationName).append("("); boolean first = true; for (final var entry : annotationMirror.getElementValues().entrySet()) { From 571bf86876fc76144a597b80850d2f634393a93a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 17 Oct 2023 20:06:51 +0000 Subject: [PATCH 0938/1323] Bump com.google.code.gson:gson from 2.10 to 2.10.1 Bumps [com.google.code.gson:gson](https://github.com/google/gson) from 2.10 to 2.10.1. - [Release notes](https://github.com/google/gson/releases) - [Changelog](https://github.com/google/gson/blob/main/CHANGELOG.md) - [Commits](https://github.com/google/gson/compare/gson-parent-2.10...gson-parent-2.10.1) --- updated-dependencies: - dependency-name: com.google.code.gson:gson dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- http-client-gson-adapter/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index 914e0d913..dca6b0684 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -14,7 +14,7 @@ com.google.code.gson gson - 2.10 + 2.10.1 From 7a040870eadfe33956a097e7a16be646a878ebbb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 17 Oct 2023 20:09:25 +0000 Subject: [PATCH 0939/1323] Bump org.apache.maven.plugins:maven-compiler-plugin Bumps [org.apache.maven.plugins:maven-compiler-plugin](https://github.com/apache/maven-compiler-plugin) from 3.10.1 to 3.11.0. - [Release notes](https://github.com/apache/maven-compiler-plugin/releases) - [Commits](https://github.com/apache/maven-compiler-plugin/compare/maven-compiler-plugin-3.10.1...maven-compiler-plugin-3.11.0) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-compiler-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- http-client/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/http-client/pom.xml b/http-client/pom.xml index d5d1e46eb..da8b9e186 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -97,7 +97,7 @@ org.apache.maven.plugins maven-compiler-plugin - 3.10.1 + 3.11.0 default-testCompile diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index 750f77797..88739d381 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -52,7 +52,7 @@ org.apache.maven.plugins maven-compiler-plugin - 3.10.1 + 3.11.0 21 From 9554ee2bba72d4ea6931f096ccbaae94b2b7c01a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 17 Oct 2023 20:12:54 +0000 Subject: [PATCH 0940/1323] Bump io.avaje:avaje-inject-maven-plugin from 1.0 to 1.2 Bumps io.avaje:avaje-inject-maven-plugin from 1.0 to 1.2. --- updated-dependencies: - dependency-name: io.avaje:avaje-inject-maven-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- tests/test-nima-jsonb/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index ff660fa82..5359a61a2 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -117,7 +117,7 @@ io.avaje avaje-inject-maven-plugin - 1.0 + 1.2 process-sources From 2f565f72fa90100174e17488cd6ce480cdf05c05 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Tue, 17 Oct 2023 22:58:17 -0400 Subject: [PATCH 0941/1323] allow path to be loaded from system properties --- .../generator/client/ClientMethodWriter.java | 34 ++++++++++++++- .../generator/client/clients/UserClient.java | 3 ++ .../http/generator/core/PathSegments.java | 43 ++++++++++++++++--- .../io/avaje/http/generator/core/Util.java | 17 +++++--- 4 files changed, 85 insertions(+), 12 deletions(-) diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java index 956431ac9..a6cc319ff 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java @@ -2,13 +2,19 @@ import static io.avaje.http.generator.core.ProcessingContext.*; import io.avaje.http.generator.core.*; +import io.avaje.http.generator.core.PathSegments.Segment; import javax.lang.model.element.TypeElement; import javax.lang.model.util.ElementFilter; +import static java.util.stream.Collectors.toMap; + import java.util.List; +import java.util.Map; import java.util.Optional; import java.util.Set; +import java.util.function.Function; +import java.util.regex.Pattern; import java.util.stream.Collectors; /** @@ -29,6 +35,8 @@ class ClientMethodWriter { private String methodGenericParams = ""; private final boolean useJsonb; private final Optional timeout; + private final boolean useConfig; + private final Map segmentPropertyMap; ClientMethodWriter(MethodReader method, Append writer, boolean useJsonb) { this.method = method; @@ -37,6 +45,12 @@ class ClientMethodWriter { this.returnType = Util.parseType(method.returnType()); this.useJsonb = useJsonb; this.timeout = method.timeout(); + this.useConfig = ProcessingContext.typeElement("io.avaje.config.Config") != null; + + this.segmentPropertyMap = + method.pathSegments().segments().stream() + .filter(Segment::isProperty) + .collect(toMap(Segment::name, s -> Util.sanitizeName(s.name()).toUpperCase())); } void addImportTypes(ControllerReader reader) { @@ -45,9 +59,14 @@ void addImportTypes(ControllerReader reader) { .map(UType::parse) .map(UType::importTypes) .forEach(reader::addImportTypes); + for (final MethodParam param : method.params()) { reader.addImportTypes(param.utype().importTypes()); } + + if (useConfig && !segmentPropertyMap.isEmpty()) { + reader.addImportType("io.avaje.config.Config"); + } } private void methodStart(Append writer) { @@ -55,6 +74,14 @@ private void methodStart(Append writer) { checkBodyHandler(param); } method.checkArgumentNames(); + + segmentPropertyMap.forEach( + (k, v) -> { + writer.append(" private static final String %s = ", v); + final String getProperty = useConfig ? "Config.get(" : "System.getProperty("; + writer.append(getProperty).append("\"%s\");", k).eol(); + }); + writer.append(" // %s %s", webMethod, method.webMethodPath()).eol(); writer.append(" @Override").eol(); AnnotationUtil.writeAnnotations(writer, method.element()); @@ -348,9 +375,14 @@ private void writePaths(Set segments) { for (PathSegments.Segment segment : segments) { if (segment.isLiteral()) { writer.append(".path(\"").append(segment.literalSection()).append("\")"); + } else if (segment.isProperty()) { + + writer.append(".path(").append(segmentPropertyMap.get(segment.name())).append(")"); + } else { + writer.append(".path(").append(segment.name()).append(")"); - //TODO: matrix params + // TODO: matrix params } } if (!segments.isEmpty()) { diff --git a/http-generator-client/src/test/java/io/avaje/http/generator/client/clients/UserClient.java b/http-generator-client/src/test/java/io/avaje/http/generator/client/clients/UserClient.java index f4e3d6163..803539388 100644 --- a/http-generator-client/src/test/java/io/avaje/http/generator/client/clients/UserClient.java +++ b/http-generator-client/src/test/java/io/avaje/http/generator/client/clients/UserClient.java @@ -20,4 +20,7 @@ public interface UserClient { @Get("/users/{userId}") String getUserById(String userId); + + @Get("${property.path}/users/{userId}") + String property(String userId); } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/PathSegments.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/PathSegments.java index 05c25c2ce..a278ed077 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/PathSegments.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/PathSegments.java @@ -36,6 +36,12 @@ static PathSegments parse(String fullPath) { segments.add(segment); chunks.named(segment.path(name), section.charAt(0)); + } else if (isProperty(section)) { + String name = section.substring(2, section.length() - 1); + Segment segment = createPropertySegment(name); + segments.add(segment); + chunks.named(segment.path(name), section.charAt(0)); + } else { Segment segment = createLiteralSegment(section); segments.add(segment); @@ -52,8 +58,12 @@ private static boolean isPathParameter(String section) { || section.startsWith("<") && section.endsWith(">"); } + private static boolean isProperty(String section) { + return section.startsWith("${") && section.endsWith("}"); + } + private static Segment createLiteralSegment(String section) { - return new Segment(section, true); + return new Segment(section, "literal"); } private static Segment createSegment(String val) { @@ -65,6 +75,11 @@ private static Segment createSegment(String val) { return new Segment(matrixSplit[0], matrixKeys); } + private static Segment createPropertySegment(String val) { + + return new Segment(val, true); + } + private final Chunks chunks; private final Set segments; private final List withMatrixs = new ArrayList<>(); @@ -129,7 +144,6 @@ public boolean isEmpty() { public static class Segment { - private static final Pattern PATTERN = Pattern.compile("[^a-zA-Z0-9_]|\\s"); private final String name; private final String sanitizedName; private final String literalSection; @@ -144,15 +158,28 @@ public static class Segment { */ private final Set matrixVarNames; + private final boolean property; + /** * Create a normal segment. */ Segment(String name) { this.name = name; - this.sanitizedName = PATTERN.matcher(name).replaceAll("_"); + this.sanitizedName = Util.sanitizeName(name); this.literalSection = null; this.matrixKeys = null; this.matrixVarNames = null; + this.property = false; + } + + /** Create a normal segment. */ + Segment(String name, boolean isProperty) { + this.name = name; + this.sanitizedName = null; + this.literalSection = null; + this.matrixKeys = null; + this.matrixVarNames = null; + this.property = isProperty; } /** @@ -160,10 +187,11 @@ public static class Segment { */ Segment(String name, Set matrixKeys) { this.name = name; - this.sanitizedName = PATTERN.matcher(name).replaceAll("_"); + this.sanitizedName = Util.sanitizeName(name); this.literalSection = null; this.matrixKeys = matrixKeys; this.matrixVarNames = new HashSet<>(); + this.property = false; for (String key : matrixKeys) { matrixVarNames.add(combine(name, key)); } @@ -172,12 +200,13 @@ public static class Segment { /** * Create a literal path segment. */ - public Segment(String section, boolean literalDummy) { + public Segment(String section, String literalDummy) { this.literalSection = section; this.name = null; this.sanitizedName = null; this.matrixKeys = null; this.matrixVarNames = null; + this.property = false; } void addNames(Set allNames) { @@ -210,6 +239,10 @@ public boolean isLiteral() { return literalSection != null; } + public boolean isProperty() { + return property; + } + boolean isPathParameter(String varName) { return (name != null && name.equals(varName)) || (matrixKeys != null && (matrixVarNames.contains(varName) || matrixKeys.contains(varName))); } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/Util.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/Util.java index 06c6fcaff..8a1569139 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/Util.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/Util.java @@ -23,6 +23,8 @@ public class Util { Pattern.compile(", (?=(?:[^\\\"]*\\\"[^\\\"]*\\\")*[^\\\"]*$)"); private static final Pattern PARENTHESIS_CONTENT = Pattern.compile("\\((.*?)\\)"); + private static final Pattern SANITIZE_PATTERN = Pattern.compile("[^a-zA-Z0-9_]|\\s"); + /** * Parse the raw type potentially handling generic parameters. */ @@ -48,6 +50,11 @@ public static String typeDef(TypeMirror typeMirror) { } } + /** Sanitize the given string such that it can be used as a method/class/field name */ + public static String sanitizeName(String name) { + return SANITIZE_PATTERN.matcher(name).replaceAll("_"); + } + /** Trim off annotations from the raw type if present. */ public static String trimAnnotations(String input) { input = COMMA_PATTERN.matcher(input).replaceAll(","); @@ -173,13 +180,11 @@ public static String initcapSnake(String input) { if (ch == '-') { sb.append(ch); upper = true; + } else if (upper) { + sb.append(Character.toUpperCase(ch)); + upper = false; } else { - if (upper) { - sb.append(Character.toUpperCase(ch)); - upper = false; - } else { - sb.append(ch); - } + sb.append(ch); } } return sb.toString(); From 014af6d237d6c41d96e2c976fb5faca0751b451e Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Tue, 17 Oct 2023 23:26:25 -0400 Subject: [PATCH 0942/1323] Update README.md --- README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 6b63dafb2..490bf4cfe 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ Use source code generation to adapt annotated REST controllers `@Path, @Get, @Po - Lightweight (65Kb library + generated source code) - Full use of Javalin or Helidon SE/Nima as desired -- Bean Validation of request bodies supported +- Bean Validation of request bodies supported (validation groups supported as well) ## Add dependencies ```xml @@ -58,7 +58,7 @@ In JDK 22+, annotation processors are disabled by default, you will need to add ``` -## Define a Controller (These APT processors work with Java and Kotlin.) +## Define a Controller (These APT processors work with both Java and Kotlin) ```java package org.example.hello; @@ -106,7 +106,7 @@ To force the AP to generate with `@javax.inject.Singleton`(in the case where you ### Usage with Javalin -The annotation processor will generate controller classes implementing the Javalin `Plugin` interface, which means we can register them with Javalin using: +The annotation processor will generate controller classes implementing the Javalin `Plugin` interface, which we can register using: ```java List routes = ...; //retrieve using a DI framework @@ -268,6 +268,7 @@ public class WidgetController$Route implements HttpFeature { var id = asInt(pathParams.first("id").get()); var result = controller.getById(id); res.headers().contentType(MediaTypes.APPLICATION_JSON); + //jsonb has a special accommodation for helidon to improve performance widgetController$WidgetJsonType.toJson(result, JsonOutput.of(res)); } From 7e06ccb8b160cfa5d44fc851437fa95eb11aa5e0 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Wed, 18 Oct 2023 20:49:01 +1300 Subject: [PATCH 0943/1323] Format only change for ClientMethodWriter --- .../generator/client/ClientMethodWriter.java | 91 +++++++++---------- 1 file changed, 41 insertions(+), 50 deletions(-) diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java index a6cc319ff..35e609672 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java @@ -13,8 +13,6 @@ import java.util.Map; import java.util.Optional; import java.util.Set; -import java.util.function.Function; -import java.util.regex.Pattern; import java.util.stream.Collectors; /** @@ -47,18 +45,17 @@ class ClientMethodWriter { this.timeout = method.timeout(); this.useConfig = ProcessingContext.typeElement("io.avaje.config.Config") != null; - this.segmentPropertyMap = - method.pathSegments().segments().stream() - .filter(Segment::isProperty) - .collect(toMap(Segment::name, s -> Util.sanitizeName(s.name()).toUpperCase())); + this.segmentPropertyMap = method.pathSegments().segments().stream() + .filter(Segment::isProperty) + .collect(toMap(Segment::name, s -> Util.sanitizeName(s.name()).toUpperCase())); } void addImportTypes(ControllerReader reader) { reader.addImportTypes(returnType.importTypes()); method.throwsList().stream() - .map(UType::parse) - .map(UType::importTypes) - .forEach(reader::addImportTypes); + .map(UType::parse) + .map(UType::importTypes) + .forEach(reader::addImportTypes); for (final MethodParam param : method.params()) { reader.addImportTypes(param.utype().importTypes()); @@ -75,12 +72,11 @@ private void methodStart(Append writer) { } method.checkArgumentNames(); - segmentPropertyMap.forEach( - (k, v) -> { - writer.append(" private static final String %s = ", v); - final String getProperty = useConfig ? "Config.get(" : "System.getProperty("; - writer.append(getProperty).append("\"%s\");", k).eol(); - }); + segmentPropertyMap.forEach((k, v) -> { + writer.append(" private static final String %s = ", v); + final String getProperty = useConfig ? "Config.get(" : "System.getProperty("; + writer.append(getProperty).append("\"%s\");", k).eol(); + }); writer.append(" // %s %s", webMethod, method.webMethodPath()).eol(); writer.append(" @Override").eol(); @@ -96,9 +92,9 @@ private void methodStart(Append writer) { final var isVarArg = Util.isVarArg(param.element(), i); final var paramType = - "java.util.function.Supplier".equals(param.utype().full()) - ? "Supplier" - : param.utype().shortType(); + "java.util.function.Supplier".equals(param.utype().full()) + ? "Supplier" + : param.utype().shortType(); if (param.overrideVarNameError()) { writer.append("/** !Error! */ "); @@ -144,7 +140,6 @@ void write() { } private void writeTimeout(RequestTimeoutPrism p) { - writer.append(" .requestTimeout(of(%s, %s))", p.value(), p.chronoUnit()).eol(); } @@ -220,11 +215,10 @@ private void writeResponse(UType type) { void writeGeneric(UType type) { if (useJsonb && type.isGeneric()) { - final var params = - type.importTypes().stream() - .skip(1) - .map(Util::shortName) - .collect(Collectors.joining(".class, ")); + final var params = type.importTypes().stream() + .skip(1) + .map(Util::shortName) + .collect(Collectors.joining(".class, ")); writer.append("Types.newParameterizedType(%s.class, %s.class)", Util.shortName(type.mainType()), params); } else { @@ -256,8 +250,8 @@ private void writeQueryParams(PathSegments pathSegments) { writer.append(" // Refer to: https://avaje.io/http/client/import#error").eol(); writer.eol(); logError( - "Explicit @QueryParam/@Header annotations required when using @Client.Import on an interface that has already been compiled.", - method.element()); + "Explicit @QueryParam/@Header annotations required when using @Client.Import on an interface that has already been compiled.", + method.element()); } } @@ -331,27 +325,27 @@ private void writeBody() { private void writeErrorMapper() { method.throwsList().stream() - .map(ProcessingContext::asElement) - .filter( - e -> - isAssignable2Interface( - e.getQualifiedName().toString(), "java.lang.RuntimeException")) - .filter( - e -> - ElementFilter.constructorsIn(e.getEnclosedElements()).stream() - .filter(c -> c.getParameters().size() == 1) - .map(c -> c.getParameters().get(0).asType().toString()) - .map(Util::trimAnnotations) - .anyMatch("io.avaje.http.client.HttpException"::equals)) - .findFirst() - .map(TypeElement::getQualifiedName) - .map(Object::toString) - .map(Util::shortName) - .ifPresent( - exception -> - writer - .append(" .errorMapper(%s::new)", exception) - .eol()); + .map(ProcessingContext::asElement) + .filter( + e -> + isAssignable2Interface( + e.getQualifiedName().toString(), "java.lang.RuntimeException")) + .filter( + e -> + ElementFilter.constructorsIn(e.getEnclosedElements()).stream() + .filter(c -> c.getParameters().size() == 1) + .map(c -> c.getParameters().get(0).asType().toString()) + .map(Util::trimAnnotations) + .anyMatch("io.avaje.http.client.HttpException"::equals)) + .findFirst() + .map(TypeElement::getQualifiedName) + .map(Object::toString) + .map(Util::shortName) + .ifPresent( + exception -> + writer + .append(" .errorMapper(%s::new)", exception) + .eol()); } /** @@ -376,11 +370,8 @@ private void writePaths(Set segments) { if (segment.isLiteral()) { writer.append(".path(\"").append(segment.literalSection()).append("\")"); } else if (segment.isProperty()) { - writer.append(".path(").append(segmentPropertyMap.get(segment.name())).append(")"); - } else { - writer.append(".path(").append(segment.name()).append(")"); // TODO: matrix params } From d2a325236f69bab3a59bc9146a05a6cd7bfd31da Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Wed, 18 Oct 2023 20:53:40 +1300 Subject: [PATCH 0944/1323] Version 2.0-RC11 --- http-api-javalin/pom.xml | 2 +- http-api/pom.xml | 2 +- http-client-gson-adapter/pom.xml | 4 ++-- http-client/pom.xml | 2 +- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 2 +- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-inject-plugin/pom.xml | 2 +- pom.xml | 2 +- tests/pom.xml | 2 +- tests/test-client-generation/pom.xml | 2 +- tests/test-client/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- 19 files changed, 20 insertions(+), 20 deletions(-) diff --git a/http-api-javalin/pom.xml b/http-api-javalin/pom.xml index 5bf74889c..5d35757d1 100644 --- a/http-api-javalin/pom.xml +++ b/http-api-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC10 + 2.0-RC11 .. diff --git a/http-api/pom.xml b/http-api/pom.xml index 7271d1065..44f30a8dd 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC10 + 2.0-RC11 .. diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index dca6b0684..06328f20b 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC10 + 2.0-RC11 avaje-http-client-gson @@ -20,7 +20,7 @@ io.avaje avaje-http-client - 2.0-RC10 + 2.0-RC11 provided diff --git a/http-client/pom.xml b/http-client/pom.xml index da8b9e186..e1b3e55c4 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC10 + 2.0-RC11 avaje-http-client diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index 6ddde9d65..93b660c5a 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC10 + 2.0-RC11 avaje-http-client-generator diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 333311b4c..6c9a90876 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC10 + 2.0-RC11 avaje-http-generator-core diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index d1fa0dbeb..6e4856bf0 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.0-RC10 + 2.0-RC11 avaje-http-helidon-generator diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index 55d7fa370..26f616403 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC10 + 2.0-RC11 avaje-http-javalin-generator diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index 2710eb86c..b07bedd68 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC10 + 2.0-RC11 avaje-http-jex-generator diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index 7b614af27..cfed895d4 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC10 + 2.0-RC11 .. diff --git a/pom.xml b/pom.xml index caca4cdaf..9e0825313 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-parent - 2.0-RC10 + 2.0-RC11 pom diff --git a/tests/pom.xml b/tests/pom.xml index 998f157ca..5a6efa3cc 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.0-RC10 + 2.0-RC11 tests diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index 1c11f8f76..73fb08799 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.0-RC10 + 2.0-RC11 test-client-generation diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index 196688a9c..678d7a1ca 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.0-RC10 + 2.0-RC11 test-client diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index f12d34646..8370cb95a 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 2.0-RC10 + 2.0-RC11 test-javalin-jsonb diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index d48ddf34d..fca819f03 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.0-RC10 + 2.0-RC11 test-javalin diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 8743ae540..46f193d06 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.0-RC10 + 2.0-RC11 test-jex diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 5359a61a2..d11f2f882 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.0-RC10 + 2.0-RC11 test-nima-jsonb diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index 88739d381..b1fd03ff6 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.0-RC10 + 2.0-RC11 test-nima From c067537029a2a5ecb579c9ed13ad74146e0284e3 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Wed, 18 Oct 2023 21:08:28 +1300 Subject: [PATCH 0945/1323] Fix indentation in dependabot-merge.yml --- .github/workflows/dependabot-merge.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/dependabot-merge.yml b/.github/workflows/dependabot-merge.yml index 4a35210c2..0328be627 100644 --- a/.github/workflows/dependabot-merge.yml +++ b/.github/workflows/dependabot-merge.yml @@ -20,8 +20,8 @@ jobs: env: PR_URL: ${{github.event.pull_request.html_url}} GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} - - name: Enable auto-merge for Dependabot PRs - run: gh pr merge --auto --merge "$PR_URL" - env: - PR_URL: ${{github.event.pull_request.html_url}} - GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} + - name: Enable auto-merge for Dependabot PRs + run: gh pr merge --auto --merge "$PR_URL" + env: + PR_URL: ${{github.event.pull_request.html_url}} + GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} From cf6ce026efb3cd3e67b44e1c8da8bb0f97540ddb Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Wed, 18 Oct 2023 09:08:23 -0400 Subject: [PATCH 0946/1323] reset path if an http scheme is detected --- .../src/main/java/io/avaje/http/client/DUrlBuilder.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/http-client/src/main/java/io/avaje/http/client/DUrlBuilder.java b/http-client/src/main/java/io/avaje/http/client/DUrlBuilder.java index 9fdadde10..34ae706c2 100644 --- a/http-client/src/main/java/io/avaje/http/client/DUrlBuilder.java +++ b/http-client/src/main/java/io/avaje/http/client/DUrlBuilder.java @@ -22,6 +22,9 @@ public UrlBuilder url(String url) { @Override public UrlBuilder path(String path) { + if (path.startsWith("http") && path.contains("://")) { + return url(path); + } buffer.append("/").append(path); return this; } From ec2609a44a4b9b6c0ca5c0fc962081496a0d29fa Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 18 Oct 2023 19:44:06 +0000 Subject: [PATCH 0947/1323] Bump avaje-inject.version from 9.7 to 9.8 Bumps `avaje-inject.version` from 9.7 to 9.8. Updates `io.avaje:avaje-inject` from 9.7 to 9.8 - [Release notes](https://github.com/avaje/avaje-inject/releases) - [Commits](https://github.com/avaje/avaje-inject/compare/9.7...9.8) Updates `io.avaje:avaje-inject-generator` from 9.7 to 9.8 --- updated-dependencies: - dependency-name: io.avaje:avaje-inject dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: io.avaje:avaje-inject-generator dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- http-client/pom.xml | 4 ++-- http-inject-plugin/pom.xml | 2 +- tests/pom.xml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/http-client/pom.xml b/http-client/pom.xml index e1b3e55c4..00d64d882 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -43,7 +43,7 @@ io.avaje avaje-inject - 9.7 + 9.8 true @@ -106,7 +106,7 @@ io.avaje avaje-inject-generator - 9.7 + 9.8 diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index cfed895d4..b7ed3e57f 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -19,7 +19,7 @@ io.avaje avaje-inject - 9.7 + 9.8 provided true diff --git a/tests/pom.xml b/tests/pom.xml index 5a6efa3cc..683b09aff 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -16,7 +16,7 @@ 3.24.2 2.15.3 2.5 - 9.7 + 9.8 4.0.0-RC1 From 864acce1591a909f80caa72b66063ad0fe58f68e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 18 Oct 2023 19:47:06 +0000 Subject: [PATCH 0948/1323] Bump io.repaint.maven:tiles-maven-plugin from 2.37 to 2.38 Bumps [io.repaint.maven:tiles-maven-plugin](https://github.com/repaint-io/maven-tiles) from 2.37 to 2.38. - [Changelog](https://github.com/repaint-io/maven-tiles/blob/master/CHANGELOG.adoc) - [Commits](https://github.com/repaint-io/maven-tiles/compare/tiles-maven-plugin-2.37...tiles-maven-plugin-2.38) --- updated-dependencies: - dependency-name: io.repaint.maven:tiles-maven-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 8370cb95a..67b486bb9 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -137,7 +137,7 @@ io.repaint.maven tiles-maven-plugin - 2.37 + 2.38 true diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index fca819f03..87785de10 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -130,7 +130,7 @@ io.repaint.maven tiles-maven-plugin - 2.37 + 2.38 true diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 46f193d06..c451ba6fc 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -122,7 +122,7 @@ io.repaint.maven tiles-maven-plugin - 2.37 + 2.38 true diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index d11f2f882..ecf13381b 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -106,7 +106,7 @@ io.repaint.maven tiles-maven-plugin - 2.37 + 2.38 true diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index b1fd03ff6..f1646ed33 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -74,7 +74,7 @@ io.repaint.maven tiles-maven-plugin - 2.37 + 2.38 true From 7ac946fb42d6fc139e432c8fceee1b5f5ce47161 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Wed, 18 Oct 2023 22:31:28 -0400 Subject: [PATCH 0949/1323] remove extra path calls --- .../generator/client/ClientMethodWriter.java | 32 ++++++++++++++++--- .../http/generator/client/clients/Titan.java | 3 ++ .../generator/client/clients/TitanFall.java | 11 +++++++ 3 files changed, 42 insertions(+), 4 deletions(-) create mode 100644 http-generator-client/src/test/java/io/avaje/http/generator/client/clients/Titan.java create mode 100644 http-generator-client/src/test/java/io/avaje/http/generator/client/clients/TitanFall.java diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java index 35e609672..1f3af3b64 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java @@ -9,6 +9,7 @@ import static java.util.stream.Collectors.toMap; +import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Optional; @@ -366,13 +367,36 @@ private void writePaths(Set segments) { if (!segments.isEmpty()) { writer.append(" "); } - for (PathSegments.Segment segment : segments) { + boolean first = true; + Iterator iterator = segments.iterator(); + boolean sentinel = true; + boolean noSlash = false; + var size = segments.size(); + while (sentinel) { + PathSegments.Segment segment = iterator.hasNext() ? iterator.next() : null; + if (segment == null) { + sentinel = false; + if (size != 0) { + writer.append("\")"); + } + continue; + } + if (first) { + writer.append(".path(\""); + first = false; + } + if (noSlash) { + writer.append("/"); + } + noSlash = true; if (segment.isLiteral()) { - writer.append(".path(\"").append(segment.literalSection()).append("\")"); + writer.append(segment.literalSection()); } else if (segment.isProperty()) { - writer.append(".path(").append(segmentPropertyMap.get(segment.name())).append(")"); + + writer.append("\" + %s + \"", segmentPropertyMap.get(segment.name())); + } else { - writer.append(".path(").append(segment.name()).append(")"); + writer.append(segment.name()); // TODO: matrix params } } diff --git a/http-generator-client/src/test/java/io/avaje/http/generator/client/clients/Titan.java b/http-generator-client/src/test/java/io/avaje/http/generator/client/clients/Titan.java new file mode 100644 index 000000000..fba7fd66f --- /dev/null +++ b/http-generator-client/src/test/java/io/avaje/http/generator/client/clients/Titan.java @@ -0,0 +1,3 @@ +package io.avaje.http.generator.client.clients; + +public class Titan {} diff --git a/http-generator-client/src/test/java/io/avaje/http/generator/client/clients/TitanFall.java b/http-generator-client/src/test/java/io/avaje/http/generator/client/clients/TitanFall.java new file mode 100644 index 000000000..21b542e72 --- /dev/null +++ b/http-generator-client/src/test/java/io/avaje/http/generator/client/clients/TitanFall.java @@ -0,0 +1,11 @@ +package io.avaje.http.generator.client.clients; + +import io.avaje.http.api.Client; +import io.avaje.http.api.Get; + +@Client +public interface TitanFall { + + @Get("/${titan}/${drop.point}") + Titan titanfall(); +} \ No newline at end of file From a81fca65adce526b31c8e3c8c223e7a111af183d Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Wed, 18 Oct 2023 22:48:25 -0400 Subject: [PATCH 0950/1323] Update ClientMethodWriter.java --- .../io/avaje/http/generator/client/ClientMethodWriter.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java index 1f3af3b64..fa095bf13 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java @@ -396,8 +396,7 @@ private void writePaths(Set segments) { writer.append("\" + %s + \"", segmentPropertyMap.get(segment.name())); } else { - writer.append(segment.name()); - // TODO: matrix params + writer.append("\" + %s + \"", segment.name()); } } if (!segments.isEmpty()) { From 6e6bba87acc460bf8efecb16ec9e77c5b511cc4c Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Wed, 18 Oct 2023 22:52:41 -0400 Subject: [PATCH 0951/1323] url instead of path --- .../src/main/java/io/avaje/http/client/DUrlBuilder.java | 9 +++++---- .../avaje/http/generator/client/ClientMethodWriter.java | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/http-client/src/main/java/io/avaje/http/client/DUrlBuilder.java b/http-client/src/main/java/io/avaje/http/client/DUrlBuilder.java index 34ae706c2..8ecc88639 100644 --- a/http-client/src/main/java/io/avaje/http/client/DUrlBuilder.java +++ b/http-client/src/main/java/io/avaje/http/client/DUrlBuilder.java @@ -15,16 +15,17 @@ final class DUrlBuilder implements UrlBuilder { @Override public UrlBuilder url(String url) { - buffer.delete(0, buffer.length()); + + if (url.startsWith("http") && url.contains("://")) { + buffer.setLength(0); + } + buffer.append(url); return this; } @Override public UrlBuilder path(String path) { - if (path.startsWith("http") && path.contains("://")) { - return url(path); - } buffer.append("/").append(path); return this; } diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java index fa095bf13..72767885e 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java @@ -382,7 +382,7 @@ private void writePaths(Set segments) { continue; } if (first) { - writer.append(".path(\""); + writer.append(".url(\""); first = false; } if (noSlash) { From 1c0c774201c2c55747e960b26fd9032798c4d2c6 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Wed, 18 Oct 2023 22:57:44 -0400 Subject: [PATCH 0952/1323] back to path --- .../src/main/java/io/avaje/http/client/DUrlBuilder.java | 4 ++++ .../io/avaje/http/generator/client/ClientMethodWriter.java | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/http-client/src/main/java/io/avaje/http/client/DUrlBuilder.java b/http-client/src/main/java/io/avaje/http/client/DUrlBuilder.java index 8ecc88639..2a5b83d18 100644 --- a/http-client/src/main/java/io/avaje/http/client/DUrlBuilder.java +++ b/http-client/src/main/java/io/avaje/http/client/DUrlBuilder.java @@ -26,6 +26,10 @@ public UrlBuilder url(String url) { @Override public UrlBuilder path(String path) { + if (path.startsWith("http") && path.contains("://")) { + buffer.setLength(0); + return this; + } buffer.append("/").append(path); return this; } diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java index 72767885e..fa095bf13 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java @@ -382,7 +382,7 @@ private void writePaths(Set segments) { continue; } if (first) { - writer.append(".url(\""); + writer.append(".path(\""); first = false; } if (noSlash) { From ba690bd5b40c868f21b9c0f15368b45e591a6e31 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Wed, 18 Oct 2023 23:14:20 -0400 Subject: [PATCH 0953/1323] revert path generation --- .../generator/client/ClientMethodWriter.java | 33 +++---------------- 1 file changed, 5 insertions(+), 28 deletions(-) diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java index fa095bf13..35e609672 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java @@ -9,7 +9,6 @@ import static java.util.stream.Collectors.toMap; -import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Optional; @@ -367,36 +366,14 @@ private void writePaths(Set segments) { if (!segments.isEmpty()) { writer.append(" "); } - boolean first = true; - Iterator iterator = segments.iterator(); - boolean sentinel = true; - boolean noSlash = false; - var size = segments.size(); - while (sentinel) { - PathSegments.Segment segment = iterator.hasNext() ? iterator.next() : null; - if (segment == null) { - sentinel = false; - if (size != 0) { - writer.append("\")"); - } - continue; - } - if (first) { - writer.append(".path(\""); - first = false; - } - if (noSlash) { - writer.append("/"); - } - noSlash = true; + for (PathSegments.Segment segment : segments) { if (segment.isLiteral()) { - writer.append(segment.literalSection()); + writer.append(".path(\"").append(segment.literalSection()).append("\")"); } else if (segment.isProperty()) { - - writer.append("\" + %s + \"", segmentPropertyMap.get(segment.name())); - + writer.append(".path(").append(segmentPropertyMap.get(segment.name())).append(")"); } else { - writer.append("\" + %s + \"", segment.name()); + writer.append(".path(").append(segment.name()).append(")"); + // TODO: matrix params } } if (!segments.isEmpty()) { From c87cddb294e89ad94f21c78074134a8b43c98e3c Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Wed, 18 Oct 2023 23:19:35 -0400 Subject: [PATCH 0954/1323] Update DUrlBuilder.java --- http-client/src/main/java/io/avaje/http/client/DUrlBuilder.java | 1 + 1 file changed, 1 insertion(+) diff --git a/http-client/src/main/java/io/avaje/http/client/DUrlBuilder.java b/http-client/src/main/java/io/avaje/http/client/DUrlBuilder.java index 2a5b83d18..133888b2d 100644 --- a/http-client/src/main/java/io/avaje/http/client/DUrlBuilder.java +++ b/http-client/src/main/java/io/avaje/http/client/DUrlBuilder.java @@ -28,6 +28,7 @@ public UrlBuilder url(String url) { public UrlBuilder path(String path) { if (path.startsWith("http") && path.contains("://")) { buffer.setLength(0); + buffer.append(path); return this; } buffer.append("/").append(path); From 981eaf2112efccd8ccd9739fe14857cc10615478 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Thu, 19 Oct 2023 16:51:50 +1300 Subject: [PATCH 0955/1323] #323 followup - tidy only and add some extra tests --- .../io/avaje/http/client/DUrlBuilder.java | 2 - .../io/avaje/http/client/DUrlBuilderTest.java | 46 +++++++++++++++++++ 2 files changed, 46 insertions(+), 2 deletions(-) create mode 100644 http-client/src/test/java/io/avaje/http/client/DUrlBuilderTest.java diff --git a/http-client/src/main/java/io/avaje/http/client/DUrlBuilder.java b/http-client/src/main/java/io/avaje/http/client/DUrlBuilder.java index 133888b2d..eb1ee40e1 100644 --- a/http-client/src/main/java/io/avaje/http/client/DUrlBuilder.java +++ b/http-client/src/main/java/io/avaje/http/client/DUrlBuilder.java @@ -15,11 +15,9 @@ final class DUrlBuilder implements UrlBuilder { @Override public UrlBuilder url(String url) { - if (url.startsWith("http") && url.contains("://")) { buffer.setLength(0); } - buffer.append(url); return this; } diff --git a/http-client/src/test/java/io/avaje/http/client/DUrlBuilderTest.java b/http-client/src/test/java/io/avaje/http/client/DUrlBuilderTest.java new file mode 100644 index 000000000..3591dfd5b --- /dev/null +++ b/http-client/src/test/java/io/avaje/http/client/DUrlBuilderTest.java @@ -0,0 +1,46 @@ +package io.avaje.http.client; + +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +class DUrlBuilderTest { + + @Test + void url() { + var uri = UrlBuilder.of("http://foo") + .path("more") + .build(); + + assertThat(uri).isEqualTo("http://foo/more"); + } + + @Test + void url_when_httpPrefix() { + var uri = UrlBuilder.of("http://foo") + .url("http://bar") + .path("more") + .build(); + + assertThat(uri).isEqualTo("http://bar/more"); + } + + @Test + void path_basic() { + var uri = UrlBuilder.of("http://foo") + .path("more") + .build(); + + assertThat(uri).isEqualTo("http://foo/more"); + } + + @Test + void path_when_httpPrefix() { + var uri = UrlBuilder.of("http://foo") + .path("http://bar") + .path("more") + .build(); + + assertThat(uri).isEqualTo("http://bar/more"); + } +} From b9b65484e03165be643d99da41facb45b8542dd0 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Thu, 19 Oct 2023 16:56:01 +1300 Subject: [PATCH 0956/1323] Version 2.0-RC12 --- http-api-javalin/pom.xml | 2 +- http-api/pom.xml | 2 +- http-client-gson-adapter/pom.xml | 4 ++-- http-client/pom.xml | 2 +- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 2 +- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-inject-plugin/pom.xml | 2 +- pom.xml | 2 +- tests/pom.xml | 2 +- tests/test-client-generation/pom.xml | 2 +- tests/test-client/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- 19 files changed, 20 insertions(+), 20 deletions(-) diff --git a/http-api-javalin/pom.xml b/http-api-javalin/pom.xml index 5d35757d1..e4931bedc 100644 --- a/http-api-javalin/pom.xml +++ b/http-api-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC11 + 2.0-RC12 .. diff --git a/http-api/pom.xml b/http-api/pom.xml index 44f30a8dd..ed5b0e928 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC11 + 2.0-RC12 .. diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index 06328f20b..8e524d811 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC11 + 2.0-RC12 avaje-http-client-gson @@ -20,7 +20,7 @@ io.avaje avaje-http-client - 2.0-RC11 + 2.0-RC12 provided diff --git a/http-client/pom.xml b/http-client/pom.xml index 00d64d882..3c4207e6b 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC11 + 2.0-RC12 avaje-http-client diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index 93b660c5a..46817d9bc 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC11 + 2.0-RC12 avaje-http-client-generator diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 6c9a90876..0de0c9f63 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC11 + 2.0-RC12 avaje-http-generator-core diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index 6e4856bf0..a1afc370d 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.0-RC11 + 2.0-RC12 avaje-http-helidon-generator diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index 26f616403..7f7dcffd1 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC11 + 2.0-RC12 avaje-http-javalin-generator diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index b07bedd68..7d33b360f 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC11 + 2.0-RC12 avaje-http-jex-generator diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index b7ed3e57f..e77161541 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC11 + 2.0-RC12 .. diff --git a/pom.xml b/pom.xml index 9e0825313..ea042e400 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-parent - 2.0-RC11 + 2.0-RC12 pom diff --git a/tests/pom.xml b/tests/pom.xml index 683b09aff..3f6f63ea6 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.0-RC11 + 2.0-RC12 tests diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index 73fb08799..8e798c856 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.0-RC11 + 2.0-RC12 test-client-generation diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index 678d7a1ca..5d19edc48 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.0-RC11 + 2.0-RC12 test-client diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 67b486bb9..a2df5edb4 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 2.0-RC11 + 2.0-RC12 test-javalin-jsonb diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 87785de10..b77790a54 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.0-RC11 + 2.0-RC12 test-javalin diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index c451ba6fc..1aca28c8a 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.0-RC11 + 2.0-RC12 test-jex diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index ecf13381b..fbb32279e 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.0-RC11 + 2.0-RC12 test-nima-jsonb diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index f1646ed33..cbc54f3fb 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.0-RC11 + 2.0-RC12 test-nima From 14d5da23357ae6997be90a61b52681de333ddc53 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Thu, 19 Oct 2023 11:55:16 -0400 Subject: [PATCH 0957/1323] change generated formatting --- .../http/generator/client/AnnotationUtil.java | 6 +++++- .../generator/client/ClientMethodWriter.java | 16 +++++++++------- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/AnnotationUtil.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/AnnotationUtil.java index aeb31c6b3..0445e4208 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/AnnotationUtil.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/AnnotationUtil.java @@ -14,13 +14,17 @@ final class AnnotationUtil { private AnnotationUtil() {} public static void writeAnnotations(Append writer, Element element) { + writeAnnotations(writer, element, ""); + } + + public static void writeAnnotations(Append writer, Element element, String indent) { for (final AnnotationMirror annotationMirror : element.getAnnotationMirrors()) { final var type = UType.parse(annotationMirror.getAnnotationType().asElement().asType()); if (type.mainType().startsWith("io.avaje.http") || type.mainType().startsWith("io.swagger")) { continue; } final String annotationName = annotationMirror.getAnnotationType().toString(); - final StringBuilder sb = new StringBuilder(" @").append(annotationName).append("("); + final StringBuilder sb = new StringBuilder(indent).append("@").append(annotationName).append("("); boolean first = true; for (final var entry : annotationMirror.getElementValues().entrySet()) { diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java index 35e609672..32b6cc498 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java @@ -72,15 +72,17 @@ private void methodStart(Append writer) { } method.checkArgumentNames(); - segmentPropertyMap.forEach((k, v) -> { - writer.append(" private static final String %s = ", v); - final String getProperty = useConfig ? "Config.get(" : "System.getProperty("; - writer.append(getProperty).append("\"%s\");", k).eol(); - }); - writer.append(" // %s %s", webMethod, method.webMethodPath()).eol(); + + segmentPropertyMap.forEach( + (k, v) -> { + writer.append(" private static final String %s = ", v); + final String getProperty = useConfig ? "Config.get(" : "System.getProperty("; + writer.append(getProperty).append("\"%s\");", k).eol(); + }); + writer.append(" @Override").eol(); - AnnotationUtil.writeAnnotations(writer, method.element()); + AnnotationUtil.writeAnnotations(writer, method.element()," "); writer.append(" public %s%s %s(", methodGenericParams, returnType.shortType(), method.simpleName()); int count = 0; List params = method.params(); From af883565400aafb9d5f9e16f6d4067f6b1cec284 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 20 Oct 2023 19:27:48 +0000 Subject: [PATCH 0958/1323] Bump nima.version from 4.0.0-RC1 to 4.0.0-RC2 Bumps `nima.version` from 4.0.0-RC1 to 4.0.0-RC2. Updates `io.helidon.webserver:helidon-webserver` from 4.0.0-RC1 to 4.0.0-RC2 Updates `io.helidon.http.media:helidon-http-media-jsonb` from 4.0.0-RC1 to 4.0.0-RC2 --- updated-dependencies: - dependency-name: io.helidon.webserver:helidon-webserver dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: io.helidon.http.media:helidon-http-media-jsonb dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- tests/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/pom.xml b/tests/pom.xml index 3f6f63ea6..47c509102 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -17,7 +17,7 @@ 2.15.3 2.5 9.8 - 4.0.0-RC1 + 4.0.0-RC2 From 0bcbf1aa28cefc0efaf03bd233a2d4f1a424abe5 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Fri, 20 Oct 2023 15:31:05 -0400 Subject: [PATCH 0959/1323] prevent duplicate constants --- .../io/avaje/http/generator/client/ClientMethodWriter.java | 7 +++++++ .../io/avaje/http/generator/client/clients/TitanFall.java | 6 +++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java index 32b6cc498..ee5d93e36 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java @@ -9,6 +9,7 @@ import static java.util.stream.Collectors.toMap; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Optional; @@ -35,6 +36,7 @@ class ClientMethodWriter { private final Optional timeout; private final boolean useConfig; private final Map segmentPropertyMap; + private final Set propertyConstants = new HashSet<>(); ClientMethodWriter(MethodReader method, Append writer, boolean useJsonb) { this.method = method; @@ -76,6 +78,11 @@ private void methodStart(Append writer) { segmentPropertyMap.forEach( (k, v) -> { + + if (!propertyConstants.add(v)) { + return; + } + writer.append(" private static final String %s = ", v); final String getProperty = useConfig ? "Config.get(" : "System.getProperty("; writer.append(getProperty).append("\"%s\");", k).eol(); diff --git a/http-generator-client/src/test/java/io/avaje/http/generator/client/clients/TitanFall.java b/http-generator-client/src/test/java/io/avaje/http/generator/client/clients/TitanFall.java index 21b542e72..918c685fa 100644 --- a/http-generator-client/src/test/java/io/avaje/http/generator/client/clients/TitanFall.java +++ b/http-generator-client/src/test/java/io/avaje/http/generator/client/clients/TitanFall.java @@ -7,5 +7,9 @@ public interface TitanFall { @Get("/${titan}/${drop.point}") - Titan titanfall(); + Titan titanFall(); + + + @Get("/${titan}/copium") + Titan titanFall3(); } \ No newline at end of file From 6332547b4c1442c26235a7bd1c33c3974f228998 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Fri, 20 Oct 2023 15:56:28 -0400 Subject: [PATCH 0960/1323] fix test --- .../http/generator/client/ClientMethodWriter.java | 13 ++++++++----- .../avaje/http/generator/client/ClientWriter.java | 7 +++++-- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java index ee5d93e36..fec5c512a 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java @@ -36,9 +36,10 @@ class ClientMethodWriter { private final Optional timeout; private final boolean useConfig; private final Map segmentPropertyMap; - private final Set propertyConstants = new HashSet<>(); + private final Set propertyConstants; - ClientMethodWriter(MethodReader method, Append writer, boolean useJsonb) { + ClientMethodWriter( + MethodReader method, Append writer, boolean useJsonb, Set propertyConstants) { this.method = method; this.writer = writer; this.webMethod = method.webMethod(); @@ -47,9 +48,11 @@ class ClientMethodWriter { this.timeout = method.timeout(); this.useConfig = ProcessingContext.typeElement("io.avaje.config.Config") != null; - this.segmentPropertyMap = method.pathSegments().segments().stream() - .filter(Segment::isProperty) - .collect(toMap(Segment::name, s -> Util.sanitizeName(s.name()).toUpperCase())); + this.segmentPropertyMap = + method.pathSegments().segments().stream() + .filter(Segment::isProperty) + .collect(toMap(Segment::name, s -> Util.sanitizeName(s.name()).toUpperCase())); + this.propertyConstants = propertyConstants; } void addImportTypes(ControllerReader reader) { diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientWriter.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientWriter.java index 8fba4298b..459615799 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientWriter.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientWriter.java @@ -3,11 +3,12 @@ import io.avaje.http.generator.core.BaseControllerWriter; import io.avaje.http.generator.core.ControllerReader; import io.avaje.http.generator.core.MethodReader; -import io.avaje.http.generator.core.ProcessingContext; import java.io.IOException; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; +import java.util.Set; /** * Write Http client adapter. @@ -21,6 +22,8 @@ class ClientWriter extends BaseControllerWriter { private final List methodList = new ArrayList<>(); private final boolean useJsonb; + private final Set propertyConstants = new HashSet<>(); + ClientWriter(ControllerReader reader, boolean useJsonB) throws IOException { super(reader, SUFFIX); @@ -39,7 +42,7 @@ protected String initPackageName(String originName) { private void readMethods() { for (final MethodReader method : reader.methods()) { if (method.isWebMethod()) { - final var methodWriter = new ClientMethodWriter(method, writer, useJsonb); + final var methodWriter = new ClientMethodWriter(method, writer, useJsonb, propertyConstants); methodWriter.addImportTypes(reader); methodList.add(methodWriter); } From 54f5804bf182317ca01d5c5f4341b12c127c3b33 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Fri, 20 Oct 2023 16:07:28 -0400 Subject: [PATCH 0961/1323] support RC2 --- README.md | 2 +- tests/test-nima-jsonb/src/main/java/org/example/Main.java | 8 +------- .../src/test/java/org/example/TestPair.java | 2 +- tests/test-nima/src/main/java/org/example/Main.java | 2 +- 4 files changed, 4 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 490bf4cfe..311714938 100644 --- a/README.md +++ b/README.md @@ -125,7 +125,7 @@ final var builder = HttpRouting.builder(); routes.forEach(builder::addFeature); WebServer.builder() - .addRouting(builder.build()) + .addRouting(builder) .build() .start(); ``` diff --git a/tests/test-nima-jsonb/src/main/java/org/example/Main.java b/tests/test-nima-jsonb/src/main/java/org/example/Main.java index dd4bf8b14..f56218391 100644 --- a/tests/test-nima-jsonb/src/main/java/org/example/Main.java +++ b/tests/test-nima-jsonb/src/main/java/org/example/Main.java @@ -16,14 +16,8 @@ public static void main(String[] args) { final List list = scope.list(HttpFeature.class); final var builder = HttpRouting.builder(); list.forEach(builder::addFeature); - final var httpRouting = builder.build(); - WebServer.builder() - .addRouting(httpRouting) - // .routing(Main::routing) - .port(8081) - .build() - .start(); + WebServer.builder().addRouting(builder).port(8081).build().start(); System.out.println("started"); } diff --git a/tests/test-nima-jsonb/src/test/java/org/example/TestPair.java b/tests/test-nima-jsonb/src/test/java/org/example/TestPair.java index 958e0b384..40e6d050f 100644 --- a/tests/test-nima-jsonb/src/test/java/org/example/TestPair.java +++ b/tests/test-nima-jsonb/src/test/java/org/example/TestPair.java @@ -15,7 +15,7 @@ public class TestPair { public TestPair() { this.webServer = WebServer.builder() - .routing(routing().build()) + .routing(routing()) .build(); webServer.start(); diff --git a/tests/test-nima/src/main/java/org/example/Main.java b/tests/test-nima/src/main/java/org/example/Main.java index 74768baa8..bb4c3ef89 100644 --- a/tests/test-nima/src/main/java/org/example/Main.java +++ b/tests/test-nima/src/main/java/org/example/Main.java @@ -16,7 +16,7 @@ public static void main(String[] args) { routes.forEach(builder::addFeature); - WebServer.builder().addRouting(builder.build()).build().start(); + WebServer.builder().addRouting(builder).build().start(); System.out.println("started"); } From 812387246f7f3fea7b258a395bf62464e2a37637 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sat, 21 Oct 2023 14:29:51 -0400 Subject: [PATCH 0962/1323] Helidon 4 --- tests/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/pom.xml b/tests/pom.xml index 47c509102..64ba13469 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -17,7 +17,7 @@ 2.15.3 2.5 9.8 - 4.0.0-RC2 + 4.0.0 From 10190f8f9def30aa98984fe242f18d431597edd5 Mon Sep 17 00:00:00 2001 From: Mark Ryan Guamos Date: Sun, 22 Oct 2023 03:37:00 +0800 Subject: [PATCH 0963/1323] any of "NotNull", "NotEmpty", "NotBlank" --- .../avaje/http/generator/core/openapi/SchemaDocBuilder.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/SchemaDocBuilder.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/SchemaDocBuilder.java index 4c08b73f6..5cd52e12b 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/SchemaDocBuilder.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/SchemaDocBuilder.java @@ -9,6 +9,7 @@ import java.util.Map; import java.util.Set; import java.util.TreeMap; +import java.util.stream.Stream; import javax.lang.model.element.AnnotationMirror; import javax.lang.model.element.Element; @@ -296,7 +297,10 @@ private void setLengthMinMax(Element element, Schema propSchema) { private boolean isNotNullable(Element element) { return element.getAnnotationMirrors().stream() - .anyMatch(m -> m.toString().contains("@") && m.toString().contains("NotNull")); + .anyMatch(m -> m.toString().contains("@") && + Stream.of("NotNull", "NotEmpty", "NotBlank") + .anyMatch(annotation -> m.toString().contains(annotation)) + ); } /** From 8fb5a2915e23c51bc514d0807bcb4302b6f117e5 Mon Sep 17 00:00:00 2001 From: Mark Ryan Guamos Date: Sun, 22 Oct 2023 11:51:43 +0800 Subject: [PATCH 0964/1323] added required props --- .../io/avaje/http/generator/core/openapi/SchemaDocBuilder.java | 1 + 1 file changed, 1 insertion(+) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/SchemaDocBuilder.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/SchemaDocBuilder.java index 4c08b73f6..3e262e47c 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/SchemaDocBuilder.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/SchemaDocBuilder.java @@ -249,6 +249,7 @@ private void populateObjectSchema(TypeMirror objectType, Schema objectSch Schema propSchema = toSchema(field.asType()); if (isNotNullable(field)) { propSchema.setNullable(Boolean.FALSE); + objectSchema.addRequiredItem(field.getSimpleName().toString()); } setDescription(field, propSchema); setLengthMinMax(field, propSchema); From 73a95aed3ccc20b88ddf08fd53a05be94fb110b7 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 24 Oct 2023 16:23:18 +1300 Subject: [PATCH 0965/1323] Format only change --- .../generator/client/ClientMethodWriter.java | 21 ++++++++----------- 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java index fec5c512a..dd35c812f 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java @@ -79,20 +79,17 @@ private void methodStart(Append writer) { writer.append(" // %s %s", webMethod, method.webMethodPath()).eol(); - segmentPropertyMap.forEach( - (k, v) -> { - - if (!propertyConstants.add(v)) { - return; - } - - writer.append(" private static final String %s = ", v); - final String getProperty = useConfig ? "Config.get(" : "System.getProperty("; - writer.append(getProperty).append("\"%s\");", k).eol(); - }); + segmentPropertyMap.forEach((k, v) -> { + if (!propertyConstants.add(v)) { + return; + } + writer.append(" private static final String %s = ", v); + final String getProperty = useConfig ? "Config.get(" : "System.getProperty("; + writer.append(getProperty).append("\"%s\");", k).eol(); + }); writer.append(" @Override").eol(); - AnnotationUtil.writeAnnotations(writer, method.element()," "); + AnnotationUtil.writeAnnotations(writer, method.element(), " "); writer.append(" public %s%s %s(", methodGenericParams, returnType.shortType(), method.simpleName()); int count = 0; List params = method.params(); From b5c8e27dff49ab7b1b0eb551dae14f2535b3e805 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 24 Oct 2023 17:36:40 +1300 Subject: [PATCH 0966/1323] Format only change --- .../generator/client/ClientMethodWriter.java | 21 ++++++++----------- 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java index dd35c812f..a9175d406 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java @@ -1,25 +1,23 @@ package io.avaje.http.generator.client; -import static io.avaje.http.generator.core.ProcessingContext.*; import io.avaje.http.generator.core.*; import io.avaje.http.generator.core.PathSegments.Segment; import javax.lang.model.element.TypeElement; import javax.lang.model.util.ElementFilter; - -import static java.util.stream.Collectors.toMap; - -import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; +import static io.avaje.http.generator.core.ProcessingContext.*; +import static java.util.stream.Collectors.toMap; + /** * Write code to register Web route for a given controller method. */ -class ClientMethodWriter { +final class ClientMethodWriter { private static final KnownResponse KNOWN_RESPONSE = new KnownResponse(); private static final String BODY_HANDLER = "java.net.http.HttpResponse.BodyHandler"; @@ -38,8 +36,7 @@ class ClientMethodWriter { private final Map segmentPropertyMap; private final Set propertyConstants; - ClientMethodWriter( - MethodReader method, Append writer, boolean useJsonb, Set propertyConstants) { + ClientMethodWriter(MethodReader method, Append writer, boolean useJsonb, Set propertyConstants) { this.method = method; this.writer = writer; this.webMethod = method.webMethod(); @@ -49,9 +46,9 @@ class ClientMethodWriter { this.useConfig = ProcessingContext.typeElement("io.avaje.config.Config") != null; this.segmentPropertyMap = - method.pathSegments().segments().stream() - .filter(Segment::isProperty) - .collect(toMap(Segment::name, s -> Util.sanitizeName(s.name()).toUpperCase())); + method.pathSegments().segments().stream() + .filter(Segment::isProperty) + .collect(toMap(Segment::name, s -> Util.sanitizeName(s.name()).toUpperCase())); this.propertyConstants = propertyConstants; } @@ -152,7 +149,7 @@ private void writeTimeout(RequestTimeoutPrism p) { writer.append(" .requestTimeout(of(%s, %s))", p.value(), p.chronoUnit()).eol(); } -private void writeEnd() { + private void writeEnd() { final var webMethod = method.webMethod(); writer.append(" .%s()", webMethod.name()).eol(); if (returnType == UType.VOID) { From 51beb5ad92189bd1a75540ef1e832168575a0a7d Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 24 Oct 2023 22:05:14 +1300 Subject: [PATCH 0967/1323] Version 2.0 --- http-api-javalin/pom.xml | 2 +- http-api/pom.xml | 2 +- http-client-gson-adapter/pom.xml | 4 ++-- http-client/pom.xml | 2 +- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 2 +- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-inject-plugin/pom.xml | 2 +- pom.xml | 2 +- tests/pom.xml | 2 +- tests/test-client-generation/pom.xml | 2 +- tests/test-client/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- 19 files changed, 20 insertions(+), 20 deletions(-) diff --git a/http-api-javalin/pom.xml b/http-api-javalin/pom.xml index e4931bedc..2bc7c8e77 100644 --- a/http-api-javalin/pom.xml +++ b/http-api-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC12 + 2.0 .. diff --git a/http-api/pom.xml b/http-api/pom.xml index ed5b0e928..7e36d2e0a 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC12 + 2.0 .. diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index 8e524d811..f1e0c1d7c 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC12 + 2.0 avaje-http-client-gson @@ -20,7 +20,7 @@ io.avaje avaje-http-client - 2.0-RC12 + 2.0 provided diff --git a/http-client/pom.xml b/http-client/pom.xml index 3c4207e6b..7d3ac2732 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC12 + 2.0 avaje-http-client diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index 46817d9bc..ad995299c 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC12 + 2.0 avaje-http-client-generator diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 0de0c9f63..108f813a1 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC12 + 2.0 avaje-http-generator-core diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index a1afc370d..1c3ebfd8f 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.0-RC12 + 2.0 avaje-http-helidon-generator diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index 7f7dcffd1..478815c22 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC12 + 2.0 avaje-http-javalin-generator diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index 7d33b360f..e6636613d 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC12 + 2.0 avaje-http-jex-generator diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index e77161541..7f093e0ca 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0-RC12 + 2.0 .. diff --git a/pom.xml b/pom.xml index ea042e400..c9a8ed374 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-parent - 2.0-RC12 + 2.0 pom diff --git a/tests/pom.xml b/tests/pom.xml index 64ba13469..25f768097 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.0-RC12 + 2.0 tests diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index 8e798c856..9ed820c84 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.0-RC12 + 2.0 test-client-generation diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index 5d19edc48..86df9460c 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.0-RC12 + 2.0 test-client diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index a2df5edb4..5680f61b1 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 2.0-RC12 + 2.0 test-javalin-jsonb diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index b77790a54..65f6f8891 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.0-RC12 + 2.0 test-javalin diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 1aca28c8a..be010b06d 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.0-RC12 + 2.0 test-jex diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index fbb32279e..8477eb922 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.0-RC12 + 2.0 test-nima-jsonb diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index cbc54f3fb..29f8e5150 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.0-RC12 + 2.0 test-nima From d4ffc9da1c96a4a48477c09a694a7524f1af3284 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 24 Oct 2023 22:10:35 +1300 Subject: [PATCH 0968/1323] Bump to next snapshot --- http-api-javalin/pom.xml | 2 +- http-api/pom.xml | 2 +- http-client-gson-adapter/pom.xml | 4 ++-- http-client/pom.xml | 2 +- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 2 +- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-inject-plugin/pom.xml | 2 +- pom.xml | 2 +- tests/pom.xml | 2 +- tests/test-client-generation/pom.xml | 2 +- tests/test-client/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- 19 files changed, 20 insertions(+), 20 deletions(-) diff --git a/http-api-javalin/pom.xml b/http-api-javalin/pom.xml index 2bc7c8e77..1713cc524 100644 --- a/http-api-javalin/pom.xml +++ b/http-api-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0 + 2.1-SNAPSHOT .. diff --git a/http-api/pom.xml b/http-api/pom.xml index 7e36d2e0a..989c575a3 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0 + 2.1-SNAPSHOT .. diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index f1e0c1d7c..dafa8c88a 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0 + 2.1-SNAPSHOT avaje-http-client-gson @@ -20,7 +20,7 @@ io.avaje avaje-http-client - 2.0 + 2.1-SNAPSHOT provided diff --git a/http-client/pom.xml b/http-client/pom.xml index 7d3ac2732..68627ecb7 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0 + 2.1-SNAPSHOT avaje-http-client diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index ad995299c..ca3c5144c 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0 + 2.1-SNAPSHOT avaje-http-client-generator diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 108f813a1..480af4b4c 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0 + 2.1-SNAPSHOT avaje-http-generator-core diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index 1c3ebfd8f..fc9e2e363 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.0 + 2.1-SNAPSHOT avaje-http-helidon-generator diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index 478815c22..3b3538f24 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0 + 2.1-SNAPSHOT avaje-http-javalin-generator diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index e6636613d..86d2c3bee 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0 + 2.1-SNAPSHOT avaje-http-jex-generator diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index 7f093e0ca..48b3c0657 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.0 + 2.1-SNAPSHOT .. diff --git a/pom.xml b/pom.xml index c9a8ed374..f9669e171 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-parent - 2.0 + 2.1-SNAPSHOT pom diff --git a/tests/pom.xml b/tests/pom.xml index 25f768097..2d5a4656b 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.0 + 2.1-SNAPSHOT tests diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index 9ed820c84..15cf478bb 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.0 + 2.1-SNAPSHOT test-client-generation diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index 86df9460c..a3dfcc34e 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.0 + 2.1-SNAPSHOT test-client diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 5680f61b1..9601942cc 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 2.0 + 2.1-SNAPSHOT test-javalin-jsonb diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 65f6f8891..11f8f2cfc 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.0 + 2.1-SNAPSHOT test-javalin diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index be010b06d..f5d9bdb6f 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.0 + 2.1-SNAPSHOT test-jex diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 8477eb922..ec4458113 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.0 + 2.1-SNAPSHOT test-nima-jsonb diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index 29f8e5150..fdc73aecf 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.0 + 2.1-SNAPSHOT test-nima From fa14fca852abd6e03961223b4192736df0edd512 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 24 Oct 2023 19:37:16 +0000 Subject: [PATCH 0969/1323] Bump io.avaje:validator-constraints from 1.1 to 1.2 Bumps io.avaje:validator-constraints from 1.1 to 1.2. --- updated-dependencies: - dependency-name: io.avaje:validator-constraints dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- http-generator-core/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 480af4b4c..92b25ada5 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -47,7 +47,7 @@ io.avaje validator-constraints - 1.1 + 1.2 true provided From 99f111dc0ab391045da65ea5ea646493b4eea9b8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 25 Oct 2023 19:54:46 +0000 Subject: [PATCH 0970/1323] Bump swagger.version from 2.2.17 to 2.2.18 Bumps `swagger.version` from 2.2.17 to 2.2.18. Updates `io.swagger.core.v3:swagger-annotations` from 2.2.17 to 2.2.18 Updates `io.swagger.core.v3:swagger-models` from 2.2.17 to 2.2.18 --- updated-dependencies: - dependency-name: io.swagger.core.v3:swagger-annotations dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: io.swagger.core.v3:swagger-models dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index f9669e171..a7d294276 100644 --- a/pom.xml +++ b/pom.xml @@ -19,7 +19,7 @@ true - 2.2.17 + 2.2.18 2.14.2 1.16 ${project.build.directory}${file.separator}module-info.shade diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 9601942cc..2f5186d78 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -14,7 +14,7 @@ true org.example.myapp.Main 5.6.3 - 2.2.17 + 2.2.18 1.3.71 diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 11f8f2cfc..be430043b 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -13,7 +13,7 @@ true org.example.myapp.Main 5.6.3 - 2.2.17 + 2.2.18 1.3.71 diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index f5d9bdb6f..a67c8e210 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -13,7 +13,7 @@ true org.example.myapp.Main 2.5 - 2.2.17 + 2.2.18 From fd868a922fcd342921773e8bf05f8525f4ec7e0a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 25 Oct 2023 19:57:57 +0000 Subject: [PATCH 0971/1323] Bump io.avaje:junit from 1.1 to 1.3 Bumps io.avaje:junit from 1.1 to 1.3. --- updated-dependencies: - dependency-name: io.avaje:junit dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- http-client-gson-adapter/pom.xml | 2 +- http-client/pom.xml | 2 +- pom.xml | 2 +- tests/test-client/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index dafa8c88a..689c1e00d 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -29,7 +29,7 @@ io.avaje junit - 1.1 + 1.3 test diff --git a/http-client/pom.xml b/http-client/pom.xml index 68627ecb7..f5945e811 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -59,7 +59,7 @@ io.avaje junit - 1.1 + 1.3 test diff --git a/pom.xml b/pom.xml index a7d294276..dc9e928b1 100644 --- a/pom.xml +++ b/pom.xml @@ -29,7 +29,7 @@ io.avaje junit - 1.1 + 1.3 test diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index a3dfcc34e..fed2bc3de 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -44,7 +44,7 @@ io.avaje junit - 1.1 + 1.3 test diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 2f5186d78..adb5f0c5e 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -95,7 +95,7 @@ io.avaje junit - 1.1 + 1.3 test diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index be430043b..8c94eaa9a 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -88,7 +88,7 @@ io.avaje junit - 1.1 + 1.3 test diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index a67c8e210..2d9c27a7b 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -87,7 +87,7 @@ io.avaje junit - 1.1 + 1.3 test diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index ec4458113..7172f7d62 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -60,7 +60,7 @@ io.avaje junit - 1.1 + 1.3 test From 0609952c333b477bb08c02f66edc68d317fa62f2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 27 Oct 2023 19:36:50 +0000 Subject: [PATCH 0972/1323] Bump avaje-inject.version from 9.8 to 9.9 Bumps `avaje-inject.version` from 9.8 to 9.9. Updates `io.avaje:avaje-inject` from 9.8 to 9.9 - [Release notes](https://github.com/avaje/avaje-inject/releases) - [Commits](https://github.com/avaje/avaje-inject/compare/9.8...9.9) Updates `io.avaje:avaje-inject-generator` from 9.8 to 9.9 --- updated-dependencies: - dependency-name: io.avaje:avaje-inject dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: io.avaje:avaje-inject-generator dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- http-client/pom.xml | 4 ++-- http-inject-plugin/pom.xml | 2 +- tests/pom.xml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/http-client/pom.xml b/http-client/pom.xml index f5945e811..470744e45 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -43,7 +43,7 @@ io.avaje avaje-inject - 9.8 + 9.9 true @@ -106,7 +106,7 @@ io.avaje avaje-inject-generator - 9.8 + 9.9 diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index 48b3c0657..b0d9854fc 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -19,7 +19,7 @@ io.avaje avaje-inject - 9.8 + 9.9 provided true diff --git a/tests/pom.xml b/tests/pom.xml index 2d5a4656b..6c8eee3c1 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -16,7 +16,7 @@ 3.24.2 2.15.3 2.5 - 9.8 + 9.9 4.0.0 From 9a22e248507ebf4dc6969ae4a1485c2563c871c1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 30 Oct 2023 19:57:11 +0000 Subject: [PATCH 0973/1323] Bump io.avaje:avaje-jsonb-generator from 1.7-RC1 to 1.9 Bumps io.avaje:avaje-jsonb-generator from 1.7-RC1 to 1.9. --- updated-dependencies: - dependency-name: io.avaje:avaje-jsonb-generator dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index adb5f0c5e..1351c1d1a 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -87,7 +87,7 @@ io.avaje avaje-jsonb-generator - 1.8 + 1.9 provided diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 7172f7d62..07c51cf68 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -93,7 +93,7 @@ io.avaje avaje-jsonb-generator - 1.7-RC1 + 1.9 From 17f2b230d25010177d0ca2acb5c02000cff18852 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 30 Oct 2023 19:59:51 +0000 Subject: [PATCH 0974/1323] Bump io.avaje:avaje-jsonb from 1.8 to 1.9 Bumps [io.avaje:avaje-jsonb](https://github.com/avaje/avaje-jsonb) from 1.8 to 1.9. - [Release notes](https://github.com/avaje/avaje-jsonb/releases) - [Commits](https://github.com/avaje/avaje-jsonb/compare/1.8...1.9) --- updated-dependencies: - dependency-name: io.avaje:avaje-jsonb dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- http-client/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/http-client/pom.xml b/http-client/pom.xml index 470744e45..13512563d 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -36,7 +36,7 @@ io.avaje avaje-jsonb - 1.8 + 1.9 true diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 1351c1d1a..35e776f40 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -81,7 +81,7 @@ io.avaje avaje-jsonb - 1.8 + 1.9 diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 07c51cf68..4d10ce3a2 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -34,7 +34,7 @@ io.avaje avaje-jsonb - 1.8 + 1.9 io.avaje From b1d42157f7abdaf16149611e564753c9967b3cee Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Mon, 30 Oct 2023 16:00:55 -0400 Subject: [PATCH 0975/1323] Update ElementReader.java --- .../main/java/io/avaje/http/generator/core/ElementReader.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java index a9e91d53b..d219f4a7f 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java @@ -76,7 +76,7 @@ public class ElementReader { if (!contextType) { readAnnotations(element, defaultType); useValidation = useValidation(); - HttpValidPrism.getOptionalOn(element).map(HttpValidPrism::groups).stream() + HttpValidPrism.getOptionalOn(element.getEnclosingElement()).map(HttpValidPrism::groups).stream() .flatMap(List::stream) .map(TypeMirror::toString) .forEach(validationGroups::add); From 9db6d8808403c6d6d4fe78392e2ed4f29d357be5 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Wed, 1 Nov 2023 17:21:33 -0400 Subject: [PATCH 0976/1323] Javalin 6-beta Support (#341) * more valid test * javalin 6 * fix validation groups * fix tests * actually fix --- .../avaje/http/api/javalin/AfterMatched.java | 23 +++++++++++++ .../avaje/http/api/javalin/BeforeMatched.java | 23 +++++++++++++ http-api/pom.xml | 8 +++++ .../io/avaje/http/api/AvajeJavalinPlugin.java | 9 +++++ .../java/io/avaje/http/api/Validator.java | 5 +-- http-api/src/main/java/module-info.java | 2 ++ .../http/generator/core/ElementReader.java | 4 +-- .../generator/core/ProcessingContext.java | 6 ++++ .../javalin/AbstractCustomMethodPrism.java | 9 +++-- .../javalin/ControllerMethodWriter.java | 3 +- .../generator/javalin/ControllerWriter.java | 34 +++++++++++++++---- .../generator/javalin/JavalinAdapter.java | 14 +++++--- .../generator/javalin/JavalinProcessor.java | 4 +++ .../generator/javalin/JavalinWebMethod.java | 6 ++-- tests/test-javalin-jsonb/pom.xml | 2 +- .../src/main/java/org/example/myapp/Main.java | 18 ++++++---- tests/test-javalin/pom.xml | 2 +- .../src/main/java/org/example/myapp/Main.java | 16 ++++----- .../main/java/org/example/TestController.java | 32 +++++++++++++---- .../src/test/java/org/example/MyForm2.java | 11 ++++++ .../java/org/example/TestControllerTest.java | 10 +++--- .../src/test/java/org/example/TestPair.java | 3 +- 22 files changed, 195 insertions(+), 49 deletions(-) create mode 100644 http-api-javalin/src/main/java/io/avaje/http/api/javalin/AfterMatched.java create mode 100644 http-api-javalin/src/main/java/io/avaje/http/api/javalin/BeforeMatched.java create mode 100644 http-api/src/main/java/io/avaje/http/api/AvajeJavalinPlugin.java create mode 100644 tests/test-nima-jsonb/src/test/java/org/example/MyForm2.java diff --git a/http-api-javalin/src/main/java/io/avaje/http/api/javalin/AfterMatched.java b/http-api-javalin/src/main/java/io/avaje/http/api/javalin/AfterMatched.java new file mode 100644 index 000000000..4d87efb94 --- /dev/null +++ b/http-api-javalin/src/main/java/io/avaje/http/api/javalin/AfterMatched.java @@ -0,0 +1,23 @@ +package io.avaje.http.api.javalin; + +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.RetentionPolicy.SOURCE; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +/** + * Marks a method that handles Javalin afterMatched requests. + * + *

    {@code
    + *
    + *  @AfterMatched
    + *  void save(Customer customer) {
    + *    ...
    + *  }
    + *
    + * }
    + */ +@Target(METHOD) +@Retention(SOURCE) +public @interface AfterMatched {} diff --git a/http-api-javalin/src/main/java/io/avaje/http/api/javalin/BeforeMatched.java b/http-api-javalin/src/main/java/io/avaje/http/api/javalin/BeforeMatched.java new file mode 100644 index 000000000..5293f92fb --- /dev/null +++ b/http-api-javalin/src/main/java/io/avaje/http/api/javalin/BeforeMatched.java @@ -0,0 +1,23 @@ +package io.avaje.http.api.javalin; + +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.RetentionPolicy.SOURCE; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +/** + * Marks a method that handles Javalin beforeMatched requests. + * + *
    {@code
    + *
    + *  @BeforeMatched
    + *  void save(Customer customer) {
    + *    ...
    + *  }
    + *
    + * }
    + */ +@Target(METHOD) +@Retention(SOURCE) +public @interface BeforeMatched {} diff --git a/http-api/pom.xml b/http-api/pom.xml index 989c575a3..24a542d47 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -21,6 +21,14 @@ avaje-http-inject-plugin ${project.version} + + io.javalin + javalin + 6.0.0-beta.1 + provided + true + + diff --git a/http-api/src/main/java/io/avaje/http/api/AvajeJavalinPlugin.java b/http-api/src/main/java/io/avaje/http/api/AvajeJavalinPlugin.java new file mode 100644 index 000000000..f5e3717e8 --- /dev/null +++ b/http-api/src/main/java/io/avaje/http/api/AvajeJavalinPlugin.java @@ -0,0 +1,9 @@ +package io.avaje.http.api; + +import io.javalin.plugin.Plugin; + +public abstract class AvajeJavalinPlugin extends Plugin { + + protected AvajeJavalinPlugin() {} + +} diff --git a/http-api/src/main/java/io/avaje/http/api/Validator.java b/http-api/src/main/java/io/avaje/http/api/Validator.java index 374500e55..19c69fd65 100644 --- a/http-api/src/main/java/io/avaje/http/api/Validator.java +++ b/http-api/src/main/java/io/avaje/http/api/Validator.java @@ -6,6 +6,7 @@ import java.util.Locale.LanguageRange; /** Validator for form beans or request beans. */ +@FunctionalInterface public interface Validator { /** @@ -18,11 +19,11 @@ public interface Validator { */ void validate(Object bean, String acceptLanguage, Class... groups) throws ValidationException; - default Locale resolveLocale(String acceptLanguage, Collection acceptLocales) { + default Locale resolveLocale(String acceptLanguage, Collection acceptedLocales) { if (acceptLanguage == null) { return null; } final List list = LanguageRange.parse(acceptLanguage); - return Locale.lookup(list, acceptLocales); + return Locale.lookup(list, acceptedLocales); } } diff --git a/http-api/src/main/java/module-info.java b/http-api/src/main/java/module-info.java index 5fe2e429f..2e95d7bf9 100644 --- a/http-api/src/main/java/module-info.java +++ b/http-api/src/main/java/module-info.java @@ -3,4 +3,6 @@ exports io.avaje.http.api; exports io.avaje.http.api.context; exports io.avaje.http.api.spi; + + requires static io.javalin; } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java index d219f4a7f..358a8d85b 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java @@ -240,7 +240,7 @@ public void overrideVarName(String name, ParamType paramType) { } public void overrideVarName(int position) { - if (paramName.equals("arg" + position)) { + if (("arg" + position).equals(paramName)) { overrideVarNameError = true; // varName += " /** @QueryParam(name=...) required */ "; } else { @@ -298,7 +298,7 @@ void writeValidate(Append writer) { if (useValidation) { writer.append("%s validator.validate(%s, ", indent, varName); platform().writeAcceptLanguage(writer); - validationGroups.forEach(g -> writer.append(", %s", Util.shortName(g))); + validationGroups.forEach(g -> writer.append(", %s.class", Util.shortName(g))); writer.append(");").eol(); } else { writer.append("%s // no validation required on %s", indent, varName).eol(); diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java index 4646a0834..85efa8d16 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java @@ -51,6 +51,7 @@ private static final class Ctx { private final String diAnnotation; private final boolean instrumentAllMethods; private final boolean disableDirectWrites; + private final boolean javalin6; private ModuleElement module; private boolean validated; @@ -85,6 +86,7 @@ private static final class Ctx { } else { useJavax = (javax); } + this.javalin6 = elementUtils.getTypeElement("io.javalin.config.JavalinConfig") != null; } } @@ -210,6 +212,10 @@ public static boolean disabledDirectWrites() { return CTX.get().disableDirectWrites; } + public static boolean javalin6() { + return CTX.get().javalin6; + } + public static Filer filer() { return CTX.get().filer; } diff --git a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/AbstractCustomMethodPrism.java b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/AbstractCustomMethodPrism.java index ea8afbc09..704a14b8a 100644 --- a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/AbstractCustomMethodPrism.java +++ b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/AbstractCustomMethodPrism.java @@ -1,5 +1,6 @@ package io.avaje.http.generator.javalin; +import static io.avaje.http.generator.javalin.JavalinWebMethod.*; import io.avaje.http.generator.core.CustomWebMethod; import io.avaje.http.generator.core.WebMethod; @@ -8,9 +9,13 @@ public abstract class AbstractCustomMethodPrism implements CustomWebMethod { @Override public WebMethod webMethod() { if (this instanceof AfterPrism) { - return JavalinWebMethod.AFTER; + return AFTER; + } else if (this instanceof BeforePrism) { + return BEFORE; + } else if (this instanceof AfterMatchedPrism) { + return AFTER_MATCHED; } else { - return JavalinWebMethod.BEFORE; + return BEFORE_MATCHED; } } } diff --git a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java index c8a9bac0b..3cda06122 100644 --- a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java +++ b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java @@ -98,7 +98,8 @@ private void writeMethod(final String fullPath) { if (method.isErrorMethod()) { writer.append(" app.exception(%s.class, (ex, ctx) -> {", method.exceptionShortName()).eol(); } else { - writer.append(" app.%s(\"%s\", ctx -> {", webMethod.name().toLowerCase(), fullPath).eol(); + var methodName = webMethod.name().toLowerCase().replace("_m", "M"); + writer.append(" app.%s(\"%s\", ctx -> {", methodName, fullPath).eol(); } if (!customMethod) { int statusCode = method.statusCode(); diff --git a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java index bc8d96c47..6fc8edf36 100644 --- a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java +++ b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java @@ -11,6 +11,7 @@ import io.avaje.http.generator.core.JsonBUtil; import io.avaje.http.generator.core.MethodReader; import io.avaje.http.generator.core.PrimitiveUtil; +import io.avaje.http.generator.core.ProcessingContext; import io.avaje.http.generator.core.UType; /** @@ -21,6 +22,7 @@ class ControllerWriter extends BaseControllerWriter { private static final String AT_GENERATED = "@Generated(\"avaje-javalin-generator\")"; private final boolean useJsonB; private final Map jsonTypes; + private final boolean javalin6 = ProcessingContext.javalin6(); ControllerWriter(ControllerReader reader, boolean jsonb) throws IOException { super(reader); @@ -36,7 +38,15 @@ class ControllerWriter extends BaseControllerWriter { this.jsonTypes = Map.of(); } reader.addImportType("io.javalin.plugin.Plugin"); - reader.addImportType("io.javalin.Javalin"); + + if (javalin6) { + + reader.addImportType("io.javalin.config.JavalinConfig"); + reader.addImportType("io.javalin.router.JavalinDefaultRouting"); + reader.addImportType("io.avaje.http.api.AvajeJavalinPlugin"); + } else { + reader.addImportType("io.javalin.Javalin"); + } } void write() { @@ -49,7 +59,17 @@ void write() { private void writeAddRoutes() { writer.append(" @Override").eol(); - writer.append(" public void apply(Javalin app) {").eol().eol(); + + if (javalin6) { + writer.append(" public void onStart(JavalinConfig cfg) {").eol(); + writer.append(" cfg.router.mount(this::routes);").eol(); + writer.append(" }").eol().eol(); + + writer.append(" private void routes(JavalinDefaultRouting app) {").eol().eol(); + } else { + writer.append(" public void apply(Javalin app) {").eol().eol(); + } + for (final MethodReader method : reader.methods()) { if (method.isWebMethod()) { writeForMethod(method); @@ -69,11 +89,11 @@ private void writeClassStart() { writer.append(AT_GENERATED).eol(); writer.append(diAnnotation()).eol(); writer - .append("public class ") - .append(shortName) - .append("$Route implements Plugin {") - .eol() - .eol(); + .append("public class ") + .append(shortName) + .append(javalin6 ? "$Route extends AvajeJavalinPlugin {" : "$Route implements Plugin {") + .eol() + .eol(); var controllerName = "controller"; var controllerType = shortName; diff --git a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinAdapter.java b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinAdapter.java index 28cffffe1..e2df0cc8f 100644 --- a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinAdapter.java +++ b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinAdapter.java @@ -141,9 +141,15 @@ public void writeAcceptLanguage(Append writer) { @Override public List>> customHandlers() { - final Function f = AfterPrism::getInstanceOn; - final Function f2 = BeforePrism::getInstanceOn; - - return List.of(f.andThen(Optional::ofNullable), f2.andThen(Optional::ofNullable)); + final Function after = AfterPrism::getInstanceOn; + final Function before = BeforePrism::getInstanceOn; + final Function afterMatched = AfterMatchedPrism::getInstanceOn; + final Function beforeMatched = BeforeMatchedPrism::getInstanceOn; + + return List.of( + after.andThen(Optional::ofNullable), + before.andThen(Optional::ofNullable), + afterMatched.andThen(Optional::ofNullable), + beforeMatched.andThen(Optional::ofNullable)); } } diff --git a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinProcessor.java b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinProcessor.java index 5d74360aa..65c0d6f9c 100644 --- a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinProcessor.java +++ b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinProcessor.java @@ -3,7 +3,9 @@ import java.io.IOException; import io.avaje.http.api.javalin.After; +import io.avaje.http.api.javalin.AfterMatched; import io.avaje.http.api.javalin.Before; +import io.avaje.http.api.javalin.BeforeMatched; import io.avaje.http.generator.core.BaseProcessor; import io.avaje.http.generator.core.ControllerReader; import io.avaje.http.generator.core.PlatformAdapter; @@ -12,6 +14,8 @@ @GeneratePrism(value = After.class, superClass = AbstractCustomMethodPrism.class) @GeneratePrism(value = Before.class, superClass = AbstractCustomMethodPrism.class) +@GeneratePrism(value = AfterMatched.class, superClass = AbstractCustomMethodPrism.class) +@GeneratePrism(value = BeforeMatched.class, superClass = AbstractCustomMethodPrism.class) public class JavalinProcessor extends BaseProcessor { @Override diff --git a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinWebMethod.java b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinWebMethod.java index 77e4aafb1..8c846cc2f 100644 --- a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinWebMethod.java +++ b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/JavalinWebMethod.java @@ -4,9 +4,11 @@ public enum JavalinWebMethod implements WebMethod { BEFORE(0), - AFTER(0); + BEFORE_MATCHED(0), + AFTER(0), + AFTER_MATCHED(0); - private int statusCode; + private final int statusCode; JavalinWebMethod(int statusCode) { this.statusCode = statusCode; diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 35e776f40..f25d0b3ff 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -13,7 +13,7 @@ true org.example.myapp.Main - 5.6.3 + 6.0.0-beta.1 2.2.18 1.3.71 diff --git a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/Main.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/Main.java index 1bbbd6f41..2bbc77fc9 100644 --- a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/Main.java +++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/Main.java @@ -7,13 +7,16 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import io.avaje.http.api.AvajeJavalinPlugin; import io.avaje.http.api.InvalidPathArgumentException; import io.avaje.http.api.InvalidTypeArgumentException; import io.avaje.http.api.ValidationException; import io.avaje.http.api.Validator; import io.avaje.inject.BeanScope; import io.avaje.inject.InjectModule; +import io.avaje.inject.spi.GenericType; import io.javalin.Javalin; +import io.javalin.config.JavalinConfig; import io.javalin.http.staticfiles.Location; import io.javalin.plugin.Plugin; import io.swagger.v3.oas.annotations.OpenAPIDefinition; @@ -37,19 +40,20 @@ public static Javalin start(int port) { // All WebRoutes / Controllers ... from DI Context final var beanScope = BeanScope.builder().build(); - final List webRoutes = beanScope.list(Plugin.class); + final List webRoutes = + beanScope.list(AvajeJavalinPlugin.class); final var app = Javalin.create( config -> { config.showJavalinBanner = false; config.staticFiles.add("public", Location.CLASSPATH); - config.accessManager( - (handler, ctx, permittedRoles) -> { - log.debug("allow access ..."); - handler.handle(ctx); - }); - webRoutes.forEach(config.plugins::register); + // config.accessManager( + // (handler, ctx, permittedRoles) -> { + // log.debug("allow access ..."); + // handler.handle(ctx); + // }); + webRoutes.forEach(config::registerPlugin); }); app.exception(ValidationException.class, (exception, ctx) -> { diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 8c94eaa9a..c2b8a2741 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -12,7 +12,7 @@ true org.example.myapp.Main - 5.6.3 + 6.0.0-beta.1 2.2.18 1.3.71 diff --git a/tests/test-javalin/src/main/java/org/example/myapp/Main.java b/tests/test-javalin/src/main/java/org/example/myapp/Main.java index d6958ec0d..532e1b153 100644 --- a/tests/test-javalin/src/main/java/org/example/myapp/Main.java +++ b/tests/test-javalin/src/main/java/org/example/myapp/Main.java @@ -7,6 +7,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import io.avaje.http.api.AvajeJavalinPlugin; import io.avaje.http.api.InvalidPathArgumentException; import io.avaje.http.api.InvalidTypeArgumentException; import io.avaje.http.api.ValidationException; @@ -15,7 +16,6 @@ import io.avaje.inject.InjectModule; import io.javalin.Javalin; import io.javalin.http.staticfiles.Location; -import io.javalin.plugin.Plugin; import io.swagger.v3.oas.annotations.OpenAPIDefinition; import io.swagger.v3.oas.annotations.info.Info; @@ -33,19 +33,19 @@ public static Javalin start(int port) { // All WebRoutes / Controllers ... from DI Context final var beanScope = BeanScope.builder().build(); - final List webRoutes = beanScope.list(Plugin.class); + final List webRoutes = beanScope.list(AvajeJavalinPlugin.class); final var app = Javalin.create( config -> { config.showJavalinBanner = false; config.staticFiles.add("public", Location.CLASSPATH); - config.accessManager( - (handler, ctx, permittedRoles) -> { - log.debug("allow access ..."); - handler.handle(ctx); - }); - webRoutes.forEach(config.plugins::register); +// config.accessManager( +// (handler, ctx, permittedRoles) -> { +// log.debug("allow access ..."); +// handler.handle(ctx); +// }); + webRoutes.forEach(config::registerPlugin); }); app.exception( diff --git a/tests/test-nima-jsonb/src/main/java/org/example/TestController.java b/tests/test-nima-jsonb/src/main/java/org/example/TestController.java index 2bc9d81be..09039d53a 100644 --- a/tests/test-nima-jsonb/src/main/java/org/example/TestController.java +++ b/tests/test-nima-jsonb/src/main/java/org/example/TestController.java @@ -1,17 +1,30 @@ package org.example; -import io.avaje.http.api.*; -import io.helidon.webserver.http.FilterChain; -import io.helidon.webserver.http.RoutingResponse; -import io.helidon.webserver.http.ServerRequest; -import io.helidon.webserver.http.ServerResponse; - import java.io.InputStream; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; +import io.avaje.http.api.BodyString; +import io.avaje.http.api.Controller; +import io.avaje.http.api.Default; +import io.avaje.http.api.ExceptionHandler; +import io.avaje.http.api.Filter; +import io.avaje.http.api.Form; +import io.avaje.http.api.FormParam; +import io.avaje.http.api.Get; +import io.avaje.http.api.InstrumentServerContext; +import io.avaje.http.api.Path; +import io.avaje.http.api.Post; +import io.avaje.http.api.Produces; +import io.avaje.http.api.QueryParam; +import io.avaje.http.api.Valid; +import io.helidon.webserver.http.FilterChain; +import io.helidon.webserver.http.RoutingResponse; +import io.helidon.webserver.http.ServerRequest; +import io.helidon.webserver.http.ServerResponse; + @Path("test") @Controller public class TestController { @@ -120,4 +133,11 @@ void filter(FilterChain chain, RoutingResponse res) { System.err.println("do nothing lmao"); chain.proceed(); } + + @Form + @Valid(groups = MyForm.class) + @Post("formBean2") + String formBean(MyForm form) { + return form.name + "|" + form.email + "|" + form.url; + } } diff --git a/tests/test-nima-jsonb/src/test/java/org/example/MyForm2.java b/tests/test-nima-jsonb/src/test/java/org/example/MyForm2.java new file mode 100644 index 000000000..23ee9fa7c --- /dev/null +++ b/tests/test-nima-jsonb/src/test/java/org/example/MyForm2.java @@ -0,0 +1,11 @@ +package org.example; + +import io.avaje.http.api.Valid; + +@Valid +public class MyForm2 { + + public String name; + public String email; + public String url; +} diff --git a/tests/test-nima-jsonb/src/test/java/org/example/TestControllerTest.java b/tests/test-nima-jsonb/src/test/java/org/example/TestControllerTest.java index a02981546..e53efa38a 100644 --- a/tests/test-nima-jsonb/src/test/java/org/example/TestControllerTest.java +++ b/tests/test-nima-jsonb/src/test/java/org/example/TestControllerTest.java @@ -1,13 +1,13 @@ package org.example; -import io.avaje.http.client.HttpClient; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.Test; +import static org.assertj.core.api.Assertions.assertThat; import java.net.http.HttpResponse; -import static org.assertj.core.api.Assertions.as; -import static org.assertj.core.api.Assertions.assertThat; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.Test; + +import io.avaje.http.client.HttpClient; class TestControllerTest { diff --git a/tests/test-nima-jsonb/src/test/java/org/example/TestPair.java b/tests/test-nima-jsonb/src/test/java/org/example/TestPair.java index 40e6d050f..6ab76b5d9 100644 --- a/tests/test-nima-jsonb/src/test/java/org/example/TestPair.java +++ b/tests/test-nima-jsonb/src/test/java/org/example/TestPair.java @@ -1,5 +1,6 @@ package org.example; +import io.avaje.http.api.Validator; import io.avaje.http.api.context.ThreadLocalRequestContextResolver; import io.avaje.http.client.HttpClient; import io.avaje.http.hibernate.validator.BeanValidator; @@ -50,7 +51,7 @@ private static HttpRouting.Builder routing() { var cr = new ThreadLocalRequestContextResolver(); var tc = new TestController(); - TestController$Route tcr = new TestController$Route(tc, jsonb, cr); + TestController$Route tcr = new TestController$Route(tc, (a,b,c)->{}, jsonb, cr); routing.addFeature(tcr); return routing; From d8be3d44d263b2a9c537cb050bc5bc10839cbbaf Mon Sep 17 00:00:00 2001 From: "robin.bygrave" Date: Thu, 2 Nov 2023 11:36:24 +1300 Subject: [PATCH 0977/1323] Javadoc for AvajeJavalinPlugin and tidy javalin ControllerWriter only --- .../io/avaje/http/api/AvajeJavalinPlugin.java | 3 +++ .../http/generator/javalin/ControllerWriter.java | 15 +++++---------- .../src/main/java/org/example/myapp/Main.java | 3 +-- .../src/main/resources/public/openapi.json | 5 ++++- .../src/main/java/org/example/myapp/Main.java | 2 +- .../src/main/resources/public/openapi.json | 3 +++ .../src/main/resources/public/openapi.json | 3 +++ 7 files changed, 20 insertions(+), 14 deletions(-) diff --git a/http-api/src/main/java/io/avaje/http/api/AvajeJavalinPlugin.java b/http-api/src/main/java/io/avaje/http/api/AvajeJavalinPlugin.java index f5e3717e8..503aba080 100644 --- a/http-api/src/main/java/io/avaje/http/api/AvajeJavalinPlugin.java +++ b/http-api/src/main/java/io/avaje/http/api/AvajeJavalinPlugin.java @@ -2,6 +2,9 @@ import io.javalin.plugin.Plugin; +/** + * A Javalin 6 route generated by avaje http javalin generator. + */ public abstract class AvajeJavalinPlugin extends Plugin { protected AvajeJavalinPlugin() {} diff --git a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java index 6fc8edf36..03fbbfca5 100644 --- a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java +++ b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java @@ -27,7 +27,6 @@ class ControllerWriter extends BaseControllerWriter { ControllerWriter(ControllerReader reader, boolean jsonb) throws IOException { super(reader); this.useJsonB = jsonb; - if (useJsonB) { reader.addImportType("io.avaje.jsonb.Jsonb"); reader.addImportType("io.avaje.jsonb.JsonType"); @@ -38,9 +37,7 @@ class ControllerWriter extends BaseControllerWriter { this.jsonTypes = Map.of(); } reader.addImportType("io.javalin.plugin.Plugin"); - if (javalin6) { - reader.addImportType("io.javalin.config.JavalinConfig"); reader.addImportType("io.javalin.router.JavalinDefaultRouting"); reader.addImportType("io.avaje.http.api.AvajeJavalinPlugin"); @@ -59,12 +56,10 @@ void write() { private void writeAddRoutes() { writer.append(" @Override").eol(); - if (javalin6) { writer.append(" public void onStart(JavalinConfig cfg) {").eol(); writer.append(" cfg.router.mount(this::routes);").eol(); writer.append(" }").eol().eol(); - writer.append(" private void routes(JavalinDefaultRouting app) {").eol().eol(); } else { writer.append(" public void apply(Javalin app) {").eol().eol(); @@ -89,11 +84,11 @@ private void writeClassStart() { writer.append(AT_GENERATED).eol(); writer.append(diAnnotation()).eol(); writer - .append("public class ") - .append(shortName) - .append(javalin6 ? "$Route extends AvajeJavalinPlugin {" : "$Route implements Plugin {") - .eol() - .eol(); + .append("public class ") + .append(shortName) + .append(javalin6 ? "$Route extends AvajeJavalinPlugin {" : "$Route implements Plugin {") + .eol() + .eol(); var controllerName = "controller"; var controllerType = shortName; diff --git a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/Main.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/Main.java index 2bbc77fc9..bc60063fc 100644 --- a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/Main.java +++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/Main.java @@ -40,8 +40,7 @@ public static Javalin start(int port) { // All WebRoutes / Controllers ... from DI Context final var beanScope = BeanScope.builder().build(); - final List webRoutes = - beanScope.list(AvajeJavalinPlugin.class); + final var webRoutes = beanScope.list(AvajeJavalinPlugin.class); final var app = Javalin.create( diff --git a/tests/test-javalin-jsonb/src/main/resources/public/openapi.json b/tests/test-javalin-jsonb/src/main/resources/public/openapi.json index 9fc694f3f..ea3caca39 100644 --- a/tests/test-javalin-jsonb/src/main/resources/public/openapi.json +++ b/tests/test-javalin-jsonb/src/main/resources/public/openapi.json @@ -1,7 +1,7 @@ { "openapi" : "3.0.1", "info" : { - "title" : "Example service showing off the Path extension method of controller", + "title" : "Example service", "description" : "Example Javalin controllers with Java and Maven", "version" : "" }, @@ -2104,6 +2104,9 @@ } }, "HelloForm" : { + "required" : [ + "name" + ], "type" : "object", "properties" : { "name" : { diff --git a/tests/test-javalin/src/main/java/org/example/myapp/Main.java b/tests/test-javalin/src/main/java/org/example/myapp/Main.java index 532e1b153..c08fbd8d9 100644 --- a/tests/test-javalin/src/main/java/org/example/myapp/Main.java +++ b/tests/test-javalin/src/main/java/org/example/myapp/Main.java @@ -33,7 +33,7 @@ public static Javalin start(int port) { // All WebRoutes / Controllers ... from DI Context final var beanScope = BeanScope.builder().build(); - final List webRoutes = beanScope.list(AvajeJavalinPlugin.class); + final var webRoutes = beanScope.list(AvajeJavalinPlugin.class); final var app = Javalin.create( diff --git a/tests/test-javalin/src/main/resources/public/openapi.json b/tests/test-javalin/src/main/resources/public/openapi.json index 5b8ec8241..ddd3021e2 100644 --- a/tests/test-javalin/src/main/resources/public/openapi.json +++ b/tests/test-javalin/src/main/resources/public/openapi.json @@ -872,6 +872,9 @@ } }, "HelloForm" : { + "required" : [ + "name" + ], "type" : "object", "properties" : { "name" : { diff --git a/tests/test-jex/src/main/resources/public/openapi.json b/tests/test-jex/src/main/resources/public/openapi.json index ac5b2453c..c0c78a221 100644 --- a/tests/test-jex/src/main/resources/public/openapi.json +++ b/tests/test-jex/src/main/resources/public/openapi.json @@ -430,6 +430,9 @@ "components" : { "schemas" : { "HelloDto" : { + "required" : [ + "name" + ], "type" : "object", "properties" : { "id" : { From 590fdb8e4ef3d20cbdeff3e7cd9be82c67e850a9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Nov 2023 19:35:11 +0000 Subject: [PATCH 0978/1323] Bump junit.version from 5.10.0 to 5.10.1 Bumps `junit.version` from 5.10.0 to 5.10.1. Updates `org.junit.jupiter:junit-jupiter-api` from 5.10.0 to 5.10.1 - [Release notes](https://github.com/junit-team/junit5/releases) - [Commits](https://github.com/junit-team/junit5/compare/r5.10.0...r5.10.1) Updates `org.junit.jupiter:junit-jupiter-engine` from 5.10.0 to 5.10.1 - [Release notes](https://github.com/junit-team/junit5/releases) - [Commits](https://github.com/junit-team/junit5/compare/r5.10.0...r5.10.1) --- updated-dependencies: - dependency-name: org.junit.jupiter:junit-jupiter-api dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: org.junit.jupiter:junit-jupiter-engine dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- tests/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/pom.xml b/tests/pom.xml index 6c8eee3c1..5185b68ad 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -12,7 +12,7 @@ true - 5.10.0 + 5.10.1 3.24.2 2.15.3 2.5 From d028f9f8061c47cf1754824ec8524ec1105ba3a3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 10 Nov 2023 19:03:49 +0000 Subject: [PATCH 0979/1323] Bump swagger.version from 2.2.18 to 2.2.19 Bumps `swagger.version` from 2.2.18 to 2.2.19. Updates `io.swagger.core.v3:swagger-annotations` from 2.2.18 to 2.2.19 Updates `io.swagger.core.v3:swagger-models` from 2.2.18 to 2.2.19 --- updated-dependencies: - dependency-name: io.swagger.core.v3:swagger-annotations dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: io.swagger.core.v3:swagger-models dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index dc9e928b1..091f7e21d 100644 --- a/pom.xml +++ b/pom.xml @@ -19,7 +19,7 @@ true - 2.2.18 + 2.2.19 2.14.2 1.16 ${project.build.directory}${file.separator}module-info.shade diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index f25d0b3ff..118c28ac9 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -14,7 +14,7 @@ true org.example.myapp.Main 6.0.0-beta.1 - 2.2.18 + 2.2.19 1.3.71 diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index c2b8a2741..c9d73d479 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -13,7 +13,7 @@ true org.example.myapp.Main 6.0.0-beta.1 - 2.2.18 + 2.2.19 1.3.71 diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 2d9c27a7b..297f47caf 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -13,7 +13,7 @@ true org.example.myapp.Main 2.5 - 2.2.18 + 2.2.19 From 94cb93872cf1e76696b4135818d1b8997f1c44f9 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Tue, 14 Nov 2023 11:25:08 -0500 Subject: [PATCH 0980/1323] javalin beta 2 --- tests/pom.xml | 1 + tests/test-javalin-jsonb/pom.xml | 1 - tests/test-javalin/pom.xml | 1 - 3 files changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/pom.xml b/tests/pom.xml index 5185b68ad..a925741ee 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -18,6 +18,7 @@ 2.5 9.9 4.0.0 + 6.0.0-beta.2 diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 118c28ac9..316ae8b28 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -13,7 +13,6 @@ true org.example.myapp.Main - 6.0.0-beta.1 2.2.19 1.3.71 diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index c9d73d479..3848384c3 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -12,7 +12,6 @@ true org.example.myapp.Main - 6.0.0-beta.1 2.2.19 1.3.71 From e0393eb405bf00e89e9f4aefe1c911b453d85781 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Wed, 15 Nov 2023 08:32:13 +1300 Subject: [PATCH 0981/1323] Bump parent pom to 4.0, use maven.compiler.release property --- http-generator-helidon/pom.xml | 6 ++---- pom.xml | 2 +- .../src/main/resources/public/openapi.json | 2 +- tests/test-nima-jsonb/pom.xml | 4 +--- tests/test-nima/pom.xml | 3 +-- 5 files changed, 6 insertions(+), 11 deletions(-) diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index fc9e2e363..7544d6c59 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -10,9 +10,7 @@ avaje-http-helidon-generator - 21 - 21 - 21 + 21 UTF-8 @@ -23,7 +21,7 @@ avaje-http-generator-core ${project.version} - + io.avaje avaje-prisms diff --git a/pom.xml b/pom.xml index 091f7e21d..b0635cbd9 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ org.avaje java11-oss - 3.12 + 4.0 io.avaje diff --git a/tests/test-javalin-jsonb/src/main/resources/public/openapi.json b/tests/test-javalin-jsonb/src/main/resources/public/openapi.json index ea3caca39..e6ed241d4 100644 --- a/tests/test-javalin-jsonb/src/main/resources/public/openapi.json +++ b/tests/test-javalin-jsonb/src/main/resources/public/openapi.json @@ -1,7 +1,7 @@ { "openapi" : "3.0.1", "info" : { - "title" : "Example service", + "title" : "Example service showing off the Path extension method of controller", "description" : "Example Javalin controllers with Java and Maven", "version" : "" }, diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 4d10ce3a2..e939d32af 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -12,9 +12,7 @@ test-nima-jsonb - 21 - 21 - 21 + 21 UTF-8 false diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index fdc73aecf..0f34275be 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -12,8 +12,7 @@ test-nima - 21 - 21 + 21 UTF-8 From ef98b0612f79386132de92fe6509b27e1dc15bcf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 16 Nov 2023 19:56:08 +0000 Subject: [PATCH 0982/1323] Bump com.fasterxml.jackson.core:jackson-databind from 2.15.3 to 2.16.0 Bumps [com.fasterxml.jackson.core:jackson-databind](https://github.com/FasterXML/jackson) from 2.15.3 to 2.16.0. - [Commits](https://github.com/FasterXML/jackson/commits) --- updated-dependencies: - dependency-name: com.fasterxml.jackson.core:jackson-databind dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- http-client/pom.xml | 2 +- tests/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/http-client/pom.xml b/http-client/pom.xml index 13512563d..247c411b4 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -29,7 +29,7 @@ com.fasterxml.jackson.core jackson-databind - 2.15.3 + 2.16.0 true diff --git a/tests/pom.xml b/tests/pom.xml index a925741ee..88351c932 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -14,7 +14,7 @@ true 5.10.1 3.24.2 - 2.15.3 + 2.16.0 2.5 9.9 4.0.0 From 257cd46f810a554af2d53e4f419237b50301befc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 20 Nov 2023 19:43:10 +0000 Subject: [PATCH 0983/1323] Bump io.repaint.maven:tiles-maven-plugin from 2.38 to 2.39 Bumps [io.repaint.maven:tiles-maven-plugin](https://github.com/repaint-io/maven-tiles) from 2.38 to 2.39. - [Release notes](https://github.com/repaint-io/maven-tiles/releases) - [Changelog](https://github.com/repaint-io/maven-tiles/blob/master/CHANGELOG.adoc) - [Commits](https://github.com/repaint-io/maven-tiles/compare/tiles-maven-plugin-2.38...tiles-maven-plugin-2.39) --- updated-dependencies: - dependency-name: io.repaint.maven:tiles-maven-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 316ae8b28..3bc16a0a3 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -136,7 +136,7 @@ io.repaint.maven tiles-maven-plugin - 2.38 + 2.39 true diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 3848384c3..9c4d67a81 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -129,7 +129,7 @@ io.repaint.maven tiles-maven-plugin - 2.38 + 2.39 true diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 297f47caf..f1e515305 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -122,7 +122,7 @@ io.repaint.maven tiles-maven-plugin - 2.38 + 2.39 true diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index e939d32af..36df5baf0 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -104,7 +104,7 @@ io.repaint.maven tiles-maven-plugin - 2.38 + 2.39 true diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index 0f34275be..64fdd5e1f 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -73,7 +73,7 @@ io.repaint.maven tiles-maven-plugin - 2.38 + 2.39 true From 15fe894fa29d2470e94fc23d4d7666746fa52697 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 27 Nov 2023 19:06:37 +0000 Subject: [PATCH 0984/1323] Bump nima.version from 4.0.0 to 4.0.1 Bumps `nima.version` from 4.0.0 to 4.0.1. Updates `io.helidon.webserver:helidon-webserver` from 4.0.0 to 4.0.1 Updates `io.helidon.http.media:helidon-http-media-jsonb` from 4.0.0 to 4.0.1 --- updated-dependencies: - dependency-name: io.helidon.webserver:helidon-webserver dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: io.helidon.http.media:helidon-http-media-jsonb dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- tests/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/pom.xml b/tests/pom.xml index 88351c932..b4b8955bd 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -17,7 +17,7 @@ 2.16.0 2.5 9.9 - 4.0.0 + 4.0.1 6.0.0-beta.2 From 6e1e64ba85b130eda062744a21311bab53d3895a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 29 Nov 2023 19:28:24 +0000 Subject: [PATCH 0985/1323] Bump avaje-inject.version from 9.9 to 9.10 Bumps `avaje-inject.version` from 9.9 to 9.10. Updates `io.avaje:avaje-inject` from 9.9 to 9.10 - [Release notes](https://github.com/avaje/avaje-inject/releases) - [Commits](https://github.com/avaje/avaje-inject/compare/9.9...9.10) Updates `io.avaje:avaje-inject-generator` from 9.9 to 9.10 --- updated-dependencies: - dependency-name: io.avaje:avaje-inject dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: io.avaje:avaje-inject-generator dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- http-client/pom.xml | 4 ++-- http-inject-plugin/pom.xml | 2 +- tests/pom.xml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/http-client/pom.xml b/http-client/pom.xml index 247c411b4..ad03e4e3c 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -43,7 +43,7 @@ io.avaje avaje-inject - 9.9 + 9.10 true @@ -106,7 +106,7 @@ io.avaje avaje-inject-generator - 9.9 + 9.10 diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index b0d9854fc..2e411bf16 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -19,7 +19,7 @@ io.avaje avaje-inject - 9.9 + 9.10 provided true diff --git a/tests/pom.xml b/tests/pom.xml index b4b8955bd..96de4fc99 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -16,7 +16,7 @@ 3.24.2 2.16.0 2.5 - 9.9 + 9.10 4.0.1 6.0.0-beta.2 From b239592181a3dc0a4a10d86ad3a0bb62f20d4739 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Fri, 1 Dec 2023 00:16:21 +1300 Subject: [PATCH 0986/1323] Version 2.1-RC1 --- http-api-javalin/pom.xml | 2 +- http-api/pom.xml | 2 +- http-client-gson-adapter/pom.xml | 4 ++-- http-client/pom.xml | 2 +- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 2 +- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-inject-plugin/pom.xml | 2 +- pom.xml | 2 +- tests/pom.xml | 2 +- tests/test-client-generation/pom.xml | 2 +- tests/test-client/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- 19 files changed, 20 insertions(+), 20 deletions(-) diff --git a/http-api-javalin/pom.xml b/http-api-javalin/pom.xml index 1713cc524..49ca8d180 100644 --- a/http-api-javalin/pom.xml +++ b/http-api-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.1-SNAPSHOT + 2.1-RC1 .. diff --git a/http-api/pom.xml b/http-api/pom.xml index 24a542d47..5cb024fce 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.1-SNAPSHOT + 2.1-RC1 .. diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index 689c1e00d..77b11a583 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.1-SNAPSHOT + 2.1-RC1 avaje-http-client-gson @@ -20,7 +20,7 @@ io.avaje avaje-http-client - 2.1-SNAPSHOT + 2.1-RC1 provided diff --git a/http-client/pom.xml b/http-client/pom.xml index 13512563d..e8e6b161c 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.1-SNAPSHOT + 2.1-RC1 avaje-http-client diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index ca3c5144c..c6d5736ba 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.1-SNAPSHOT + 2.1-RC1 avaje-http-client-generator diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 92b25ada5..7f6321e69 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.1-SNAPSHOT + 2.1-RC1 avaje-http-generator-core diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index 7544d6c59..f8edd4899 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.1-SNAPSHOT + 2.1-RC1 avaje-http-helidon-generator diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index 3b3538f24..ed3b4a3db 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.1-SNAPSHOT + 2.1-RC1 avaje-http-javalin-generator diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index 86d2c3bee..ecb8a0138 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.1-SNAPSHOT + 2.1-RC1 avaje-http-jex-generator diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index b0d9854fc..a4248dcbe 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.1-SNAPSHOT + 2.1-RC1 .. diff --git a/pom.xml b/pom.xml index b0635cbd9..ae2341b28 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-parent - 2.1-SNAPSHOT + 2.1-RC1 pom diff --git a/tests/pom.xml b/tests/pom.xml index a925741ee..c95fcf6f8 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.1-SNAPSHOT + 2.1-RC1 tests diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index 15cf478bb..33bbbb496 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.1-SNAPSHOT + 2.1-RC1 test-client-generation diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index fed2bc3de..53fc3c74c 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.1-SNAPSHOT + 2.1-RC1 test-client diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 316ae8b28..9faf57e83 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 2.1-SNAPSHOT + 2.1-RC1 test-javalin-jsonb diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 3848384c3..54f43cfa7 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.1-SNAPSHOT + 2.1-RC1 test-javalin diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 297f47caf..b6dd7f0f6 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.1-SNAPSHOT + 2.1-RC1 test-jex diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index e939d32af..cea191c12 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.1-SNAPSHOT + 2.1-RC1 test-nima-jsonb diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index 0f34275be..70a698e9e 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.1-SNAPSHOT + 2.1-RC1 test-nima From 841db33a05633fbce728eb3092103bc02372ba86 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 8 Dec 2023 19:09:59 +0000 Subject: [PATCH 0987/1323] Bump io.rest-assured:rest-assured from 5.3.2 to 5.4.0 Bumps [io.rest-assured:rest-assured](https://github.com/rest-assured/rest-assured) from 5.3.2 to 5.4.0. - [Changelog](https://github.com/rest-assured/rest-assured/blob/master/changelog.txt) - [Commits](https://github.com/rest-assured/rest-assured/commits/rest-assured-5.4.0) --- updated-dependencies: - dependency-name: io.rest-assured:rest-assured dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 9078eb292..cbe494343 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -101,7 +101,7 @@ io.rest-assured rest-assured - 5.3.2 + 5.4.0 test diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 1314a81fb..a836cfd62 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -94,7 +94,7 @@ io.rest-assured rest-assured - 5.3.2 + 5.4.0 test From 0c1d3fdf32f200fe24be9906ee4c168aba85084b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 12 Dec 2023 19:17:05 +0000 Subject: [PATCH 0988/1323] Bump io.repaint.maven:tiles-maven-plugin from 2.39 to 2.40 Bumps [io.repaint.maven:tiles-maven-plugin](https://github.com/repaint-io/maven-tiles) from 2.39 to 2.40. - [Release notes](https://github.com/repaint-io/maven-tiles/releases) - [Changelog](https://github.com/repaint-io/maven-tiles/blob/master/CHANGELOG.adoc) - [Commits](https://github.com/repaint-io/maven-tiles/compare/tiles-maven-plugin-2.39...tiles-maven-plugin-2.40) --- updated-dependencies: - dependency-name: io.repaint.maven:tiles-maven-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index cbe494343..a6915f75b 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -136,7 +136,7 @@ io.repaint.maven tiles-maven-plugin - 2.39 + 2.40 true diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index a836cfd62..c7e3bb857 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -129,7 +129,7 @@ io.repaint.maven tiles-maven-plugin - 2.39 + 2.40 true diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 3f8d0bb50..b70ca0818 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -122,7 +122,7 @@ io.repaint.maven tiles-maven-plugin - 2.39 + 2.40 true diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 465dfcfd0..40a757b7c 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -104,7 +104,7 @@ io.repaint.maven tiles-maven-plugin - 2.39 + 2.40 true diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index 6762a013c..13b405bfb 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -73,7 +73,7 @@ io.repaint.maven tiles-maven-plugin - 2.39 + 2.40 true From 05009d850dc7ea8707eea9e1fe08e11449a36a39 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Tue, 12 Dec 2023 17:51:02 -0500 Subject: [PATCH 0989/1323] [http-core] Handle `@param` Newlines in Javadoc Reader (#351) * Update JavadocParserTest.java * Revert "Update JavadocParserTest.java" This reverts commit a6ff6418fdf93f2dd466f575f7ee2186f45d2c14. * handle newlines in params --- .../generator/core/javadoc/JavadocParser.java | 70 ++++++++++++------- .../core/javadoc/JavadocParserTest.java | 18 +++++ 2 files changed, 63 insertions(+), 25 deletions(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/javadoc/JavadocParser.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/javadoc/JavadocParser.java index 79b3c446d..2d18bbe05 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/javadoc/JavadocParser.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/javadoc/JavadocParser.java @@ -19,22 +19,25 @@ class JavadocParser { private static final int PARAM_DESC = 7; private static final int RETURN_DESC = 8; private static final int IGNORE = 9; + private static final int CODE = 10; private static final String DEPRECATED = "deprecated"; private int previousState = TEXT; - private StringBuilder currentParam = new StringBuilder(); - private StringBuilder currentDoclet = new StringBuilder(); + private final StringBuilder currentParam = new StringBuilder(); + private final StringBuilder currentDoclet = new StringBuilder(); private StringBuilder currentContent; private int state = TEXT; private String returnDesc = ""; - private Map params = new LinkedHashMap<>(); + private final Map params = new LinkedHashMap<>(); private boolean deprecated; +private boolean hasReturn; + /** * Parse the javadoc. */ @@ -48,6 +51,7 @@ Javadoc parse(String text) { currentContent = mainContent; for (char c : text.toCharArray()) { + switch (state) { case RETURN_DESC: if (c == '\n') { @@ -57,6 +61,11 @@ Javadoc parse(String text) { if (state == PARAM_DESC) { processSetParam(); } + case CODE: + if (state == CODE && c == '}') { + state = previousState; + break; + } case TEXT: processText(c); continue; @@ -77,32 +86,44 @@ Javadoc parse(String text) { } } - if (state == RETURN_DESC) { - returnDesc = currentContent.toString(); + if (hasReturn) { + returnDesc = mergeLines(currentContent.toString()); } return splitMain(mainContent.toString().trim()); } private void processSetParam() { - params.put(currentParam.toString(), currentContent.toString().trim()); + params.put(currentParam.toString(), mergeLines(currentContent.toString().trim())); } private void processReturnDesc(StringBuilder mainContent) { state = TEXT; previousState = TEXT; returnDesc = currentContent.toString(); - currentContent = mainContent; + currentContent = new StringBuilder(returnDesc); } private void processText(char c) { - if (c == '{' || c == '@') { - currentDoclet.delete(0, currentDoclet.length()); - state = DOCLET_START; - } else if (c == '<') { - state = TAG_START; - } else if (c != '}' && c != '>') { - currentContent.append(c); + switch (c) { + case '{': + case '@': + currentDoclet.delete(0, currentDoclet.length()); + state = DOCLET_START; + break; + case '<': + state = TAG_START; + break; + case '\n': + if (state == CODE) { + currentContent.append("\\n"); + return; + } + default: + if (c != '}' && c != '>') { + currentContent.append(c); + } + break; } } @@ -132,23 +153,22 @@ private void processDocletStart(char c) { deprecated = true; } state = IGNORE; - } else { - if (docletName.equals("param")) { - currentParam.delete(0, currentParam.length()); - state = PARAM_NAME; - } - if (docletName.equals("return")) { - currentContent = new StringBuilder(); - state = RETURN_DESC; - previousState = RETURN_DESC; - } + } else if ("param".equals(docletName)) { + currentParam.delete(0, currentParam.length()); + state = PARAM_NAME; + } else if ("return".equals(docletName)) { + currentContent = new StringBuilder(); + state = RETURN_DESC; + previousState = RETURN_DESC; + hasReturn=true; + } else if ("@code".equals(docletName)) { + state = CODE; } } else { currentDoclet.append(c); } } - private Javadoc splitMain(String mainText) { String desc = ""; diff --git a/http-generator-core/src/test/java/io/avaje/http/generator/core/javadoc/JavadocParserTest.java b/http-generator-core/src/test/java/io/avaje/http/generator/core/javadoc/JavadocParserTest.java index 14166b45c..ef40dd149 100644 --- a/http-generator-core/src/test/java/io/avaje/http/generator/core/javadoc/JavadocParserTest.java +++ b/http-generator-core/src/test/java/io/avaje/http/generator/core/javadoc/JavadocParserTest.java @@ -145,4 +145,22 @@ public void lines() { assertThat(parser.mergeLines("\n one \n two \n three \n")).isEqualTo("one two three"); } + + @Test + public void parse_param_with_newline() { + + JavadocParser parser = new JavadocParser(); + + Javadoc doc = parser.parse( + "This is a description with bold and {@code some code}\n" + + "@since 1.0\n" + + "@param foo The\n foo param\n" + + "@param bar The {@code \n} param\n" + + "@return The {@value return}\n value\n"); + + assertEquals("This is a description with bold and some code", doc.getSummary()); + assertEquals("The foo param", doc.getParams().get("foo")); + assertEquals("The \\n param", doc.getParams().get("bar")); + assertEquals("The return value", doc.getReturnDescription()); + } } From f8ec5133b9c03f043937a827f765c8a6d009d36b Mon Sep 17 00:00:00 2001 From: "robin.bygrave" Date: Wed, 13 Dec 2023 12:18:03 +1300 Subject: [PATCH 0990/1323] Fix #354 - Add toEnum() to PathTypeConversion, also support non-upper case Also support enums that are not all upper case (if people choose to do that). --- .../io/avaje/http/api/PathTypeConversion.java | 32 +++++++++++++++- .../http/api/PathTypeConversionTest.java | 38 +++++++++++++++++++ .../io/avaje/http/generator/core/TypeMap.java | 3 +- 3 files changed, 69 insertions(+), 4 deletions(-) diff --git a/http-api/src/main/java/io/avaje/http/api/PathTypeConversion.java b/http-api/src/main/java/io/avaje/http/api/PathTypeConversion.java index 1cd272f20..9bd7568cc 100644 --- a/http-api/src/main/java/io/avaje/http/api/PathTypeConversion.java +++ b/http-api/src/main/java/io/avaje/http/api/PathTypeConversion.java @@ -71,16 +71,31 @@ public static int asInt(String value) { } /** Convert to enum. */ - @SuppressWarnings({"unchecked", "rawtypes"}) + @SuppressWarnings({"rawtypes"}) public static Enum asEnum(Class clazz, String value) { checkNull(value); try { - return Enum.valueOf((Class) clazz, value.toUpperCase()); + return convertEnum(clazz, value); } catch (final IllegalArgumentException e) { throw new InvalidPathArgumentException(e); } } + @SuppressWarnings({"unchecked", "rawtypes"}) + public static Enum convertEnum(Class clazz, String value) { + try { + return Enum.valueOf((Class) clazz, value); + } catch (final IllegalArgumentException e) { + if (value != null) { + final String asUpper = value.toUpperCase(); + if (!asUpper.equals(value)) { + return Enum.valueOf((Class) clazz, asUpper); + } + } + throw e; + } + } + /** * Convert to long. */ @@ -240,6 +255,19 @@ public static Integer asInteger(String value) { } } + /** Convert to enum. */ + @SuppressWarnings({"rawtypes"}) + public static Enum toEnum(Class clazz, String value) { + if (isNullOrEmpty(value)) { + return null; + } + try { + return convertEnum(clazz, value); + } catch (final IllegalArgumentException e) { + throw new InvalidTypeArgumentException(e); + } + } + /** * Convert to Integer (allowing nulls). */ diff --git a/http-api/src/test/java/io/avaje/http/api/PathTypeConversionTest.java b/http-api/src/test/java/io/avaje/http/api/PathTypeConversionTest.java index f682d09e7..d9c692cff 100644 --- a/http-api/src/test/java/io/avaje/http/api/PathTypeConversionTest.java +++ b/http-api/src/test/java/io/avaje/http/api/PathTypeConversionTest.java @@ -233,6 +233,44 @@ void asInteger_invalid() { assertThrows(InvalidPathArgumentException.class, () -> PathTypeConversion.asInteger("junk")); } + enum Hello { + ONE, + TWO + } + + @SuppressWarnings("unchecked") + @Test + void toEnum() { + assertThat(PathTypeConversion.toEnum(Hello.class, "ONE")).isEqualTo(Hello.ONE); + assertThat(PathTypeConversion.toEnum(Hello.class, "one")).isEqualTo(Hello.ONE); + assertThat(PathTypeConversion.toEnum(Hello.class, "Two")).isEqualTo(Hello.TWO); + assertThat(PathTypeConversion.toEnum(Hello.class, "")).isNull(); + assertThat(PathTypeConversion.toEnum(Hello.class, null)).isNull(); + } + + @Test + void toEnum_invalid() { + assertThrows(InvalidTypeArgumentException.class, () -> PathTypeConversion.toEnum(Hello.class, "DoesNotExist")); + } + + @SuppressWarnings("unchecked") + @Test + void asEnum() { + assertThat(PathTypeConversion.asEnum(Hello.class, "ONE")).isEqualTo(Hello.ONE); + assertThat(PathTypeConversion.asEnum(Hello.class, "One")).isEqualTo(Hello.ONE); + assertThat(PathTypeConversion.asEnum(Hello.class, "one")).isEqualTo(Hello.ONE); + assertThat(PathTypeConversion.asEnum(Hello.class, "Two")).isEqualTo(Hello.TWO); + assertThat(PathTypeConversion.toEnum(Hello.class, "")).isNull(); + assertThat(PathTypeConversion.toEnum(Hello.class, null)).isNull(); + } + + @Test + void asEnum_invalid() { + assertThrows(InvalidPathArgumentException.class, () -> PathTypeConversion.asEnum(Hello.class, "")); + assertThrows(InvalidPathArgumentException.class, () -> PathTypeConversion.asEnum(Hello.class, null)); + assertThrows(InvalidPathArgumentException.class, () -> PathTypeConversion.asEnum(Hello.class, "DoesNotExist")); + } + @Test void toInteger() { assertThat(PathTypeConversion.toInteger("42")).isEqualTo(42); diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/TypeMap.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/TypeMap.java index c81938cf8..1594766f2 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/TypeMap.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/TypeMap.java @@ -310,14 +310,13 @@ static class EnumHandler extends ObjectHandler { private final UType type; EnumHandler(UType type) { - super(type.mainType(), type.shortName()); this.type = type; } @Override public String toMethod() { - return "(" + type.shortType() + ") asEnum(" + type.shortType() + ".class, "; + return "(" + type.shortType() + ") toEnum(" + type.shortType() + ".class, "; } @Override From 7d419a25f0ae7184c376a9c911a3cd6de10e1cb4 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Wed, 13 Dec 2023 21:27:32 +1300 Subject: [PATCH 0991/1323] #358 Generated openapi.json should contain a servers section with localhost:8080 --- .../generator/core/openapi/DocContext.java | 22 +++++++++---------- .../src/main/resources/public/openapi.json | 8 ++++++- .../resources/expectedInheritedOpenApi.json | 6 +++++ .../src/test/resources/expectedOpenApi.json | 6 +++++ .../src/main/resources/public/openapi.json | 8 ++++++- .../src/main/resources/public/openapi.json | 6 +++++ 6 files changed, 43 insertions(+), 13 deletions(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/DocContext.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/DocContext.java index 590e03c0c..7e50915cb 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/DocContext.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/DocContext.java @@ -10,7 +10,6 @@ import javax.annotation.processing.Messager; import javax.annotation.processing.ProcessingEnvironment; import javax.lang.model.element.Element; -import javax.lang.model.element.TypeElement; import javax.lang.model.type.TypeMirror; import javax.lang.model.util.Elements; import javax.tools.Diagnostic; @@ -32,6 +31,7 @@ import io.swagger.v3.oas.models.media.Content; import io.swagger.v3.oas.models.media.Schema; import io.swagger.v3.oas.models.security.SecurityScheme; +import io.swagger.v3.oas.models.servers.Server; import io.swagger.v3.oas.models.tags.Tag; /** Context for building the OpenAPI documentation. */ @@ -65,10 +65,14 @@ public boolean isOpenApiAvailable() { } private OpenAPI initOpenAPI() { - OpenAPI openAPI = new OpenAPI(); openAPI.setPaths(new Paths()); + Server server = new Server(); + server.setUrl("localhost:8080"); + server.setDescription("local testing"); + openAPI.addServersItem(server); + Info info = new Info(); info.setTitle(""); info.setVersion(""); @@ -110,7 +114,6 @@ void addRequestBody(Operation operation, Schema schema, String mediaType, String * Return the OpenAPI adding the paths and schemas. */ private OpenAPI getApiForWriting() { - Paths paths = openAPI.getPaths(); if (paths == null) { paths = new Paths(); @@ -148,30 +151,29 @@ private Tag createTagItem(TagPrism tag) { public void addTagsDefinition(Element element) { final var tags = TagsPrism.getInstanceOn(element); - if (tags == null) return; - + if (tags == null) { + return; + } for(var tag : tags.value()){ openAPI.addTagsItem(createTagItem(tag)); } } public void addTagDefinition(Element element) { - for (var tag : TagPrism.getAllInstancesOn(element)) { openAPI.addTagsItem(createTagItem(tag)); } } public void addSecurityScheme(Element element) { - this.addSecuritySchemes(SecuritySchemePrism.getAllInstancesOn(element)); } public void addSecuritySchemes(Element element) { var schemes = SecuritySchemesPrism.getInstanceOn(element); if (schemes == null) { - return; - } + return; + } this.addSecuritySchemes(schemes.value()); } @@ -196,7 +198,6 @@ void addSecuritySchemes(List schemes) { } public void readApiDefinition(Element element) { - final var openApi = OpenAPIDefinitionPrism.getInstanceOn(element); final var info = openApi.info(); if (!info.title().isEmpty()) { @@ -217,7 +218,6 @@ public void writeApi() { } catch (final Exception e) { logError(null, "Error writing openapi file" + e.getMessage()); - e.printStackTrace(); } } diff --git a/tests/test-javalin-jsonb/src/main/resources/public/openapi.json b/tests/test-javalin-jsonb/src/main/resources/public/openapi.json index e6ed241d4..087e3dd87 100644 --- a/tests/test-javalin-jsonb/src/main/resources/public/openapi.json +++ b/tests/test-javalin-jsonb/src/main/resources/public/openapi.json @@ -5,6 +5,12 @@ "description" : "Example Javalin controllers with Java and Maven", "version" : "" }, + "servers" : [ + { + "url" : "localhost:8080", + "description" : "local testing" + } + ], "tags" : [ { "name" : "tag1", @@ -844,7 +850,7 @@ ], "responses" : { "200" : { - "description" : "The Hello DTO given the id and name.", + "description" : "Return the Hello DTO.", "content" : { "application/json" : { "schema" : { diff --git a/tests/test-javalin-jsonb/src/test/resources/expectedInheritedOpenApi.json b/tests/test-javalin-jsonb/src/test/resources/expectedInheritedOpenApi.json index 4b1490dac..a0e6983f6 100644 --- a/tests/test-javalin-jsonb/src/test/resources/expectedInheritedOpenApi.json +++ b/tests/test-javalin-jsonb/src/test/resources/expectedInheritedOpenApi.json @@ -4,6 +4,12 @@ "title" : "Example service showing off the Path extension method of controller", "version" : "" }, + "servers" : [ + { + "url" : "localhost:8080", + "description" : "local testing" + } + ], "tags" : [ { "name" : "tag1", diff --git a/tests/test-javalin-jsonb/src/test/resources/expectedOpenApi.json b/tests/test-javalin-jsonb/src/test/resources/expectedOpenApi.json index 74f02b477..2a354cb45 100644 --- a/tests/test-javalin-jsonb/src/test/resources/expectedOpenApi.json +++ b/tests/test-javalin-jsonb/src/test/resources/expectedOpenApi.json @@ -5,6 +5,12 @@ "description" : "Example Javalin controllers with Java and Maven", "version" : "" }, + "servers" : [ + { + "url" : "localhost:8080", + "description" : "local testing" + } + ], "tags" : [ { "name" : "tag1", diff --git a/tests/test-javalin/src/main/resources/public/openapi.json b/tests/test-javalin/src/main/resources/public/openapi.json index ddd3021e2..ff158eb08 100644 --- a/tests/test-javalin/src/main/resources/public/openapi.json +++ b/tests/test-javalin/src/main/resources/public/openapi.json @@ -5,6 +5,12 @@ "description" : "Example Javalin controllers with Java and Maven", "version" : "" }, + "servers" : [ + { + "url" : "localhost:8080", + "description" : "local testing" + } + ], "paths" : { "/bars" : { "get" : { @@ -781,7 +787,7 @@ ], "responses" : { "200" : { - "description" : "The Hello DTO given the id and name.", + "description" : "Return the Hello DTO.", "content" : { "application/json" : { "schema" : { diff --git a/tests/test-jex/src/main/resources/public/openapi.json b/tests/test-jex/src/main/resources/public/openapi.json index c0c78a221..b761bf8db 100644 --- a/tests/test-jex/src/main/resources/public/openapi.json +++ b/tests/test-jex/src/main/resources/public/openapi.json @@ -4,6 +4,12 @@ "title" : "", "version" : "" }, + "servers" : [ + { + "url" : "localhost:8080", + "description" : "local testing" + } + ], "paths" : { "" : { "get" : { From 982b1e41e025a1a012906384a470fda57ed49323 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Wed, 13 Dec 2023 22:44:00 +1300 Subject: [PATCH 0992/1323] #355 Controller methods returning null should produce 204 no content response Helidon generation only in this commit --- .../helidon/nima/ControllerMethodWriter.java | 27 +++++++++++++------ .../main/java/org/example/TestController.java | 5 ++++ .../java/org/example/TestControllerTest.java | 21 +++++++++++++++ 3 files changed, 45 insertions(+), 8 deletions(-) diff --git a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java index 1d71a7491..f7f7365ab 100644 --- a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java +++ b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java @@ -186,19 +186,30 @@ void writeHandler(boolean requestScoped) { writer.append(");").eol(); if (!method.isVoid() && !isFilter) { - writeContextReturn(); + TypeMirror typeMirror = method.returnType(); + boolean includeNoContent = !typeMirror.getKind().isPrimitive(); + if (includeNoContent) { + writer.append(" if (result == null) {").eol(); + writer.append(" res.status(NO_CONTENT_204).send();").eol(); + writer.append(" } else {").eol(); + } + String indent = includeNoContent ? " " : " "; + writeContextReturn(indent); if (isInputStream(method.returnType())) { final var uType = UType.parse(method.returnType()); - writer.append(" result.transferTo(res.outputStream());", uType.shortName()).eol(); + writer.append(indent).append("result.transferTo(res.outputStream());", uType.shortName()).eol(); } else if (producesJson()) { if (returnTypeString()) { - writer.append(" res.send(result); // send raw JSON").eol(); + writer.append(indent).append("res.send(result); // send raw JSON").eol(); } else { final var uType = UType.parse(method.returnType()); - writer.append(" %sJsonType.toJson(result, JsonOutput.of(res));", uType.shortName()).eol(); + writer.append(indent).append("%sJsonType.toJson(result, JsonOutput.of(res));", uType.shortName()).eol(); } } else { - writer.append(" res.send(result);").eol(); + writer.append(indent).append("res.send(result);").eol(); + } + if (includeNoContent) { + writer.append(" }").eol(); } } writer.append(" }").eol().eol(); @@ -260,14 +271,14 @@ private boolean usesFormParams() { return method.params().stream().anyMatch(p -> p.isForm() || ParamType.FORMPARAM.equals(p.paramType())); } - private void writeContextReturn() { + private void writeContextReturn(String indent) { final var producesOp = Optional.ofNullable(method.produces()); if (producesOp.isEmpty() && !useJsonB) { return; } - final var produces = producesOp.map(MediaType::parse).orElse(MediaType.APPLICATION_JSON); - final var contentTypeString = " res.headers().contentType(MediaTypes."; + final var contentTypeString = "res.headers().contentType(MediaTypes."; + writer.append(indent); switch (produces) { case APPLICATION_JSON -> writer.append(contentTypeString).append("APPLICATION_JSON);").eol(); case TEXT_HTML -> writer.append(contentTypeString).append("TEXT_HTML);").eol(); diff --git a/tests/test-nima-jsonb/src/main/java/org/example/TestController.java b/tests/test-nima-jsonb/src/main/java/org/example/TestController.java index 09039d53a..098f4d8d6 100644 --- a/tests/test-nima-jsonb/src/main/java/org/example/TestController.java +++ b/tests/test-nima-jsonb/src/main/java/org/example/TestController.java @@ -140,4 +140,9 @@ void filter(FilterChain chain, RoutingResponse res) { String formBean(MyForm form) { return form.name + "|" + form.email + "|" + form.url; } + + @Get("maybeNoContent") + String maybeNoContent(Boolean empty) { + return Boolean.TRUE.equals(empty) ? null : "Hi"; + } } diff --git a/tests/test-nima-jsonb/src/test/java/org/example/TestControllerTest.java b/tests/test-nima-jsonb/src/test/java/org/example/TestControllerTest.java index e53efa38a..6c43551c3 100644 --- a/tests/test-nima-jsonb/src/test/java/org/example/TestControllerTest.java +++ b/tests/test-nima-jsonb/src/test/java/org/example/TestControllerTest.java @@ -29,6 +29,27 @@ void hello() { assertThat(res.body()).isEqualTo("Hello world - index"); } + @Test + void maybeNoContent() { + HttpResponse res = client.request() + .path("test/maybeNoContent") + .queryParam("empty", false) + .GET() + .asString(); + + assertThat(res.statusCode()).isEqualTo(200); + assertThat(res.body()).isEqualTo("Hi"); + + HttpResponse res2 = client.request() + .path("test/maybeNoContent") + .queryParam("empty", true) + .GET() + .asString(); + + assertThat(res2.statusCode()).isEqualTo(204); + assertThat(res2.body()).isEqualTo(""); + } + @Test void strBody() { HttpResponse res = client.request() From f4e77554cc53b5f26dd1cd368408d2d3d846a508 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Wed, 13 Dec 2023 23:15:54 +1300 Subject: [PATCH 0993/1323] Version 2.1-RC2 --- http-api-javalin/pom.xml | 2 +- http-api/pom.xml | 2 +- http-client-gson-adapter/pom.xml | 4 ++-- http-client/pom.xml | 2 +- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 2 +- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-inject-plugin/pom.xml | 2 +- pom.xml | 2 +- tests/pom.xml | 2 +- tests/test-client-generation/pom.xml | 2 +- tests/test-client/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- 19 files changed, 20 insertions(+), 20 deletions(-) diff --git a/http-api-javalin/pom.xml b/http-api-javalin/pom.xml index 49ca8d180..7687abe8b 100644 --- a/http-api-javalin/pom.xml +++ b/http-api-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.1-RC1 + 2.1-RC2 .. diff --git a/http-api/pom.xml b/http-api/pom.xml index 5cb024fce..92e2a3fa5 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.1-RC1 + 2.1-RC2 .. diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index 77b11a583..7856a46e9 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.1-RC1 + 2.1-RC2 avaje-http-client-gson @@ -20,7 +20,7 @@ io.avaje avaje-http-client - 2.1-RC1 + 2.1-RC2 provided diff --git a/http-client/pom.xml b/http-client/pom.xml index 48cb477dd..4d1d5aa4e 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.1-RC1 + 2.1-RC2 avaje-http-client diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index c6d5736ba..8883be97b 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.1-RC1 + 2.1-RC2 avaje-http-client-generator diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 7f6321e69..ce7930875 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.1-RC1 + 2.1-RC2 avaje-http-generator-core diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index f8edd4899..78905aba3 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.1-RC1 + 2.1-RC2 avaje-http-helidon-generator diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index ed3b4a3db..99714d83b 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.1-RC1 + 2.1-RC2 avaje-http-javalin-generator diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index ecb8a0138..1fc11c976 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.1-RC1 + 2.1-RC2 avaje-http-jex-generator diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index 088c47d4a..80de0036e 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.1-RC1 + 2.1-RC2 .. diff --git a/pom.xml b/pom.xml index ae2341b28..dda33be9f 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-parent - 2.1-RC1 + 2.1-RC2 pom diff --git a/tests/pom.xml b/tests/pom.xml index 3bd22a123..72c519f86 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.1-RC1 + 2.1-RC2 tests diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index 33bbbb496..d20333436 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.1-RC1 + 2.1-RC2 test-client-generation diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index 53fc3c74c..28b361eac 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.1-RC1 + 2.1-RC2 test-client diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index a6915f75b..021d4485d 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 2.1-RC1 + 2.1-RC2 test-javalin-jsonb diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index c7e3bb857..808bc28d4 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.1-RC1 + 2.1-RC2 test-javalin diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index b70ca0818..be20a4a76 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.1-RC1 + 2.1-RC2 test-jex diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 40a757b7c..f7b9f3c22 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.1-RC1 + 2.1-RC2 test-nima-jsonb diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index 13b405bfb..9cde275f8 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.1-RC1 + 2.1-RC2 test-nima From e692e8aa1709ce8d0de9f205fb077e94bc0e98b0 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Wed, 13 Dec 2023 23:33:53 +1300 Subject: [PATCH 0994/1323] #358 Fix shade plugin for - Generated openapi.json should contain a servers section --- pom.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/pom.xml b/pom.xml index dda33be9f..e46724050 100644 --- a/pom.xml +++ b/pom.xml @@ -109,7 +109,6 @@ io/swagger/v3/oas/models/callbacks/** io/swagger/v3/oas/models/examples/** - io/swagger/v3/oas/models/servers/** From e6f1422ccefd31c5cd88d67662b7f0be8e1d67b9 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Wed, 13 Dec 2023 23:40:46 +1300 Subject: [PATCH 0995/1323] Version 2.1-RC3 --- http-api-javalin/pom.xml | 2 +- http-api/pom.xml | 2 +- http-client-gson-adapter/pom.xml | 4 ++-- http-client/pom.xml | 2 +- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 2 +- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-inject-plugin/pom.xml | 2 +- pom.xml | 2 +- tests/pom.xml | 2 +- tests/test-client-generation/pom.xml | 2 +- tests/test-client/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- 19 files changed, 20 insertions(+), 20 deletions(-) diff --git a/http-api-javalin/pom.xml b/http-api-javalin/pom.xml index 7687abe8b..03f9f6d8a 100644 --- a/http-api-javalin/pom.xml +++ b/http-api-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.1-RC2 + 2.1-RC3 .. diff --git a/http-api/pom.xml b/http-api/pom.xml index 92e2a3fa5..a13d15391 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.1-RC2 + 2.1-RC3 .. diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index 7856a46e9..572f1c5c5 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.1-RC2 + 2.1-RC3 avaje-http-client-gson @@ -20,7 +20,7 @@ io.avaje avaje-http-client - 2.1-RC2 + 2.1-RC3 provided diff --git a/http-client/pom.xml b/http-client/pom.xml index 4d1d5aa4e..522690da5 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.1-RC2 + 2.1-RC3 avaje-http-client diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index 8883be97b..165a75749 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.1-RC2 + 2.1-RC3 avaje-http-client-generator diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index ce7930875..83afc986b 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.1-RC2 + 2.1-RC3 avaje-http-generator-core diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index 78905aba3..2bbe6ea01 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.1-RC2 + 2.1-RC3 avaje-http-helidon-generator diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index 99714d83b..cc59b6264 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.1-RC2 + 2.1-RC3 avaje-http-javalin-generator diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index 1fc11c976..a37c1afea 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.1-RC2 + 2.1-RC3 avaje-http-jex-generator diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index 80de0036e..231c0aa2a 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.1-RC2 + 2.1-RC3 .. diff --git a/pom.xml b/pom.xml index e46724050..04128528c 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-parent - 2.1-RC2 + 2.1-RC3 pom diff --git a/tests/pom.xml b/tests/pom.xml index 72c519f86..d709502eb 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.1-RC2 + 2.1-RC3 tests diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index d20333436..0b2accb2e 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.1-RC2 + 2.1-RC3 test-client-generation diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index 28b361eac..7df8cfa98 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.1-RC2 + 2.1-RC3 test-client diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 021d4485d..d95aef129 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 2.1-RC2 + 2.1-RC3 test-javalin-jsonb diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 808bc28d4..9738eca9a 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.1-RC2 + 2.1-RC3 test-javalin diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index be20a4a76..fedf84041 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.1-RC2 + 2.1-RC3 test-jex diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index f7b9f3c22..8b5e319de 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.1-RC2 + 2.1-RC3 test-nima-jsonb diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index 9cde275f8..17ccd9c78 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.1-RC2 + 2.1-RC3 test-nima From b42bf8d06b21bf0551433571fbcd459948c56be0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 18 Dec 2023 19:23:40 +0000 Subject: [PATCH 0996/1323] Bump io.avaje:avaje-prisms from 1.16 to 1.17 Bumps [io.avaje:avaje-prisms](https://github.com/avaje/avaje-prisms) from 1.16 to 1.17. - [Release notes](https://github.com/avaje/avaje-prisms/releases) - [Commits](https://github.com/avaje/avaje-prisms/compare/1.16...1.17) --- updated-dependencies: - dependency-name: io.avaje:avaje-prisms dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 04128528c..134149255 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ true 2.2.19 2.14.2 - 1.16 + 1.17 ${project.build.directory}${file.separator}module-info.shade From 489855821cb2f648222f5da214787328572ce98c Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Tue, 19 Dec 2023 10:21:47 -0500 Subject: [PATCH 0997/1323] Bump Javalin 6 version --- tests/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/pom.xml b/tests/pom.xml index d709502eb..2cef37f03 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -18,7 +18,7 @@ 2.5 9.10 4.0.1 - 6.0.0-beta.2 + 6.0.0-beta.4 From f88834186e5a3fa46ff1fdaba58bcd3f7267b6f3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 19 Dec 2023 19:50:46 +0000 Subject: [PATCH 0998/1323] Bump org.apache.maven.plugins:maven-compiler-plugin Bumps [org.apache.maven.plugins:maven-compiler-plugin](https://github.com/apache/maven-compiler-plugin) from 3.11.0 to 3.12.0. - [Release notes](https://github.com/apache/maven-compiler-plugin/releases) - [Commits](https://github.com/apache/maven-compiler-plugin/compare/maven-compiler-plugin-3.11.0...maven-compiler-plugin-3.12.0) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-compiler-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- http-client/pom.xml | 2 +- tests/test-client-generation/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/http-client/pom.xml b/http-client/pom.xml index 522690da5..5f52f267b 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -97,7 +97,7 @@ org.apache.maven.plugins maven-compiler-plugin - 3.11.0 + 3.12.0 default-testCompile diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index 0b2accb2e..d48da04ab 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -98,7 +98,7 @@ org.apache.maven.plugins maven-compiler-plugin - 3.11.0 + 3.12.0 diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index 17ccd9c78..049e1c458 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -51,7 +51,7 @@ org.apache.maven.plugins maven-compiler-plugin - 3.11.0 + 3.12.0 21 From 23e7a5a1c0542a5780b6550e95e2539509032e04 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 19 Dec 2023 19:53:05 +0000 Subject: [PATCH 0999/1323] Bump swagger.version from 2.2.19 to 2.2.20 Bumps `swagger.version` from 2.2.19 to 2.2.20. Updates `io.swagger.core.v3:swagger-annotations` from 2.2.19 to 2.2.20 Updates `io.swagger.core.v3:swagger-models` from 2.2.19 to 2.2.20 --- updated-dependencies: - dependency-name: io.swagger.core.v3:swagger-annotations dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: io.swagger.core.v3:swagger-models dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index 134149255..8457a1922 100644 --- a/pom.xml +++ b/pom.xml @@ -19,7 +19,7 @@ true - 2.2.19 + 2.2.20 2.14.2 1.17 ${project.build.directory}${file.separator}module-info.shade diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index d95aef129..94432182c 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -13,7 +13,7 @@ true org.example.myapp.Main - 2.2.19 + 2.2.20 1.3.71 diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 9738eca9a..c69b1272e 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -12,7 +12,7 @@ true org.example.myapp.Main - 2.2.19 + 2.2.20 1.3.71 diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index fedf84041..c81100c26 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -13,7 +13,7 @@ true org.example.myapp.Main 2.5 - 2.2.19 + 2.2.20 From f478c7e9ebf9b16ae3557da4349545a22e66763f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 20 Dec 2023 19:27:55 +0000 Subject: [PATCH 1000/1323] Bump nima.version from 4.0.1 to 4.0.2 Bumps `nima.version` from 4.0.1 to 4.0.2. Updates `io.helidon.webserver:helidon-webserver` from 4.0.1 to 4.0.2 Updates `io.helidon.http.media:helidon-http-media-jsonb` from 4.0.1 to 4.0.2 --- updated-dependencies: - dependency-name: io.helidon.webserver:helidon-webserver dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: io.helidon.http.media:helidon-http-media-jsonb dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- tests/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/pom.xml b/tests/pom.xml index 2cef37f03..8a0aad5e4 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -17,7 +17,7 @@ 2.16.0 2.5 9.10 - 4.0.1 + 4.0.2 6.0.0-beta.4 From ce9372c81f8550b5a47f614e1a00389bd65badef Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sat, 23 Dec 2023 18:00:25 -0500 Subject: [PATCH 1001/1323] Fix Java Lang imports (#367) * fix java lang imports * actually uppercase --- .../http/generator/core/MethodReader.java | 26 +++++++++---------- .../io/avaje/http/generator/core/UType.java | 8 +++--- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java index d7140d6b6..2ffa86e20 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java @@ -472,20 +472,18 @@ public List throwsList() { * arg0, arg1, arg2 etc. */ public void checkArgumentNames() { - if (!params.isEmpty() && pathSegments != null) { - if (allArgParamNames()) { - final var namedSegments = namedSegments(); - if (params.size() >= namedSegments.size()) { - // path params, take the names from the segments - for (int i = 0; i < namedSegments.size(); i++) { - MethodParam pathParam = params.get(i); - pathParam.overrideVarName(namedSegments.get(i).name(), ParamType.PATHPARAM); - } - // QueryParam and Headers which now require explicit names - for (int i = namedSegments.size(); i < params.size(); i++) { - MethodParam param = params.get(i); - param.overrideVarName(i); - } + if (!params.isEmpty() && pathSegments != null && allArgParamNames()) { + final var namedSegments = namedSegments(); + if (params.size() >= namedSegments.size()) { + // path params, take the names from the segments + for (int i = 0; i < namedSegments.size(); i++) { + MethodParam pathParam = params.get(i); + pathParam.overrideVarName(namedSegments.get(i).name(), ParamType.PATHPARAM); + } + // QueryParam and Headers which now require explicit names + for (int i = namedSegments.size(); i < params.size(); i++) { + MethodParam param = params.get(i); + param.overrideVarName(i); } } } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java index dd8a5e93f..e17894025 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java @@ -120,9 +120,11 @@ public String full() { @Override public Set importTypes() { - return rawType.startsWith("java.lang.") && rawType.indexOf('.') > -1 - ? Set.of() - : Collections.singleton(rawType.replace("[]", "")); + return rawType.startsWith("java.lang.") + && Character.isUpperCase(rawType.charAt(10)) + && rawType.indexOf('.') > -1 + ? Set.of() + : Collections.singleton(rawType.replace("[]", "")); } @Override From e90e8ffbf51a3feef46a79ef6b0459a49e680650 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Sun, 24 Dec 2023 12:07:55 +1300 Subject: [PATCH 1002/1323] #367 Follow up for java.lang imports --- .../io/avaje/http/generator/core/UType.java | 8 +++++--- .../avaje/http/generator/core/UTypeTest.java | 20 +++++++++++++++++++ 2 files changed, 25 insertions(+), 3 deletions(-) create mode 100644 http-generator-core/src/test/java/io/avaje/http/generator/core/UTypeTest.java diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java index e17894025..e86848f12 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java @@ -120,9 +120,7 @@ public String full() { @Override public Set importTypes() { - return rawType.startsWith("java.lang.") - && Character.isUpperCase(rawType.charAt(10)) - && rawType.indexOf('.') > -1 + return isJavaLangPackage(rawType) ? Set.of() : Collections.singleton(rawType.replace("[]", "")); } @@ -143,6 +141,10 @@ public String mainType() { } } + static boolean isJavaLangPackage(String rawType) { + return rawType.startsWith("java.lang.") && Character.isUpperCase(rawType.charAt(10)); + } + /** * Generic type. */ diff --git a/http-generator-core/src/test/java/io/avaje/http/generator/core/UTypeTest.java b/http-generator-core/src/test/java/io/avaje/http/generator/core/UTypeTest.java new file mode 100644 index 000000000..12dea5d6d --- /dev/null +++ b/http-generator-core/src/test/java/io/avaje/http/generator/core/UTypeTest.java @@ -0,0 +1,20 @@ +package io.avaje.http.generator.core; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +class UTypeTest { + + @Test + void isJavaLangPackage() { + assertTrue(UType.isJavaLangPackage("java.lang.F")); + assertTrue(UType.isJavaLangPackage("java.lang.Foo")); + } + + @Test + void isJavaLangPackage_expect_false() { + assertFalse(UType.isJavaLangPackage("java.lang.other.Foo")); + assertFalse(UType.isJavaLangPackage("not.lang.Foo")); + } +} From 4674493a4322c76b2dc9c0042adb8990d87b9ddc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 Dec 2023 19:58:10 +0000 Subject: [PATCH 1003/1323] Bump com.fasterxml.jackson.core:jackson-databind from 2.16.0 to 2.16.1 Bumps [com.fasterxml.jackson.core:jackson-databind](https://github.com/FasterXML/jackson) from 2.16.0 to 2.16.1. - [Commits](https://github.com/FasterXML/jackson/commits) --- updated-dependencies: - dependency-name: com.fasterxml.jackson.core:jackson-databind dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- http-client/pom.xml | 2 +- tests/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/http-client/pom.xml b/http-client/pom.xml index 5f52f267b..8abcb7bef 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -29,7 +29,7 @@ com.fasterxml.jackson.core jackson-databind - 2.16.0 + 2.16.1 true diff --git a/tests/pom.xml b/tests/pom.xml index 8a0aad5e4..816ccbc84 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -14,7 +14,7 @@ true 5.10.1 3.24.2 - 2.16.0 + 2.16.1 2.5 9.10 4.0.2 From 7c53a7d00a46e3999468b7801990cebf06f3e78e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 Dec 2023 19:59:45 +0000 Subject: [PATCH 1004/1323] Bump org.apache.maven.plugins:maven-compiler-plugin Bumps [org.apache.maven.plugins:maven-compiler-plugin](https://github.com/apache/maven-compiler-plugin) from 3.12.0 to 3.12.1. - [Release notes](https://github.com/apache/maven-compiler-plugin/releases) - [Commits](https://github.com/apache/maven-compiler-plugin/compare/maven-compiler-plugin-3.12.0...maven-compiler-plugin-3.12.1) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-compiler-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- http-client/pom.xml | 2 +- tests/test-client-generation/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/http-client/pom.xml b/http-client/pom.xml index 8abcb7bef..7562e5143 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -97,7 +97,7 @@ org.apache.maven.plugins maven-compiler-plugin - 3.12.0 + 3.12.1 default-testCompile diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index d48da04ab..5ab130edb 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -98,7 +98,7 @@ org.apache.maven.plugins maven-compiler-plugin - 3.12.0 + 3.12.1 diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index 049e1c458..0d5c15f77 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -51,7 +51,7 @@ org.apache.maven.plugins maven-compiler-plugin - 3.12.0 + 3.12.1 21 From a75560ea4edf3fee640c63a4a98e9bc4fa919571 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Jan 2024 19:47:22 +0000 Subject: [PATCH 1005/1323] Bump org.assertj:assertj-core from 3.24.2 to 3.25.0 Bumps [org.assertj:assertj-core](https://github.com/assertj/assertj) from 3.24.2 to 3.25.0. - [Release notes](https://github.com/assertj/assertj/releases) - [Commits](https://github.com/assertj/assertj/compare/assertj-build-3.24.2...assertj-build-3.25.0) --- updated-dependencies: - dependency-name: org.assertj:assertj-core dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- tests/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/pom.xml b/tests/pom.xml index 816ccbc84..095546076 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -13,7 +13,7 @@ true 5.10.1 - 3.24.2 + 3.25.0 2.16.1 2.5 9.10 From 671e88d7beafd87060724b5967f8eeb8ae0d78bc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 3 Jan 2024 19:58:06 +0000 Subject: [PATCH 1006/1323] Bump org.assertj:assertj-core from 3.25.0 to 3.25.1 Bumps [org.assertj:assertj-core](https://github.com/assertj/assertj) from 3.25.0 to 3.25.1. - [Release notes](https://github.com/assertj/assertj/releases) - [Commits](https://github.com/assertj/assertj/compare/assertj-build-3.25.0...assertj-build-3.25.1) --- updated-dependencies: - dependency-name: org.assertj:assertj-core dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- tests/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/pom.xml b/tests/pom.xml index 095546076..27441f440 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -13,7 +13,7 @@ true 5.10.1 - 3.25.0 + 3.25.1 2.16.1 2.5 9.10 From 28a18fedac205af0b470d6d05fc9df88d95d78c1 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sun, 7 Jan 2024 19:09:30 -0500 Subject: [PATCH 1007/1323] Fix Javalin 5 generation not triggering properly --- .../java/io/avaje/http/generator/core/ProcessingContext.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java index 85efa8d16..ea81a0ccd 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java @@ -86,7 +86,7 @@ private static final class Ctx { } else { useJavax = (javax); } - this.javalin6 = elementUtils.getTypeElement("io.javalin.config.JavalinConfig") != null; + this.javalin6 = elementUtils.getTypeElement("io.javalin.config.RouterConfig") != null; } } From 3c0d086932348257183dabc1ec1e8a9610bb68ee Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sun, 7 Jan 2024 23:32:59 -0500 Subject: [PATCH 1008/1323] Add `jdk.crypto.ec` to http client module To call things via ssl this is required, and yet I often forget to add it when creating services --- http-client/src/main/java/module-info.java | 1 + 1 file changed, 1 insertion(+) diff --git a/http-client/src/main/java/module-info.java b/http-client/src/main/java/module-info.java index f8445cd87..cabe2d47d 100644 --- a/http-client/src/main/java/module-info.java +++ b/http-client/src/main/java/module-info.java @@ -3,6 +3,7 @@ uses io.avaje.http.client.HttpClient.GeneratedComponent; requires transitive java.net.http; + requires transitive jdk.crypto.ec; requires transitive io.avaje.applog; requires static com.fasterxml.jackson.databind; requires static com.fasterxml.jackson.annotation; From cae7b790a6b305cacaf6cf25272a2eb8b11f3ff9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Jan 2024 19:37:56 +0000 Subject: [PATCH 1009/1323] Bump io.avaje:avaje-prisms from 1.17 to 1.18 Bumps [io.avaje:avaje-prisms](https://github.com/avaje/avaje-prisms) from 1.17 to 1.18. - [Release notes](https://github.com/avaje/avaje-prisms/releases) - [Commits](https://github.com/avaje/avaje-prisms/compare/1.17...1.18) --- updated-dependencies: - dependency-name: io.avaje:avaje-prisms dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 8457a1922..06b065ded 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ true 2.2.20 2.14.2 - 1.17 + 1.18 ${project.build.directory}${file.separator}module-info.shade From ce77a0939f23b155bb7e6eb65b76a2aabee0b282 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 10 Jan 2024 19:00:49 +0000 Subject: [PATCH 1010/1323] Bump io.avaje:avaje-prisms from 1.18 to 1.20 Bumps [io.avaje:avaje-prisms](https://github.com/avaje/avaje-prisms) from 1.18 to 1.20. - [Release notes](https://github.com/avaje/avaje-prisms/releases) - [Commits](https://github.com/avaje/avaje-prisms/compare/1.18...1.20) --- updated-dependencies: - dependency-name: io.avaje:avaje-prisms dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 06b065ded..be49accb9 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ true 2.2.20 2.14.2 - 1.18 + 1.20 ${project.build.directory}${file.separator}module-info.shade From 634a129f1948539ac46934fc71f433716b3ab5c6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 16 Jan 2024 19:55:44 +0000 Subject: [PATCH 1011/1323] Bump nima.version from 4.0.2 to 4.0.3 Bumps `nima.version` from 4.0.2 to 4.0.3. Updates `io.helidon.webserver:helidon-webserver` from 4.0.2 to 4.0.3 Updates `io.helidon.http.media:helidon-http-media-jsonb` from 4.0.2 to 4.0.3 --- updated-dependencies: - dependency-name: io.helidon.webserver:helidon-webserver dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: io.helidon.http.media:helidon-http-media-jsonb dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- tests/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/pom.xml b/tests/pom.xml index 27441f440..131963175 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -17,7 +17,7 @@ 2.16.1 2.5 9.10 - 4.0.2 + 4.0.3 6.0.0-beta.4 From 9d1a0ad51237a78017825fd2b8d359406735bef4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 19 Jan 2024 19:34:01 +0000 Subject: [PATCH 1012/1323] Bump io.avaje:avaje-prisms from 1.20 to 1.21 Bumps [io.avaje:avaje-prisms](https://github.com/avaje/avaje-prisms) from 1.20 to 1.21. - [Release notes](https://github.com/avaje/avaje-prisms/releases) - [Commits](https://github.com/avaje/avaje-prisms/compare/1.20...1.21) --- updated-dependencies: - dependency-name: io.avaje:avaje-prisms dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index be49accb9..09c0612ca 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ true 2.2.20 2.14.2 - 1.20 + 1.21 ${project.build.directory}${file.separator}module-info.shade From 91ea22c80c6d2b82ff41c4e1414136cd1b7ba2cf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 24 Jan 2024 19:33:21 +0000 Subject: [PATCH 1013/1323] Bump org.assertj:assertj-core from 3.25.1 to 3.25.2 Bumps [org.assertj:assertj-core](https://github.com/assertj/assertj) from 3.25.1 to 3.25.2. - [Release notes](https://github.com/assertj/assertj/releases) - [Commits](https://github.com/assertj/assertj/compare/assertj-build-3.25.1...assertj-build-3.25.2) --- updated-dependencies: - dependency-name: org.assertj:assertj-core dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- tests/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/pom.xml b/tests/pom.xml index 131963175..6e67907f1 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -13,7 +13,7 @@ true 5.10.1 - 3.25.1 + 3.25.2 2.16.1 2.5 9.10 From 3481d1c71ebcc59169a0becc74ec2493dcd0b9d5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 26 Jan 2024 19:25:42 +0000 Subject: [PATCH 1014/1323] Bump nima.version from 4.0.3 to 4.0.4 Bumps `nima.version` from 4.0.3 to 4.0.4. Updates `io.helidon.webserver:helidon-webserver` from 4.0.3 to 4.0.4 Updates `io.helidon.http.media:helidon-http-media-jsonb` from 4.0.3 to 4.0.4 --- updated-dependencies: - dependency-name: io.helidon.webserver:helidon-webserver dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: io.helidon.http.media:helidon-http-media-jsonb dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- tests/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/pom.xml b/tests/pom.xml index 6e67907f1..448ea27dc 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -17,7 +17,7 @@ 2.16.1 2.5 9.10 - 4.0.3 + 4.0.4 6.0.0-beta.4 From 5420b2a33ba4d3356f63adf9415f6fec48ed549c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 29 Jan 2024 19:59:18 +0000 Subject: [PATCH 1015/1323] Bump io.javalin:javalin from 5.6.3 to 6.0.0 Bumps [io.javalin:javalin](https://github.com/javalin/javalin) from 5.6.3 to 6.0.0. - [Release notes](https://github.com/javalin/javalin/releases) - [Commits](https://github.com/javalin/javalin/compare/javalin-parent-5.6.3...javalin-parent-6.0.0) --- updated-dependencies: - dependency-name: io.javalin:javalin dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- http-api/pom.xml | 2 +- http-client/pom.xml | 2 +- tests/pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/http-api/pom.xml b/http-api/pom.xml index a13d15391..de31f6ae5 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -24,7 +24,7 @@ io.javalin javalin - 6.0.0-beta.1 + 6.0.0 provided true diff --git a/http-client/pom.xml b/http-client/pom.xml index 7562e5143..7548879c5 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -66,7 +66,7 @@ io.javalin javalin - 5.6.3 + 6.0.0 test diff --git a/tests/pom.xml b/tests/pom.xml index 448ea27dc..446deb37d 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -18,7 +18,7 @@ 2.5 9.10 4.0.4 - 6.0.0-beta.4 + 6.0.0 From 1678d15b019bb09d4926862527cdf1a0b0eae47c Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Mon, 29 Jan 2024 15:30:57 -0500 Subject: [PATCH 1016/1323] fix tests --- README.md | 6 +++--- http-client/pom.xml | 3 +-- .../io/avaje/http/client/HelloControllerTest.java | 6 +++--- .../src/test/java/org/example/webserver/App.java | 7 +------ .../example/webserver/HelloController$Route.java | 14 ++++++++++---- 5 files changed, 18 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 311714938..955d2757a 100644 --- a/README.md +++ b/README.md @@ -106,12 +106,12 @@ To force the AP to generate with `@javax.inject.Singleton`(in the case where you ### Usage with Javalin -The annotation processor will generate controller classes implementing the Javalin `Plugin` interface, which we can register using: +The annotation processor will generate controller classes implementing the `AvajeJavalinPlugin` interface, which we can register in javalin using: ```java -List routes = ...; //retrieve using a DI framework +List routes = ...; //retrieve using a DI framework -Javalin.create(cfg -> routes.forEach(cfg.plugins::register)).start(); +Javalin.create(cfg -> routes.forEach(cfg::registerPlugin)).start(); ``` ### Usage with Helidon SE (4.x) diff --git a/http-client/pom.xml b/http-client/pom.xml index 7548879c5..e7988e1ae 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -73,8 +73,7 @@ io.avaje avaje-http-api - ${project.version} - test + 2.1-RC3 diff --git a/http-client/src/test/java/io/avaje/http/client/HelloControllerTest.java b/http-client/src/test/java/io/avaje/http/client/HelloControllerTest.java index 1beebb1d8..9004d865b 100644 --- a/http-client/src/test/java/io/avaje/http/client/HelloControllerTest.java +++ b/http-client/src/test/java/io/avaje/http/client/HelloControllerTest.java @@ -287,7 +287,7 @@ void get_stream_NotFoundException() { assertThat(metrics.responseBytes()).isEqualTo(0); assertThat(metrics.totalMicros()).isGreaterThan(0); - assertThat(httpException.bodyAsString()).isEqualTo("Not Found"); + assertThat(httpException.bodyAsString()).isEqualTo("Endpoint GET /this-path-does-not-exist not found"); assertThat(httpException.isPlainText()).isTrue(); assertThat(httpException.contentType()) .isPresent() @@ -480,7 +480,7 @@ void get_notFound() { final HttpResponse hres = request.GET().asString(); assertThat(hres.statusCode()).isEqualTo(404); - assertThat(hres.body()).contains("Not Found"); + assertThat(hres.body()).contains("not found"); final HttpClient.Metrics metrics = clientContext.metrics(true); assertThat(metrics.totalCount()).isEqualTo(1); assertThat(metrics.errorCount()).isEqualTo(1); @@ -814,7 +814,7 @@ void get_bean_404() { } catch (HttpException e) { assertThat(e.statusCode()).isEqualTo(404); assertThat(e.contentType()).isPresent().get().isEqualTo("text/plain"); - assertThat(e.bodyAsString()).isEqualTo("Not Found"); + assertThat(e.bodyAsString()).isEqualTo("Endpoint GET /does-not-exist not found"); } } diff --git a/http-client/src/test/java/org/example/webserver/App.java b/http-client/src/test/java/org/example/webserver/App.java index 2c4972e9d..818e567de 100644 --- a/http-client/src/test/java/org/example/webserver/App.java +++ b/http-client/src/test/java/org/example/webserver/App.java @@ -27,12 +27,7 @@ public static Javalin start(int port) { Javalin.create( config -> { config.showJavalinBanner = false; - config.accessManager( - (handler, ctx, permittedRoles) -> { - log.debug("allow access ..."); - handler.handle(ctx); - }); - config.plugins.register(bean); + config.registerPlugin(bean); }); app.exception( diff --git a/http-client/src/test/java/org/example/webserver/HelloController$Route.java b/http-client/src/test/java/org/example/webserver/HelloController$Route.java index 673b1e71a..bca12e34b 100644 --- a/http-client/src/test/java/org/example/webserver/HelloController$Route.java +++ b/http-client/src/test/java/org/example/webserver/HelloController$Route.java @@ -6,13 +6,14 @@ import java.time.LocalDate; +import io.avaje.http.api.AvajeJavalinPlugin; import io.avaje.http.api.PathSegment; import io.avaje.http.api.Validator; -import io.javalin.Javalin; -import io.javalin.plugin.Plugin; +import io.javalin.config.JavalinConfig; +import io.javalin.router.JavalinDefaultRouting; //@Singleton -public class HelloController$Route implements Plugin{ +public class HelloController$Route extends AvajeJavalinPlugin { private final HelloController controller; private final Validator validator; @@ -22,8 +23,13 @@ public class HelloController$Route implements Plugin{ this.validator = validator; } + @Override - public void apply(Javalin cfg) { + public void onStart(JavalinConfig cfg) { + cfg.router.mount(this::routes); + } + + private void routes(JavalinDefaultRouting cfg) { cfg.get("/hello/message", ctx -> { ctx.status(200); From 3c71e43e0bc1fa42485b52783293552fed025528 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 30 Jan 2024 20:07:11 +1300 Subject: [PATCH 1017/1323] Version 2.1 --- http-api-javalin/pom.xml | 2 +- http-api/pom.xml | 2 +- http-client-gson-adapter/pom.xml | 4 ++-- http-client/pom.xml | 4 ++-- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 2 +- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-inject-plugin/pom.xml | 2 +- pom.xml | 2 +- tests/pom.xml | 2 +- tests/test-client-generation/pom.xml | 2 +- tests/test-client/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- 19 files changed, 21 insertions(+), 21 deletions(-) diff --git a/http-api-javalin/pom.xml b/http-api-javalin/pom.xml index 03f9f6d8a..565778a5c 100644 --- a/http-api-javalin/pom.xml +++ b/http-api-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.1-RC3 + 2.1 .. diff --git a/http-api/pom.xml b/http-api/pom.xml index de31f6ae5..10514661c 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.1-RC3 + 2.1 .. diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index 572f1c5c5..8e8bcd5a7 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.1-RC3 + 2.1 avaje-http-client-gson @@ -20,7 +20,7 @@ io.avaje avaje-http-client - 2.1-RC3 + 2.1 provided diff --git a/http-client/pom.xml b/http-client/pom.xml index e7988e1ae..b6e01f213 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.1-RC3 + 2.1 avaje-http-client @@ -73,7 +73,7 @@ io.avaje avaje-http-api - 2.1-RC3 + 2.1 diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index 165a75749..b52ecba74 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.1-RC3 + 2.1 avaje-http-client-generator diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 83afc986b..0824ede9b 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.1-RC3 + 2.1 avaje-http-generator-core diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index 2bbe6ea01..c0ee2ff9e 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.1-RC3 + 2.1 avaje-http-helidon-generator diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index cc59b6264..7c71b2e61 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.1-RC3 + 2.1 avaje-http-javalin-generator diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index a37c1afea..3d96d8e15 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.1-RC3 + 2.1 avaje-http-jex-generator diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index 231c0aa2a..df71741cd 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.1-RC3 + 2.1 .. diff --git a/pom.xml b/pom.xml index 09c0612ca..b4270e67c 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-parent - 2.1-RC3 + 2.1 pom diff --git a/tests/pom.xml b/tests/pom.xml index 446deb37d..585249ac5 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.1-RC3 + 2.1 tests diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index 5ab130edb..45c2dfd10 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.1-RC3 + 2.1 test-client-generation diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index 7df8cfa98..3640a102e 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.1-RC3 + 2.1 test-client diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 94432182c..3c330d5cb 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 2.1-RC3 + 2.1 test-javalin-jsonb diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index c69b1272e..7beb94f1a 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.1-RC3 + 2.1 test-javalin diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index c81100c26..1118e569d 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.1-RC3 + 2.1 test-jex diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 8b5e319de..760d1f760 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.1-RC3 + 2.1 test-nima-jsonb diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index 0d5c15f77..5d47805f4 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.1-RC3 + 2.1 test-nima From 533588a7edcae6c299c03e2a73ddf5a0ee34e4c5 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 30 Jan 2024 20:13:32 +1300 Subject: [PATCH 1018/1323] Bump to next snapshot --- http-api-javalin/pom.xml | 2 +- http-api/pom.xml | 2 +- http-client-gson-adapter/pom.xml | 4 ++-- http-client/pom.xml | 4 ++-- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 2 +- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-inject-plugin/pom.xml | 2 +- pom.xml | 2 +- tests/pom.xml | 2 +- tests/test-client-generation/pom.xml | 2 +- tests/test-client/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- 19 files changed, 21 insertions(+), 21 deletions(-) diff --git a/http-api-javalin/pom.xml b/http-api-javalin/pom.xml index 565778a5c..10ead3339 100644 --- a/http-api-javalin/pom.xml +++ b/http-api-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.1 + 2.2-SNAPSHOT .. diff --git a/http-api/pom.xml b/http-api/pom.xml index 10514661c..8d64516e0 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.1 + 2.2-SNAPSHOT .. diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index 8e8bcd5a7..85d90120c 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.1 + 2.2-SNAPSHOT avaje-http-client-gson @@ -20,7 +20,7 @@ io.avaje avaje-http-client - 2.1 + 2.2-SNAPSHOT provided diff --git a/http-client/pom.xml b/http-client/pom.xml index b6e01f213..f11229a65 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.1 + 2.2-SNAPSHOT avaje-http-client @@ -73,7 +73,7 @@ io.avaje avaje-http-api - 2.1 + 2.2-SNAPSHOT diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index b52ecba74..709367019 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.1 + 2.2-SNAPSHOT avaje-http-client-generator diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 0824ede9b..bd8c68521 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.1 + 2.2-SNAPSHOT avaje-http-generator-core diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index c0ee2ff9e..294d4c4e4 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.1 + 2.2-SNAPSHOT avaje-http-helidon-generator diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index 7c71b2e61..d0f1ac934 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.1 + 2.2-SNAPSHOT avaje-http-javalin-generator diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index 3d96d8e15..e209aeb5a 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.1 + 2.2-SNAPSHOT avaje-http-jex-generator diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index df71741cd..9932d2583 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.1 + 2.2-SNAPSHOT .. diff --git a/pom.xml b/pom.xml index b4270e67c..3eb6c22db 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-parent - 2.1 + 2.2-SNAPSHOT pom diff --git a/tests/pom.xml b/tests/pom.xml index 585249ac5..eff13a795 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.1 + 2.2-SNAPSHOT tests diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index 45c2dfd10..9cd12c5f0 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.1 + 2.2-SNAPSHOT test-client-generation diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index 3640a102e..f84127e3e 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.1 + 2.2-SNAPSHOT test-client diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 3c330d5cb..fa03a187e 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 2.1 + 2.2-SNAPSHOT test-javalin-jsonb diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 7beb94f1a..7c75c1f8a 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.1 + 2.2-SNAPSHOT test-javalin diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 1118e569d..98968274e 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.1 + 2.2-SNAPSHOT test-jex diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 760d1f760..655f0de55 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.1 + 2.2-SNAPSHOT test-nima-jsonb diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index 5d47805f4..dd18766eb 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.1 + 2.2-SNAPSHOT test-nima From c3bb7761c28b2d921376c7fec3c2a948a4aadcc7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 5 Feb 2024 19:45:56 +0000 Subject: [PATCH 1019/1323] Bump io.javalin:javalin from 6.0.0 to 6.0.1 Bumps [io.javalin:javalin](https://github.com/javalin/javalin) from 6.0.0 to 6.0.1. - [Release notes](https://github.com/javalin/javalin/releases) - [Commits](https://github.com/javalin/javalin/compare/javalin-parent-6.0.0...javalin-parent-6.0.1) --- updated-dependencies: - dependency-name: io.javalin:javalin dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- http-api/pom.xml | 2 +- http-client/pom.xml | 2 +- tests/pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/http-api/pom.xml b/http-api/pom.xml index 8d64516e0..aea857ad1 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -24,7 +24,7 @@ io.javalin javalin - 6.0.0 + 6.0.1 provided true diff --git a/http-client/pom.xml b/http-client/pom.xml index f11229a65..b4ab79200 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -66,7 +66,7 @@ io.javalin javalin - 6.0.0 + 6.0.1 test diff --git a/tests/pom.xml b/tests/pom.xml index eff13a795..e2f4f05a4 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -18,7 +18,7 @@ 2.5 9.10 4.0.4 - 6.0.0 + 6.0.1 From 124d2a3b54ab76091835ef80bb5b125ffe33b2ac Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 5 Feb 2024 19:47:58 +0000 Subject: [PATCH 1020/1323] Bump junit.version from 5.10.1 to 5.10.2 Bumps `junit.version` from 5.10.1 to 5.10.2. Updates `org.junit.jupiter:junit-jupiter-api` from 5.10.1 to 5.10.2 - [Release notes](https://github.com/junit-team/junit5/releases) - [Commits](https://github.com/junit-team/junit5/compare/r5.10.1...r5.10.2) Updates `org.junit.jupiter:junit-jupiter-engine` from 5.10.1 to 5.10.2 - [Release notes](https://github.com/junit-team/junit5/releases) - [Commits](https://github.com/junit-team/junit5/compare/r5.10.1...r5.10.2) --- updated-dependencies: - dependency-name: org.junit.jupiter:junit-jupiter-api dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: org.junit.jupiter:junit-jupiter-engine dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- tests/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/pom.xml b/tests/pom.xml index e2f4f05a4..267f2b1e1 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -12,7 +12,7 @@ true - 5.10.1 + 5.10.2 3.25.2 2.16.1 2.5 From 90d7f59435549c0c7cb5397d1cb5bf1c2133aacc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 5 Feb 2024 19:50:00 +0000 Subject: [PATCH 1021/1323] Bump org.assertj:assertj-core from 3.25.2 to 3.25.3 Bumps [org.assertj:assertj-core](https://github.com/assertj/assertj) from 3.25.2 to 3.25.3. - [Release notes](https://github.com/assertj/assertj/releases) - [Commits](https://github.com/assertj/assertj/compare/assertj-build-3.25.2...assertj-build-3.25.3) --- updated-dependencies: - dependency-name: org.assertj:assertj-core dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- tests/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/pom.xml b/tests/pom.xml index 267f2b1e1..082fa5898 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -13,7 +13,7 @@ true 5.10.2 - 3.25.2 + 3.25.3 2.16.1 2.5 9.10 From 12d70c7995d3a278bab12a499c39c94931c70684 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 6 Feb 2024 19:01:22 +0000 Subject: [PATCH 1022/1323] Bump nima.version from 4.0.4 to 4.0.5 Bumps `nima.version` from 4.0.4 to 4.0.5. Updates `io.helidon.webserver:helidon-webserver` from 4.0.4 to 4.0.5 Updates `io.helidon.http.media:helidon-http-media-jsonb` from 4.0.4 to 4.0.5 --- updated-dependencies: - dependency-name: io.helidon.webserver:helidon-webserver dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: io.helidon.http.media:helidon-http-media-jsonb dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- tests/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/pom.xml b/tests/pom.xml index 082fa5898..af31b3c6a 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -17,7 +17,7 @@ 2.16.1 2.5 9.10 - 4.0.4 + 4.0.5 6.0.1 From 92ab14d58769352ae72bcc7ba9f231d88c1f20fb Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Mon, 12 Feb 2024 13:26:17 -0500 Subject: [PATCH 1023/1323] Remove `jdk.crypto.ec` It's deprecated now I guess https://bugs.openjdk.org/browse/JDK-8312267 --- http-client/src/main/java/module-info.java | 1 - 1 file changed, 1 deletion(-) diff --git a/http-client/src/main/java/module-info.java b/http-client/src/main/java/module-info.java index cabe2d47d..f8445cd87 100644 --- a/http-client/src/main/java/module-info.java +++ b/http-client/src/main/java/module-info.java @@ -3,7 +3,6 @@ uses io.avaje.http.client.HttpClient.GeneratedComponent; requires transitive java.net.http; - requires transitive jdk.crypto.ec; requires transitive io.avaje.applog; requires static com.fasterxml.jackson.databind; requires static com.fasterxml.jackson.annotation; From e0a0c7dd09c4f41a9d94ce337759fd3471848d4f Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sat, 17 Feb 2024 11:23:27 -0500 Subject: [PATCH 1024/1323] support helidon path pattern --- .github/workflows/release.yml | 41 +++++++++++++++++++ .../http/generator/core/PathSegments.java | 2 +- .../helidon/nima/ControllerMethodWriter.java | 2 +- tests/test-nima-jsonb/.classpath | 6 +++ .../main/java/org/example/TestController.java | 10 +++++ 5 files changed, 59 insertions(+), 2 deletions(-) create mode 100644 .github/workflows/release.yml diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 000000000..0c1cf427e --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,41 @@ +on: + workflow_dispatch: + inputs: + version: + description: 'Version of the release' + required: true + +jobs: + publish: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Set up Java for publishing to Maven Central Repository + uses: actions/setup-java@v1 + with: + java-version: 11 + server-id: ossrh + server-username: MAVEN_USERNAME + server-password: MAVEN_PASSWORD + gpg-private-key: ${{ secrets.OSSRH_GPG_SECRET_KEY }} + gpg-passphrase: MAVEN_GPG_PASSPHRASE + - name: build artifact + run: mvn clean package + env: #can maybe do something with this? + VERSION: ${{ inputs.version }} + - name: Create release + uses: ncipollo/release-action@v1 + with: + allowUpdates: true + artifacts: "${{ github.workspace }}/target/*.jar" + token: ${{ secrets.GITHUB_TOKEN }} + - name: Publish to the Maven Central Repository + run: | + mvn \ + --no-transfer-progress \ + --batch-mode \ + deploy + env: + MAVEN_USERNAME: ${{ secrets.OSSRH_USERNAME }} + MAVEN_PASSWORD: ${{ secrets.OSSRH_TOKEN }} + MAVEN_GPG_PASSPHRASE: ${{ secrets.OSSRH_GPG_SECRET_KEY_PASSWORD }} diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/PathSegments.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/PathSegments.java index a278ed077..f5d21977a 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/PathSegments.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/PathSegments.java @@ -164,7 +164,7 @@ public static class Segment { * Create a normal segment. */ Segment(String name) { - this.name = name; + this.name = name.startsWith("+") ? name.substring(1) : name.split(":")[0]; this.sanitizedName = Util.sanitizeName(name); this.literalSection = null; this.matrixKeys = null; diff --git a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java index f7f7365ab..8a31e3a51 100644 --- a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java +++ b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java @@ -92,7 +92,7 @@ void writeRule() { } else if (isFilter) { writer.append(" routing.addFilter(this::_%s);", method.simpleName()).eol(); } else { - writer.append(" routing.%s(\"%s\", this::_%s);", webMethod.name().toLowerCase(), method.fullPath(), method.simpleName()).eol(); + writer.append(" routing.%s(\"%s\", this::_%s);", webMethod.name().toLowerCase(), method.fullPath().replace("\\", "\\\\"), method.simpleName()).eol(); } } diff --git a/tests/test-nima-jsonb/.classpath b/tests/test-nima-jsonb/.classpath index b636cdf6d..cb6ee63ad 100644 --- a/tests/test-nima-jsonb/.classpath +++ b/tests/test-nima-jsonb/.classpath @@ -39,11 +39,17 @@ + + + + + + diff --git a/tests/test-nima-jsonb/src/main/java/org/example/TestController.java b/tests/test-nima-jsonb/src/main/java/org/example/TestController.java index 098f4d8d6..6f8593d67 100644 --- a/tests/test-nima-jsonb/src/main/java/org/example/TestController.java +++ b/tests/test-nima-jsonb/src/main/java/org/example/TestController.java @@ -145,4 +145,14 @@ String formBean(MyForm form) { String maybeNoContent(Boolean empty) { return Boolean.TRUE.equals(empty) ? null : "Hi"; } + + @Get("/peppermint/{patty:\\d+}") + String pattern(String patty) { + return patty.toString(); + } + + @Get("/minus/{+plus}") + String patternPlus(String plus) { + return plus.toString(); + } } From f4f6bf40eb8d4b16888c0a1c5c4c3ec83bbde69a Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sat, 17 Feb 2024 11:30:09 -0500 Subject: [PATCH 1025/1323] Delete .github/workflows/release.yml --- .github/workflows/release.yml | 41 ----------------------------------- 1 file changed, 41 deletions(-) delete mode 100644 .github/workflows/release.yml diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml deleted file mode 100644 index 0c1cf427e..000000000 --- a/.github/workflows/release.yml +++ /dev/null @@ -1,41 +0,0 @@ -on: - workflow_dispatch: - inputs: - version: - description: 'Version of the release' - required: true - -jobs: - publish: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Set up Java for publishing to Maven Central Repository - uses: actions/setup-java@v1 - with: - java-version: 11 - server-id: ossrh - server-username: MAVEN_USERNAME - server-password: MAVEN_PASSWORD - gpg-private-key: ${{ secrets.OSSRH_GPG_SECRET_KEY }} - gpg-passphrase: MAVEN_GPG_PASSPHRASE - - name: build artifact - run: mvn clean package - env: #can maybe do something with this? - VERSION: ${{ inputs.version }} - - name: Create release - uses: ncipollo/release-action@v1 - with: - allowUpdates: true - artifacts: "${{ github.workspace }}/target/*.jar" - token: ${{ secrets.GITHUB_TOKEN }} - - name: Publish to the Maven Central Repository - run: | - mvn \ - --no-transfer-progress \ - --batch-mode \ - deploy - env: - MAVEN_USERNAME: ${{ secrets.OSSRH_USERNAME }} - MAVEN_PASSWORD: ${{ secrets.OSSRH_TOKEN }} - MAVEN_GPG_PASSPHRASE: ${{ secrets.OSSRH_GPG_SECRET_KEY_PASSWORD }} From be87eddf4686c466f9801beb4ba1627e12860974 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sat, 17 Feb 2024 11:31:01 -0500 Subject: [PATCH 1026/1323] Delete tests/test-nima-jsonb/.classpath --- tests/test-nima-jsonb/.classpath | 57 -------------------------------- 1 file changed, 57 deletions(-) delete mode 100644 tests/test-nima-jsonb/.classpath diff --git a/tests/test-nima-jsonb/.classpath b/tests/test-nima-jsonb/.classpath deleted file mode 100644 index cb6ee63ad..000000000 --- a/tests/test-nima-jsonb/.classpath +++ /dev/null @@ -1,57 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - From 177af3928a0207352c56b7f72c6935f3fce2052c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Feb 2024 19:08:26 +0000 Subject: [PATCH 1027/1323] Bump io.avaje:junit from 1.3 to 1.4 Bumps io.avaje:junit from 1.3 to 1.4. --- updated-dependencies: - dependency-name: io.avaje:junit dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- http-client-gson-adapter/pom.xml | 2 +- http-client/pom.xml | 2 +- pom.xml | 2 +- tests/test-client/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index 85d90120c..a2c054f76 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -29,7 +29,7 @@ io.avaje junit - 1.3 + 1.4 test diff --git a/http-client/pom.xml b/http-client/pom.xml index b4ab79200..396a6169a 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -59,7 +59,7 @@ io.avaje junit - 1.3 + 1.4 test diff --git a/pom.xml b/pom.xml index 3eb6c22db..ace448a13 100644 --- a/pom.xml +++ b/pom.xml @@ -29,7 +29,7 @@ io.avaje junit - 1.3 + 1.4 test diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index f84127e3e..b85f887dc 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -44,7 +44,7 @@ io.avaje junit - 1.3 + 1.4 test diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index fa03a187e..2760ea899 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -94,7 +94,7 @@ io.avaje junit - 1.3 + 1.4 test diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 7c75c1f8a..990de2fe4 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -87,7 +87,7 @@ io.avaje junit - 1.3 + 1.4 test diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 98968274e..3870a004f 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -87,7 +87,7 @@ io.avaje junit - 1.3 + 1.4 test diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 655f0de55..e14beca92 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -58,7 +58,7 @@ io.avaje junit - 1.3 + 1.4 test From 0902013484b6924757d7801495a71375470a3a9a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Feb 2024 19:10:00 +0000 Subject: [PATCH 1028/1323] Bump io.javalin:javalin from 6.0.1 to 6.1.0 Bumps [io.javalin:javalin](https://github.com/javalin/javalin) from 6.0.1 to 6.1.0. - [Release notes](https://github.com/javalin/javalin/releases) - [Commits](https://github.com/javalin/javalin/compare/javalin-parent-6.0.1...javalin-parent-6.1.0) --- updated-dependencies: - dependency-name: io.javalin:javalin dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- http-api/pom.xml | 2 +- http-client/pom.xml | 2 +- tests/pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/http-api/pom.xml b/http-api/pom.xml index aea857ad1..2ae8d3800 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -24,7 +24,7 @@ io.javalin javalin - 6.0.1 + 6.1.0 provided true diff --git a/http-client/pom.xml b/http-client/pom.xml index 396a6169a..7e5407f2e 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -66,7 +66,7 @@ io.javalin javalin - 6.0.1 + 6.1.0 test diff --git a/tests/pom.xml b/tests/pom.xml index af31b3c6a..b0418ef1c 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -18,7 +18,7 @@ 2.5 9.10 4.0.5 - 6.0.1 + 6.1.0 From cc2c54abc9c3cb2c2e5e589451997b00a04be3a9 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 20 Feb 2024 22:33:32 +1300 Subject: [PATCH 1029/1323] Version 2.2 --- http-api-javalin/pom.xml | 2 +- http-api/pom.xml | 2 +- http-client-gson-adapter/pom.xml | 4 ++-- http-client/pom.xml | 4 ++-- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 2 +- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-inject-plugin/pom.xml | 2 +- pom.xml | 2 +- tests/pom.xml | 2 +- tests/test-client-generation/pom.xml | 2 +- tests/test-client/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- 19 files changed, 21 insertions(+), 21 deletions(-) diff --git a/http-api-javalin/pom.xml b/http-api-javalin/pom.xml index 10ead3339..a80bf57b0 100644 --- a/http-api-javalin/pom.xml +++ b/http-api-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.2-SNAPSHOT + 2.2 .. diff --git a/http-api/pom.xml b/http-api/pom.xml index 2ae8d3800..67864dcf6 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.2-SNAPSHOT + 2.2 .. diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index a2c054f76..0c93a6445 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.2-SNAPSHOT + 2.2 avaje-http-client-gson @@ -20,7 +20,7 @@ io.avaje avaje-http-client - 2.2-SNAPSHOT + 2.2 provided diff --git a/http-client/pom.xml b/http-client/pom.xml index 7e5407f2e..8363970d8 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.2-SNAPSHOT + 2.2 avaje-http-client @@ -73,7 +73,7 @@ io.avaje avaje-http-api - 2.2-SNAPSHOT + 2.2 diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index 709367019..facb85fa1 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.2-SNAPSHOT + 2.2 avaje-http-client-generator diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index bd8c68521..5160fa46d 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.2-SNAPSHOT + 2.2 avaje-http-generator-core diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index 294d4c4e4..62f852539 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.2-SNAPSHOT + 2.2 avaje-http-helidon-generator diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index d0f1ac934..43e0288ce 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.2-SNAPSHOT + 2.2 avaje-http-javalin-generator diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index e209aeb5a..e2e11eb44 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.2-SNAPSHOT + 2.2 avaje-http-jex-generator diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index 9932d2583..213b89aee 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.2-SNAPSHOT + 2.2 .. diff --git a/pom.xml b/pom.xml index ace448a13..f5e268e76 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-parent - 2.2-SNAPSHOT + 2.2 pom diff --git a/tests/pom.xml b/tests/pom.xml index b0418ef1c..624451471 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.2-SNAPSHOT + 2.2 tests diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index 9cd12c5f0..8c199f3d3 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.2-SNAPSHOT + 2.2 test-client-generation diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index b85f887dc..18463cc19 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.2-SNAPSHOT + 2.2 test-client diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 2760ea899..8896f6b8d 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 2.2-SNAPSHOT + 2.2 test-javalin-jsonb diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 990de2fe4..a2d0cd8b5 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.2-SNAPSHOT + 2.2 test-javalin diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 3870a004f..9ae5053ef 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.2-SNAPSHOT + 2.2 test-jex diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index e14beca92..f03a40ae0 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.2-SNAPSHOT + 2.2 test-nima-jsonb diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index dd18766eb..9d3dcd214 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.2-SNAPSHOT + 2.2 test-nima From 8a4fd6dfb294dce3823a0349d2e57a0ecd80257c Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 20 Feb 2024 22:38:19 +1300 Subject: [PATCH 1030/1323] Bump to next snapshot --- http-api-javalin/pom.xml | 2 +- http-api/pom.xml | 2 +- http-client-gson-adapter/pom.xml | 4 ++-- http-client/pom.xml | 4 ++-- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 2 +- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-inject-plugin/pom.xml | 2 +- pom.xml | 2 +- tests/pom.xml | 2 +- tests/test-client-generation/pom.xml | 2 +- tests/test-client/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- 19 files changed, 21 insertions(+), 21 deletions(-) diff --git a/http-api-javalin/pom.xml b/http-api-javalin/pom.xml index a80bf57b0..227b30e20 100644 --- a/http-api-javalin/pom.xml +++ b/http-api-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.2 + 2.3-SNAPSHOT .. diff --git a/http-api/pom.xml b/http-api/pom.xml index 67864dcf6..4769e340b 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.2 + 2.3-SNAPSHOT .. diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index 0c93a6445..53cbd6358 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.2 + 2.3-SNAPSHOT avaje-http-client-gson @@ -20,7 +20,7 @@ io.avaje avaje-http-client - 2.2 + 2.3-SNAPSHOT provided diff --git a/http-client/pom.xml b/http-client/pom.xml index 8363970d8..dbaa0d198 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.2 + 2.3-SNAPSHOT avaje-http-client @@ -73,7 +73,7 @@ io.avaje avaje-http-api - 2.2 + 2.3-SNAPSHOT diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index facb85fa1..aee55b55b 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.2 + 2.3-SNAPSHOT avaje-http-client-generator diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 5160fa46d..909161d33 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.2 + 2.3-SNAPSHOT avaje-http-generator-core diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index 62f852539..2f925e52f 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.2 + 2.3-SNAPSHOT avaje-http-helidon-generator diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index 43e0288ce..c1282c185 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.2 + 2.3-SNAPSHOT avaje-http-javalin-generator diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index e2e11eb44..d6181902c 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.2 + 2.3-SNAPSHOT avaje-http-jex-generator diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index 213b89aee..3717261dc 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.2 + 2.3-SNAPSHOT .. diff --git a/pom.xml b/pom.xml index f5e268e76..b1709018e 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-parent - 2.2 + 2.3-SNAPSHOT pom diff --git a/tests/pom.xml b/tests/pom.xml index 624451471..9b916d3a6 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.2 + 2.3-SNAPSHOT tests diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index 8c199f3d3..c6a16f001 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.2 + 2.3-SNAPSHOT test-client-generation diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index 18463cc19..f2a5d58fb 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.2 + 2.3-SNAPSHOT test-client diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 8896f6b8d..7ca2d0174 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 2.2 + 2.3-SNAPSHOT test-javalin-jsonb diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index a2d0cd8b5..f232004af 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.2 + 2.3-SNAPSHOT test-javalin diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 9ae5053ef..5cbf37709 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.2 + 2.3-SNAPSHOT test-jex diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index f03a40ae0..4c8473556 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.2 + 2.3-SNAPSHOT test-nima-jsonb diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index 9d3dcd214..1bf392abd 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.2 + 2.3-SNAPSHOT test-nima From 3243ba1548638d4bf15d516d0a73aa2d43b3f776 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 20 Feb 2024 19:33:12 +0000 Subject: [PATCH 1031/1323] Bump io.avaje:avaje-jsonb from 1.9 to 1.10 Bumps [io.avaje:avaje-jsonb](https://github.com/avaje/avaje-jsonb) from 1.9 to 1.10. - [Release notes](https://github.com/avaje/avaje-jsonb/releases) - [Commits](https://github.com/avaje/avaje-jsonb/compare/1.9...1.10) --- updated-dependencies: - dependency-name: io.avaje:avaje-jsonb dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- http-client/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/http-client/pom.xml b/http-client/pom.xml index dbaa0d198..143bbf12c 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -36,7 +36,7 @@ io.avaje avaje-jsonb - 1.9 + 1.10 true diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 7ca2d0174..32c1e28f7 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -80,7 +80,7 @@ io.avaje avaje-jsonb - 1.9 + 1.10 diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 4c8473556..5e33e67a2 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -32,7 +32,7 @@ io.avaje avaje-jsonb - 1.9 + 1.10 io.avaje From b40de34b62edea281994ff0a1f41e3b4a33a1921 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 20 Feb 2024 19:35:19 +0000 Subject: [PATCH 1032/1323] Bump io.avaje:avaje-jsonb-generator from 1.9 to 1.10 Bumps io.avaje:avaje-jsonb-generator from 1.9 to 1.10. --- updated-dependencies: - dependency-name: io.avaje:avaje-jsonb-generator dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 32c1e28f7..938a20737 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -86,7 +86,7 @@ io.avaje avaje-jsonb-generator - 1.9 + 1.10 provided diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 5e33e67a2..571007b0e 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -91,7 +91,7 @@ io.avaje avaje-jsonb-generator - 1.9 + 1.10 From 6a6f6071c6a34bc7911820ddb8a1ebd30f075602 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 20 Feb 2024 19:37:15 +0000 Subject: [PATCH 1033/1323] Bump avaje-inject.version from 9.10 to 9.11 Bumps `avaje-inject.version` from 9.10 to 9.11. Updates `io.avaje:avaje-inject` from 9.10 to 9.11 - [Release notes](https://github.com/avaje/avaje-inject/releases) - [Commits](https://github.com/avaje/avaje-inject/compare/9.10...9.11) Updates `io.avaje:avaje-inject-generator` from 9.10 to 9.11 --- updated-dependencies: - dependency-name: io.avaje:avaje-inject dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: io.avaje:avaje-inject-generator dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- http-client/pom.xml | 4 ++-- http-inject-plugin/pom.xml | 2 +- tests/pom.xml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/http-client/pom.xml b/http-client/pom.xml index 143bbf12c..2492d8a95 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -43,7 +43,7 @@ io.avaje avaje-inject - 9.10 + 9.11 true @@ -105,7 +105,7 @@ io.avaje avaje-inject-generator - 9.10 + 9.11 diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index 3717261dc..10784cbbb 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -19,7 +19,7 @@ io.avaje avaje-inject - 9.10 + 9.11 provided true diff --git a/tests/pom.xml b/tests/pom.xml index 9b916d3a6..99e3fb788 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -16,7 +16,7 @@ 3.25.3 2.16.1 2.5 - 9.10 + 9.11 4.0.5 6.1.0 From 179f7329598e8ab43c37622fcdbb7a2b49652aa7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 23 Feb 2024 19:53:14 +0000 Subject: [PATCH 1034/1323] Bump io.javalin:javalin from 6.1.0 to 6.1.1 Bumps [io.javalin:javalin](https://github.com/javalin/javalin) from 6.1.0 to 6.1.1. - [Release notes](https://github.com/javalin/javalin/releases) - [Commits](https://github.com/javalin/javalin/compare/javalin-parent-6.1.0...javalin-parent-6.1.1) --- updated-dependencies: - dependency-name: io.javalin:javalin dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- http-api/pom.xml | 2 +- http-client/pom.xml | 2 +- tests/pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/http-api/pom.xml b/http-api/pom.xml index 4769e340b..f4666d103 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -24,7 +24,7 @@ io.javalin javalin - 6.1.0 + 6.1.1 provided true diff --git a/http-client/pom.xml b/http-client/pom.xml index 2492d8a95..876f76ec5 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -66,7 +66,7 @@ io.javalin javalin - 6.1.0 + 6.1.1 test diff --git a/tests/pom.xml b/tests/pom.xml index 99e3fb788..b4eee3206 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -18,7 +18,7 @@ 2.5 9.11 4.0.5 - 6.1.0 + 6.1.1 From 3d1cb0c8493530903fb8fcbd79dcb464bc404173 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sun, 25 Feb 2024 15:42:18 -0500 Subject: [PATCH 1035/1323] Javadoc badges (#393) * javadoc badges * update javadoc typos * fix doc --- README.md | 4 +++- .../java/io/avaje/http/client/HttpClient.java | 3 ++- .../avaje/http/client/HttpClientResponse.java | 24 +++++++++---------- 3 files changed, 17 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 955d2757a..bfe8803b0 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,10 @@ # [Avaje-HTTP](https://avaje.io/http/) +[![Discord](https://img.shields.io/discord/1074074312421683250?color=%237289da&label=discord)](https://discord.gg/Qcqf9R27BR) [![Build](https://github.com/avaje/avaje-http/actions/workflows/build.yml/badge.svg)](https://github.com/avaje/avaje-http/actions/workflows/build.yml) [![Maven Central : avaje-inject](https://img.shields.io/maven-central/v/io.avaje/avaje-http-api.svg?label=Maven%20Central)](https://maven-badges.herokuapp.com/maven-central/io.avaje/avaje-http-api) +[![javadoc](https://javadoc.io/badge2/io.avaje/avaje-http-api/http_api_javadoc.svg?&color=purple)](https://javadoc.io/doc/io.avaje/avaje-http-api) +[![javadoc](https://javadoc.io/badge2/io.avaje/avaje-http-client/http_client_javadoc.svg?&color=purple)](https://javadoc.io/doc/io.avaje/avaje-http-client) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://github.com/avaje/avaje-inject/blob/master/LICENSE) -[![Discord](https://img.shields.io/discord/1074074312421683250?color=%237289da&label=discord)](https://discord.gg/Qcqf9R27BR) HTTP server and client libraries via code generation. diff --git a/http-client/src/main/java/io/avaje/http/client/HttpClient.java b/http-client/src/main/java/io/avaje/http/client/HttpClient.java index f51f95cb3..38dc149b4 100644 --- a/http-client/src/main/java/io/avaje/http/client/HttpClient.java +++ b/http-client/src/main/java/io/avaje/http/client/HttpClient.java @@ -3,6 +3,7 @@ import java.net.Authenticator; import java.net.CookieHandler; import java.net.ProxySelector; +import java.net.http.HttpRequest; import java.time.Duration; import java.util.Map; import java.util.concurrent.Executor; @@ -69,7 +70,7 @@ static Builder builder() { HttpClientRequest request(); /** - * Return a UrlBuilder to use to build an URL taking into account the base URL. + * Returns a UrlBuilder to build a URL, considering the base URL. */ UrlBuilder url(); diff --git a/http-client/src/main/java/io/avaje/http/client/HttpClientResponse.java b/http-client/src/main/java/io/avaje/http/client/HttpClientResponse.java index cddf068b4..f50712bf2 100644 --- a/http-client/src/main/java/io/avaje/http/client/HttpClientResponse.java +++ b/http-client/src/main/java/io/avaje/http/client/HttpClientResponse.java @@ -63,7 +63,7 @@ public interface HttpClientResponse { /** * Return the response with the body containing a single instance of the given type. *

    - * If the HTTP statusCode is not in the 2XX range a HttpException is throw which contains + * If the HTTP statusCode is not in the 2XX range, an HttpException is thrown containing * the HttpResponse. This is the cause in the CompletionException when using an async request. * * @param type The type of the bean to convert the response content into. @@ -76,7 +76,7 @@ public interface HttpClientResponse { /** * Return the response with the body containing a single instance of the given type. *

    - * If the HTTP statusCode is not in the 2XX range a HttpException is throw which contains + * If the HTTP statusCode is not in the 2XX range, an HttpException is thrown containing * the HttpResponse. This is the cause in the CompletionException when using an async request. * * @param type The type of the bean to convert the response content into. @@ -88,7 +88,7 @@ public interface HttpClientResponse { /** * Return the response with the body containing a list of the given type. *

    - * If the HTTP statusCode is not in the 2XX range a HttpException is throw which contains + * If the HTTP statusCode is not in the 2XX range, an HttpException is thrown containing * the HttpResponse. This is the cause in the CompletionException when using an async request. * * @param type The type of the bean to convert the response content into. @@ -101,7 +101,7 @@ public interface HttpClientResponse { /** * Return the response with the body containing a list of the given type. *

    - * If the HTTP statusCode is not in the 2XX range a HttpException is throw which contains + * If the HTTP statusCode is not in the 2XX range, an HttpException is thrown containing * the HttpResponse. This is the cause in the CompletionException when using an async request. * * @param type The type of the bean to convert the response content into. @@ -122,7 +122,7 @@ public interface HttpClientResponse { * may not be available at the time of the callback. As such {@link RequestLogger} * will not include response content when logging stream request/response *

    - * If the HTTP statusCode is not in the 2XX range a HttpException is throw which contains + * If the HTTP statusCode is not in the 2XX range, an HttpException is thrown containing * the HttpResponse. This is the cause in the CompletionException when using an async request. * * @param type The type of the bean to convert the response content into. @@ -143,7 +143,7 @@ public interface HttpClientResponse { * may not be available at the time of the callback. As such {@link RequestLogger} * will not include response content when logging stream request/response *

    - * If the HTTP statusCode is not in the 2XX range a HttpException is throw which contains + * If the HTTP statusCode is not in the 2XX range, an HttpException is thrown containing * the HttpResponse. This is the cause in the CompletionException when using an async request. * * @param type The type of the bean to convert the response content into. @@ -156,7 +156,7 @@ public interface HttpClientResponse { /** * Return the response as a single bean. *

    - * If the HTTP statusCode is not in the 2XX range a HttpException is throw which contains + * If the HTTP statusCode is not in the 2XX range, an HttpException is thrown containing * the HttpResponse. This is the cause in the CompletionException when using an async request. * * @param type The type of the bean to convert the response content into. @@ -169,7 +169,7 @@ public interface HttpClientResponse { /** * Return the response as a list of beans. *

    - * If the HTTP statusCode is not in the 2XX range a HttpException is throw which contains + * If the HTTP statusCode is not in the 2XX range, an HttpException is thrown containing * the HttpResponse. This is the cause in the CompletionException when using an async request. * * @param type The type of the bean to convert the response content into. @@ -190,7 +190,7 @@ public interface HttpClientResponse { * may not be available at the time of the callback. As such {@link RequestLogger} * will not include response content when logging stream request/response *

    - * If the HTTP statusCode is not in the 2XX range a HttpException is throw which contains + * If the HTTP statusCode is not in the 2XX range, an HttpException is thrown containing * the HttpResponse. This is the cause in the CompletionException when using an async request. * * @param type The type of the bean to convert the response content into. @@ -203,7 +203,7 @@ public interface HttpClientResponse { /** * Return the response as a single bean. *

    - * If the HTTP statusCode is not in the 2XX range a HttpException is throw which contains + * If the HTTP statusCode is not in the 2XX range, an HttpException is thrown containing * the HttpResponse. This is the cause in the CompletionException when using an async request. * * @param type The type of the bean to convert the response content into. @@ -215,7 +215,7 @@ public interface HttpClientResponse { /** * Return the response as a list of beans. *

    - * If the HTTP statusCode is not in the 2XX range a HttpException is throw which contains + * If the HTTP statusCode is not in the 2XX range, an HttpException is thrown containing * the HttpResponse. This is the cause in the CompletionException when using an async request. * * @param type The type of the bean to convert the response content into. @@ -235,7 +235,7 @@ public interface HttpClientResponse { * may not be available at the time of the callback. As such {@link RequestLogger} * will not include response content when logging stream request/response *

    - * If the HTTP statusCode is not in the 2XX range a HttpException is throw which contains + * If the HTTP statusCode is not in the 2XX range, an HttpException is thrown containing * the HttpResponse. This is the cause in the CompletionException when using an async request. * * @param type The type of the bean to convert the response content into. From e5b74cd7e406c26523c764ef248a2dc3649c6654 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 Feb 2024 19:32:16 +0000 Subject: [PATCH 1036/1323] Bump io.javalin:javalin from 6.1.1 to 6.1.2 Bumps [io.javalin:javalin](https://github.com/javalin/javalin) from 6.1.1 to 6.1.2. - [Release notes](https://github.com/javalin/javalin/releases) - [Commits](https://github.com/javalin/javalin/compare/javalin-parent-6.1.1...javalin-parent-6.1.2) --- updated-dependencies: - dependency-name: io.javalin:javalin dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- http-api/pom.xml | 2 +- http-client/pom.xml | 2 +- tests/pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/http-api/pom.xml b/http-api/pom.xml index f4666d103..38416a409 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -24,7 +24,7 @@ io.javalin javalin - 6.1.1 + 6.1.2 provided true diff --git a/http-client/pom.xml b/http-client/pom.xml index 876f76ec5..63e7a55d6 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -66,7 +66,7 @@ io.javalin javalin - 6.1.1 + 6.1.2 test diff --git a/tests/pom.xml b/tests/pom.xml index b4eee3206..1eff3a2dd 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -18,7 +18,7 @@ 2.5 9.11 4.0.5 - 6.1.1 + 6.1.2 From 9bed11c97d1eb16e7ee5dcd58dcb5f3e0e40cd97 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 Mar 2024 19:31:37 +0000 Subject: [PATCH 1037/1323] Bump io.javalin:javalin from 6.1.2 to 6.1.3 Bumps [io.javalin:javalin](https://github.com/javalin/javalin) from 6.1.2 to 6.1.3. - [Release notes](https://github.com/javalin/javalin/releases) - [Commits](https://github.com/javalin/javalin/compare/javalin-parent-6.1.2...javalin-parent-6.1.3) --- updated-dependencies: - dependency-name: io.javalin:javalin dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- http-api/pom.xml | 2 +- http-client/pom.xml | 2 +- tests/pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/http-api/pom.xml b/http-api/pom.xml index 38416a409..251933d62 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -24,7 +24,7 @@ io.javalin javalin - 6.1.2 + 6.1.3 provided true diff --git a/http-client/pom.xml b/http-client/pom.xml index 63e7a55d6..fc90043e7 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -66,7 +66,7 @@ io.javalin javalin - 6.1.2 + 6.1.3 test diff --git a/tests/pom.xml b/tests/pom.xml index 1eff3a2dd..c86e61d22 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -18,7 +18,7 @@ 2.5 9.11 4.0.5 - 6.1.2 + 6.1.3 From d0c5fd21014121df4086684613f23951ae756beb Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Fri, 8 Mar 2024 00:49:48 -0500 Subject: [PATCH 1038/1323] fix helidon nested types --- .../io/avaje/http/generator/core/UType.java | 46 +++++++++---------- .../org/example/path/PathTestController.java | 7 +++ .../example/path/nest/PathNestController.java | 3 ++ 3 files changed, 33 insertions(+), 23 deletions(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java index e86848f12..f22658b2b 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java @@ -75,6 +75,28 @@ default String genericParams() { return ""; } + static String innerTypesImport(String type) { + final var parts = type.split("\\."); + var result = ""; + var foundUpper = false; + + for (var i = 0; i < parts.length; i++) { + if (!Character.isUpperCase(parts[i].charAt(0))) { + result += parts[i] + "."; + } else if (!foundUpper) { + foundUpper = true; + result += parts[i] + (i == parts.length - 1 ? "" : "."); + } else { + break; + } + } + + if (result.endsWith(".")) { + result = result.substring(0, result.length() - 1); + } + return result; + } + class VoidType implements UType { @Override @@ -122,7 +144,7 @@ public String full() { public Set importTypes() { return isJavaLangPackage(rawType) ? Set.of() - : Collections.singleton(rawType.replace("[]", "")); + : Collections.singleton(innerTypesImport(rawType.replace("[]", ""))); } @Override @@ -217,28 +239,6 @@ public Set importTypes() { return set; } - public String innerTypesImport(String type) { - final var parts = type.split("\\."); - var result = ""; - var foundUpper = false; - - for (var i = 0; i < parts.length; i++) { - if (!Character.isUpperCase(parts[i].charAt(0))) { - result += parts[i] + "."; - } else if (!foundUpper) { - foundUpper = true; - result += parts[i] + (i == parts.length - 1 ? "" : "."); - } else { - break; - } - } - - if (result.endsWith(".")) { - result = result.substring(0, result.length() - 1); - } - return result; - } - @Override public boolean isGeneric() { return true; diff --git a/tests/test-nima-jsonb/src/main/java/org/example/path/PathTestController.java b/tests/test-nima-jsonb/src/main/java/org/example/path/PathTestController.java index d1787fdf9..5d1a3f970 100644 --- a/tests/test-nima-jsonb/src/main/java/org/example/path/PathTestController.java +++ b/tests/test-nima-jsonb/src/main/java/org/example/path/PathTestController.java @@ -1,5 +1,7 @@ package org.example.path; +import org.example.path.nest.PathNestController.NestedTypeResponse; + import io.avaje.http.api.Controller; import io.avaje.http.api.Get; import io.avaje.http.api.Path; @@ -14,4 +16,9 @@ public class PathTestController { String hello() { return "hi"; } + + @Get("/nested/respo") + NestedTypeResponse nested() { + return new NestedTypeResponse(0, null); + } } diff --git a/tests/test-nima-jsonb/src/main/java/org/example/path/nest/PathNestController.java b/tests/test-nima-jsonb/src/main/java/org/example/path/nest/PathNestController.java index bdd49b65e..47fb7479c 100644 --- a/tests/test-nima-jsonb/src/main/java/org/example/path/nest/PathNestController.java +++ b/tests/test-nima-jsonb/src/main/java/org/example/path/nest/PathNestController.java @@ -4,10 +4,13 @@ import io.avaje.http.api.Get; import io.avaje.http.api.Path; import io.avaje.http.api.Produces; +import io.avaje.jsonb.Json; @Path("test") @Controller public class PathNestController { + @Json + public record NestedTypeResponse(long id, String name) {} @Produces("text/plain") @Get From c85d2ec52d63dca44cb9fe7afa8e542380cdd79a Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Mon, 11 Mar 2024 09:07:02 +1300 Subject: [PATCH 1039/1323] Version 2.3-RC1 --- http-api-javalin/pom.xml | 2 +- http-api/pom.xml | 2 +- http-client-gson-adapter/pom.xml | 4 ++-- http-client/pom.xml | 4 ++-- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 2 +- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-inject-plugin/pom.xml | 2 +- pom.xml | 2 +- tests/pom.xml | 2 +- tests/test-client-generation/pom.xml | 2 +- tests/test-client/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- 19 files changed, 21 insertions(+), 21 deletions(-) diff --git a/http-api-javalin/pom.xml b/http-api-javalin/pom.xml index 227b30e20..1ff083419 100644 --- a/http-api-javalin/pom.xml +++ b/http-api-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.3-SNAPSHOT + 2.3-RC1 .. diff --git a/http-api/pom.xml b/http-api/pom.xml index 251933d62..87f35e005 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.3-SNAPSHOT + 2.3-RC1 .. diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index 53cbd6358..c92cd1df4 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.3-SNAPSHOT + 2.3-RC1 avaje-http-client-gson @@ -20,7 +20,7 @@ io.avaje avaje-http-client - 2.3-SNAPSHOT + 2.3-RC1 provided diff --git a/http-client/pom.xml b/http-client/pom.xml index fc90043e7..ad2cbc29c 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.3-SNAPSHOT + 2.3-RC1 avaje-http-client @@ -73,7 +73,7 @@ io.avaje avaje-http-api - 2.3-SNAPSHOT + 2.3-RC1 diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index aee55b55b..27a35db46 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.3-SNAPSHOT + 2.3-RC1 avaje-http-client-generator diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 909161d33..32ae33bdf 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.3-SNAPSHOT + 2.3-RC1 avaje-http-generator-core diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index 2f925e52f..45ec73065 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.3-SNAPSHOT + 2.3-RC1 avaje-http-helidon-generator diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index c1282c185..c45512818 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.3-SNAPSHOT + 2.3-RC1 avaje-http-javalin-generator diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index d6181902c..5f71cbd24 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.3-SNAPSHOT + 2.3-RC1 avaje-http-jex-generator diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index 10784cbbb..7a36cb0d3 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.3-SNAPSHOT + 2.3-RC1 .. diff --git a/pom.xml b/pom.xml index b1709018e..e9f9d8863 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-parent - 2.3-SNAPSHOT + 2.3-RC1 pom diff --git a/tests/pom.xml b/tests/pom.xml index c86e61d22..334acd786 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.3-SNAPSHOT + 2.3-RC1 tests diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index c6a16f001..554be8bf5 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.3-SNAPSHOT + 2.3-RC1 test-client-generation diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index f2a5d58fb..a9c4f948a 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.3-SNAPSHOT + 2.3-RC1 test-client diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 938a20737..47d7181fb 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 2.3-SNAPSHOT + 2.3-RC1 test-javalin-jsonb diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index f232004af..7dfa2ea65 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.3-SNAPSHOT + 2.3-RC1 test-javalin diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 5cbf37709..130ae2d83 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.3-SNAPSHOT + 2.3-RC1 test-jex diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 571007b0e..ad24b2e90 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.3-SNAPSHOT + 2.3-RC1 test-nima-jsonb diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index 1bf392abd..1ff037a1f 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.3-SNAPSHOT + 2.3-RC1 test-nima From a2c1600dbde40787a9af621a8b8552ef89ec0391 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 11 Mar 2024 19:48:23 +0000 Subject: [PATCH 1040/1323] Bump com.fasterxml.jackson.core:jackson-databind from 2.16.1 to 2.16.2 Bumps [com.fasterxml.jackson.core:jackson-databind](https://github.com/FasterXML/jackson) from 2.16.1 to 2.16.2. - [Commits](https://github.com/FasterXML/jackson/commits) --- updated-dependencies: - dependency-name: com.fasterxml.jackson.core:jackson-databind dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- http-client/pom.xml | 2 +- tests/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/http-client/pom.xml b/http-client/pom.xml index ad2cbc29c..2526c0ad4 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -29,7 +29,7 @@ com.fasterxml.jackson.core jackson-databind - 2.16.1 + 2.16.2 true diff --git a/tests/pom.xml b/tests/pom.xml index 334acd786..98e55419c 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -14,7 +14,7 @@ true 5.10.2 3.25.3 - 2.16.1 + 2.16.2 2.5 9.11 4.0.5 From 55b27a6de2dd70b585d28f53b7acf479235629d9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 13 Mar 2024 19:34:29 +0000 Subject: [PATCH 1041/1323] Bump com.fasterxml.jackson.core:jackson-databind from 2.16.2 to 2.17.0 Bumps [com.fasterxml.jackson.core:jackson-databind](https://github.com/FasterXML/jackson) from 2.16.2 to 2.17.0. - [Commits](https://github.com/FasterXML/jackson/commits) --- updated-dependencies: - dependency-name: com.fasterxml.jackson.core:jackson-databind dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- http-client/pom.xml | 2 +- tests/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/http-client/pom.xml b/http-client/pom.xml index 2526c0ad4..68250f2eb 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -29,7 +29,7 @@ com.fasterxml.jackson.core jackson-databind - 2.16.2 + 2.17.0 true diff --git a/tests/pom.xml b/tests/pom.xml index 98e55419c..b60d7be64 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -14,7 +14,7 @@ true 5.10.2 3.25.3 - 2.16.2 + 2.17.0 2.5 9.11 4.0.5 From 8c864ae21e97ff08b91f21c419dd8761ebf15518 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Fri, 15 Mar 2024 04:37:29 -0400 Subject: [PATCH 1042/1323] [http-client] Add `@Headers` Annotation (#402) * add Headers Annotation * Format only changes --------- Co-authored-by: Rob Bygrave --- .../main/java/io/avaje/http/api/Headers.java | 32 +++++++++++++++++++ .../generator/client/ClientMethodWriter.java | 25 +++++++++++++++ .../generator/client/ClientProcessor.java | 2 ++ .../generator/client/clients/TitanFall.java | 4 +++ 4 files changed, 63 insertions(+) create mode 100644 http-api/src/main/java/io/avaje/http/api/Headers.java diff --git a/http-api/src/main/java/io/avaje/http/api/Headers.java b/http-api/src/main/java/io/avaje/http/api/Headers.java new file mode 100644 index 000000000..47486a084 --- /dev/null +++ b/http-api/src/main/java/io/avaje/http/api/Headers.java @@ -0,0 +1,32 @@ +package io.avaje.http.api; + +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +/** + * Headers for an Http @Client interface method. + * + *

    We can put this on a method or the interface to add preset headers to the generated + * implementation bean property. + * + *

    {@code
    + * @Headers({
    + * "Accept: application/vnd.github.v3.full+json",
    + * "User-Agent: Avaje-Sample-App"
    + * })
    + * @Get("users/{username}")
    + * User getUser(@Path("username") String username);
    + *
    + * }
    + */ +@Retention(RUNTIME) +@Target({TYPE, METHOD}) +public @interface Headers { + + /** The array of headers */ + String[] value(); +} diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java index a9175d406..ed838d217 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java @@ -7,11 +7,15 @@ import javax.lang.model.util.ElementFilter; import java.util.List; import java.util.Map; +import java.util.Map.Entry; import java.util.Optional; import java.util.Set; +import java.util.function.Function; import java.util.stream.Collectors; +import java.util.stream.Stream; import static io.avaje.http.generator.core.ProcessingContext.*; +import static java.util.stream.Collectors.toList; import static java.util.stream.Collectors.toMap; /** @@ -35,6 +39,7 @@ final class ClientMethodWriter { private final boolean useConfig; private final Map segmentPropertyMap; private final Set propertyConstants; + private final List> presetHeaders; ClientMethodWriter(MethodReader method, Append writer, boolean useJsonb, Set propertyConstants) { this.method = method; @@ -50,6 +55,24 @@ final class ClientMethodWriter { .filter(Segment::isProperty) .collect(toMap(Segment::name, s -> Util.sanitizeName(s.name()).toUpperCase())); this.propertyConstants = propertyConstants; + var element = method.element(); + + this.presetHeaders = + Stream.concat( + HeadersPrism.getOptionalOn(element).stream(), + HeadersPrism.getOptionalOn(element.getEnclosingElement()).stream()) + .map(HeadersPrism::value) + .map(List::stream) + .flatMap(Function.identity()) + .peek( + s -> { + if (!s.contains(":")) { + logError(element, "@Headers value must have a \":\"", method); + } + }) + .map(s -> s.split(":", 2)) + .filter(a -> a.length == 2) + .map(a -> Map.entry(a[0].trim(), a[1].trim())).collect(toList()); } void addImportTypes(ControllerReader reader) { @@ -272,6 +295,8 @@ private void writeHeaders() { } } } + presetHeaders.forEach(e -> + writer.append(" .header(\"%s\", \"%s\")", e.getKey(), e.getValue().replace("\\", "\\\\")).eol()); } private void writeBeanParams(PathSegments segments) { diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java index 05b14fc04..99a3d2512 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java @@ -21,7 +21,9 @@ import io.avaje.http.generator.core.ControllerReader; import io.avaje.http.generator.core.ImportPrism; import io.avaje.http.generator.core.ProcessingContext; +import io.avaje.prism.GeneratePrism; +@GeneratePrism(io.avaje.http.api.Headers.class) @SupportedAnnotationTypes({ClientPrism.PRISM_TYPE, ImportPrism.PRISM_TYPE}) public class ClientProcessor extends AbstractProcessor { diff --git a/http-generator-client/src/test/java/io/avaje/http/generator/client/clients/TitanFall.java b/http-generator-client/src/test/java/io/avaje/http/generator/client/clients/TitanFall.java index 918c685fa..64d32e84f 100644 --- a/http-generator-client/src/test/java/io/avaje/http/generator/client/clients/TitanFall.java +++ b/http-generator-client/src/test/java/io/avaje/http/generator/client/clients/TitanFall.java @@ -2,14 +2,18 @@ import io.avaje.http.api.Client; import io.avaje.http.api.Get; +import io.avaje.http.api.Headers; @Client +@Headers("Content-Type: applicaton/json") public interface TitanFall { @Get("/${titan}/${drop.point}") + @Headers("Something: \\invalid\n\t") Titan titanFall(); @Get("/${titan}/copium") + @Headers(" Accept : applicaton/json") Titan titanFall3(); } \ No newline at end of file From 27c83d149f980425d4df2e095865f3ec2dc2ef35 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Fri, 15 Mar 2024 21:42:32 +1300 Subject: [PATCH 1043/1323] Version 2.3-RC2 --- http-api-javalin/pom.xml | 2 +- http-api/pom.xml | 2 +- http-client-gson-adapter/pom.xml | 4 ++-- http-client/pom.xml | 4 ++-- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 2 +- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-inject-plugin/pom.xml | 2 +- pom.xml | 2 +- tests/pom.xml | 2 +- tests/test-client-generation/pom.xml | 2 +- tests/test-client/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- 19 files changed, 21 insertions(+), 21 deletions(-) diff --git a/http-api-javalin/pom.xml b/http-api-javalin/pom.xml index 1ff083419..afa876497 100644 --- a/http-api-javalin/pom.xml +++ b/http-api-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.3-RC1 + 2.3-RC2 .. diff --git a/http-api/pom.xml b/http-api/pom.xml index 87f35e005..796953b08 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.3-RC1 + 2.3-RC2 .. diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index c92cd1df4..191f47e8a 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.3-RC1 + 2.3-RC2 avaje-http-client-gson @@ -20,7 +20,7 @@ io.avaje avaje-http-client - 2.3-RC1 + 2.3-RC2 provided diff --git a/http-client/pom.xml b/http-client/pom.xml index 68250f2eb..581061896 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.3-RC1 + 2.3-RC2 avaje-http-client @@ -73,7 +73,7 @@ io.avaje avaje-http-api - 2.3-RC1 + 2.3-RC2 diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index 27a35db46..146b08cf4 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.3-RC1 + 2.3-RC2 avaje-http-client-generator diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 32ae33bdf..e34af456a 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.3-RC1 + 2.3-RC2 avaje-http-generator-core diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index 45ec73065..de1347cc5 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.3-RC1 + 2.3-RC2 avaje-http-helidon-generator diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index c45512818..eb3343594 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.3-RC1 + 2.3-RC2 avaje-http-javalin-generator diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index 5f71cbd24..7d9e2dd62 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.3-RC1 + 2.3-RC2 avaje-http-jex-generator diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index 7a36cb0d3..e191c46eb 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.3-RC1 + 2.3-RC2 .. diff --git a/pom.xml b/pom.xml index e9f9d8863..e5b21f76b 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-parent - 2.3-RC1 + 2.3-RC2 pom diff --git a/tests/pom.xml b/tests/pom.xml index b60d7be64..b9d43cb09 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.3-RC1 + 2.3-RC2 tests diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index 554be8bf5..27a54ff2b 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.3-RC1 + 2.3-RC2 test-client-generation diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index a9c4f948a..0ee97e666 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.3-RC1 + 2.3-RC2 test-client diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 47d7181fb..f41b9d573 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 2.3-RC1 + 2.3-RC2 test-javalin-jsonb diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 7dfa2ea65..1ecce13ae 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.3-RC1 + 2.3-RC2 test-javalin diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 130ae2d83..3426f81d9 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.3-RC1 + 2.3-RC2 test-jex diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index ad24b2e90..33682c8ea 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.3-RC1 + 2.3-RC2 test-nima-jsonb diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index 1ff037a1f..e7bc0982f 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.3-RC1 + 2.3-RC2 test-nima From 52b98d2d57a682f9b5d6943a8f2a6dc95b41032d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 15 Mar 2024 19:13:52 +0000 Subject: [PATCH 1044/1323] Bump nima.version from 4.0.5 to 4.0.6 Bumps `nima.version` from 4.0.5 to 4.0.6. Updates `io.helidon.webserver:helidon-webserver` from 4.0.5 to 4.0.6 Updates `io.helidon.http.media:helidon-http-media-jsonb` from 4.0.5 to 4.0.6 --- updated-dependencies: - dependency-name: io.helidon.webserver:helidon-webserver dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: io.helidon.http.media:helidon-http-media-jsonb dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- tests/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/pom.xml b/tests/pom.xml index b9d43cb09..5b474e8b9 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -17,7 +17,7 @@ 2.17.0 2.5 9.11 - 4.0.5 + 4.0.6 6.1.3 From cc8357817c87df49399a26e51deedc397adf941f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 18 Mar 2024 19:15:31 +0000 Subject: [PATCH 1045/1323] Bump org.apache.maven.plugins:maven-compiler-plugin Bumps [org.apache.maven.plugins:maven-compiler-plugin](https://github.com/apache/maven-compiler-plugin) from 3.12.1 to 3.13.0. - [Release notes](https://github.com/apache/maven-compiler-plugin/releases) - [Commits](https://github.com/apache/maven-compiler-plugin/compare/maven-compiler-plugin-3.12.1...maven-compiler-plugin-3.13.0) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-compiler-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- http-client/pom.xml | 2 +- tests/test-client-generation/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/http-client/pom.xml b/http-client/pom.xml index 581061896..bdfc43fbb 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -96,7 +96,7 @@ org.apache.maven.plugins maven-compiler-plugin - 3.12.1 + 3.13.0 default-testCompile diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index 27a54ff2b..9f157dd5b 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -98,7 +98,7 @@ org.apache.maven.plugins maven-compiler-plugin - 3.12.1 + 3.13.0 diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index e7bc0982f..123dc0123 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -51,7 +51,7 @@ org.apache.maven.plugins maven-compiler-plugin - 3.12.1 + 3.13.0 21 From b2275448251f47072b3db260a91bae82f0cb75da Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 19 Mar 2024 19:19:06 +0000 Subject: [PATCH 1046/1323] Bump com.squareup.retrofit2:converter-scalars from 2.9.0 to 2.10.0 Bumps [com.squareup.retrofit2:converter-scalars](https://github.com/square/retrofit) from 2.9.0 to 2.10.0. - [Release notes](https://github.com/square/retrofit/releases) - [Changelog](https://github.com/square/retrofit/blob/trunk/CHANGELOG.md) - [Commits](https://github.com/square/retrofit/compare/2.9.0...2.10.0) --- updated-dependencies: - dependency-name: com.squareup.retrofit2:converter-scalars dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- tests/test-client-generation/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index 9f157dd5b..c1b1eb37f 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -56,7 +56,7 @@ com.squareup.retrofit2 converter-scalars - 2.9.0 + 2.10.0 From d42d7499c86eb2ed724a94fbfe8c6f38f0371870 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 19 Mar 2024 19:21:08 +0000 Subject: [PATCH 1047/1323] Bump com.squareup.retrofit2:retrofit from 2.9.0 to 2.10.0 Bumps [com.squareup.retrofit2:retrofit](https://github.com/square/retrofit) from 2.9.0 to 2.10.0. - [Release notes](https://github.com/square/retrofit/releases) - [Changelog](https://github.com/square/retrofit/blob/trunk/CHANGELOG.md) - [Commits](https://github.com/square/retrofit/compare/2.9.0...2.10.0) --- updated-dependencies: - dependency-name: com.squareup.retrofit2:retrofit dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- tests/test-client-generation/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index c1b1eb37f..da228ff7e 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -44,7 +44,7 @@ com.squareup.retrofit2 retrofit - 2.9.0 + 2.10.0 From 46bf7b72698dbe5febf4400ff11346bc28b6a755 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 19 Mar 2024 19:23:02 +0000 Subject: [PATCH 1048/1323] Bump com.squareup.retrofit2:converter-gson from 2.9.0 to 2.10.0 Bumps [com.squareup.retrofit2:converter-gson](https://github.com/square/retrofit) from 2.9.0 to 2.10.0. - [Release notes](https://github.com/square/retrofit/releases) - [Changelog](https://github.com/square/retrofit/blob/trunk/CHANGELOG.md) - [Commits](https://github.com/square/retrofit/compare/2.9.0...2.10.0) --- updated-dependencies: - dependency-name: com.squareup.retrofit2:converter-gson dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- tests/test-client-generation/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index da228ff7e..132db89f4 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -50,7 +50,7 @@ com.squareup.retrofit2 converter-gson - 2.9.0 + 2.10.0 From f5a80b6b9ffb0ad5ad2240e9be5ed7b0631c67b9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 20 Mar 2024 19:02:36 +0000 Subject: [PATCH 1049/1323] Bump swagger.version from 2.2.20 to 2.2.21 Bumps `swagger.version` from 2.2.20 to 2.2.21. Updates `io.swagger.core.v3:swagger-annotations` from 2.2.20 to 2.2.21 Updates `io.swagger.core.v3:swagger-models` from 2.2.20 to 2.2.21 --- updated-dependencies: - dependency-name: io.swagger.core.v3:swagger-annotations dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: io.swagger.core.v3:swagger-models dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index e5b21f76b..2a26dcbe6 100644 --- a/pom.xml +++ b/pom.xml @@ -19,7 +19,7 @@ true - 2.2.20 + 2.2.21 2.14.2 1.21 ${project.build.directory}${file.separator}module-info.shade diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index f41b9d573..513404162 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -13,7 +13,7 @@ true org.example.myapp.Main - 2.2.20 + 2.2.21 1.3.71 diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 1ecce13ae..7496e44e7 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -12,7 +12,7 @@ true org.example.myapp.Main - 2.2.20 + 2.2.21 1.3.71 diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 3426f81d9..6b9983345 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -13,7 +13,7 @@ true org.example.myapp.Main 2.5 - 2.2.20 + 2.2.21 From 4fc840346a35d855349269b7adacc5feb757d5c2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 29 Mar 2024 19:27:50 +0000 Subject: [PATCH 1050/1323] Bump com.squareup.retrofit2:converter-scalars from 2.10.0 to 2.11.0 Bumps [com.squareup.retrofit2:converter-scalars](https://github.com/square/retrofit) from 2.10.0 to 2.11.0. - [Release notes](https://github.com/square/retrofit/releases) - [Changelog](https://github.com/square/retrofit/blob/trunk/CHANGELOG.md) - [Commits](https://github.com/square/retrofit/compare/2.10.0...2.11.0) --- updated-dependencies: - dependency-name: com.squareup.retrofit2:converter-scalars dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- tests/test-client-generation/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index 132db89f4..13ecfae22 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -56,7 +56,7 @@ com.squareup.retrofit2 converter-scalars - 2.10.0 + 2.11.0 From 88167698bfadd0b3620993b26bd68c0a0246a8b8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 29 Mar 2024 19:29:42 +0000 Subject: [PATCH 1051/1323] Bump com.squareup.retrofit2:retrofit from 2.10.0 to 2.11.0 Bumps [com.squareup.retrofit2:retrofit](https://github.com/square/retrofit) from 2.10.0 to 2.11.0. - [Release notes](https://github.com/square/retrofit/releases) - [Changelog](https://github.com/square/retrofit/blob/trunk/CHANGELOG.md) - [Commits](https://github.com/square/retrofit/compare/2.10.0...2.11.0) --- updated-dependencies: - dependency-name: com.squareup.retrofit2:retrofit dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- tests/test-client-generation/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index 13ecfae22..6de3ec1c8 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -44,7 +44,7 @@ com.squareup.retrofit2 retrofit - 2.10.0 + 2.11.0 From 172bfb9024980ec781d73fc406a25058f7825bfe Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 29 Mar 2024 19:31:54 +0000 Subject: [PATCH 1052/1323] Bump com.squareup.retrofit2:converter-gson from 2.10.0 to 2.11.0 Bumps [com.squareup.retrofit2:converter-gson](https://github.com/square/retrofit) from 2.10.0 to 2.11.0. - [Release notes](https://github.com/square/retrofit/releases) - [Changelog](https://github.com/square/retrofit/blob/trunk/CHANGELOG.md) - [Commits](https://github.com/square/retrofit/compare/2.10.0...2.11.0) --- updated-dependencies: - dependency-name: com.squareup.retrofit2:converter-gson dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- tests/test-client-generation/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index 6de3ec1c8..3b8573a74 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -50,7 +50,7 @@ com.squareup.retrofit2 converter-gson - 2.10.0 + 2.11.0 From 6f5c92edf787e8206b2421d850f55ee1d2c31c25 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Fri, 5 Apr 2024 00:07:05 -0400 Subject: [PATCH 1053/1323] can now read record javadocs for openapi --- .../core/openapi/SchemaDocBuilder.java | 20 +++++++++++++++++-- .../src/main/java/org/example/Person.java | 8 +++++--- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/SchemaDocBuilder.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/SchemaDocBuilder.java index d1fbeb8fe..7eac9ddc1 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/SchemaDocBuilder.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/SchemaDocBuilder.java @@ -7,6 +7,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.Set; import java.util.TreeMap; import java.util.stream.Stream; @@ -168,7 +169,7 @@ Schema toSchema(TypeMirror type) { private Schema buildEnumSchema(Element e) { var schema = new StringSchema(); e.getEnclosedElements().stream() - .filter(ec -> ec.getKind().equals(ElementKind.ENUM_CONSTANT)) + .filter(ec -> ElementKind.ENUM_CONSTANT.equals(ec.getKind())) .forEach(ec -> schema.addEnumItem(ec.getSimpleName().toString())); var doc = Javadoc.parse(elements.getDocComment(e)); @@ -267,8 +268,21 @@ private void setFormatFromValidation(Element element, Schema propSchema) { private void setDescription(Element element, Schema propSchema) { var doc = Javadoc.parse(elements.getDocComment(element)); + if (!doc.getSummary().isEmpty()) { propSchema.setDescription(doc.getSummary()); + return; + } + try { + + final var enclosingElement = element.getEnclosingElement(); + if (enclosingElement.getKind() == ElementKind.valueOf("RECORD")) { + Optional.of(Javadoc.parse(elements.getDocComment(enclosingElement))) + .map(d -> d.getParams().get(element.getSimpleName().toString())) + .ifPresent(propSchema::setDescription); + } + } catch (IllegalArgumentException e) { + // not on jdk 16+ } } @@ -322,7 +336,9 @@ private void gatherProperties(List fields, Element element) { } if (element instanceof TypeElement) { Element mappedSuper = types.asElement(((TypeElement) element).getSuperclass()); - if (mappedSuper != null && !"java.lang.Object".equals(mappedSuper.toString())) { + if (mappedSuper != null + && !"java.lang.Object".equals(mappedSuper.toString()) + && !"java.lang.Record".equals(mappedSuper.toString())) { gatherProperties(fields, mappedSuper); } for (VariableElement field : ElementFilter.fieldsIn(element.getEnclosedElements())) { diff --git a/tests/test-nima-jsonb/src/main/java/org/example/Person.java b/tests/test-nima-jsonb/src/main/java/org/example/Person.java index 3f0b73270..19c6bf60a 100644 --- a/tests/test-nima-jsonb/src/main/java/org/example/Person.java +++ b/tests/test-nima-jsonb/src/main/java/org/example/Person.java @@ -2,7 +2,9 @@ import io.avaje.jsonb.Json; +/** + * @param id the id + * @param name the name + */ @Json -public record Person(long id, String name) { - -} +public record Person(long id, String name) {} From 982819fdf8c34baf8cc8b85cac03aa589d207937 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Apr 2024 19:43:38 +0000 Subject: [PATCH 1054/1323] Bump nima.version from 4.0.6 to 4.0.7 Bumps `nima.version` from 4.0.6 to 4.0.7. Updates `io.helidon.webserver:helidon-webserver` from 4.0.6 to 4.0.7 Updates `io.helidon.http.media:helidon-http-media-jsonb` from 4.0.6 to 4.0.7 --- updated-dependencies: - dependency-name: io.helidon.webserver:helidon-webserver dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: io.helidon.http.media:helidon-http-media-jsonb dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- tests/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/pom.xml b/tests/pom.xml index 5b474e8b9..3b15015a1 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -17,7 +17,7 @@ 2.17.0 2.5 9.11 - 4.0.6 + 4.0.7 6.1.3 From a085c08edf4db302737b376c674435e705ae6445 Mon Sep 17 00:00:00 2001 From: "robin.bygrave" Date: Tue, 9 Apr 2024 14:51:03 +1200 Subject: [PATCH 1055/1323] Support Byte-Buddy / Mockito with JDK 23 via -Dnet.bytebuddy.experimental=true --- http-client-gson-adapter/pom.xml | 9 --------- http-client/pom.xml | 20 +++++++++++++------- pom.xml | 12 ++++++++++++ 3 files changed, 25 insertions(+), 16 deletions(-) diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index 191f47e8a..c45680c03 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -24,15 +24,6 @@ provided - - - - io.avaje - junit - 1.4 - test - - diff --git a/http-client/pom.xml b/http-client/pom.xml index bdfc43fbb..6dfd31353 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -56,13 +56,6 @@ test - - io.avaje - junit - 1.4 - test - - io.javalin javalin @@ -93,6 +86,19 @@ + + org.apache.maven.plugins + maven-failsafe-plugin + 3.2.5 + + + org.apache.maven.plugins + maven-surefire-plugin + 3.2.5 + + -XX:+EnableDynamicAgentLoading -Dnet.bytebuddy.experimental=true + + org.apache.maven.plugins maven-compiler-plugin diff --git a/pom.xml b/pom.xml index 2a26dcbe6..28e360790 100644 --- a/pom.xml +++ b/pom.xml @@ -26,6 +26,18 @@ + + net.bytebuddy + byte-buddy + 1.14.13 + test + + + net.bytebuddy + byte-buddy-agent + 1.14.13 + test + io.avaje junit From 58c3091dd6c4ba18a4fcd8fe41e95ee81cd7c04d Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Mon, 8 Apr 2024 23:47:22 -0400 Subject: [PATCH 1056/1323] Dependabot Grouping (#415) --- .github/dependabot.yml | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 6da8cf94c..0852ee27e 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -3,5 +3,21 @@ updates: - package-ecosystem: maven directory: "/" schedule: - interval: "daily" + interval: "weekly" open-pull-requests-limit: 10 + groups: + dev-deps: + dependency-type: "development" + prod-deps: + dependency-type: "production" + +- package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" + open-pull-requests-limit: 5 + commit-message: + prefix: "[workflow]" + labels: + - "dependencies" + target-branch: "master" From 94ba54ebc3a94ec126e929142f8cfa3af10f756b Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 9 Apr 2024 22:58:14 +1200 Subject: [PATCH 1057/1323] Version 2.3 --- http-api-javalin/pom.xml | 2 +- http-api/pom.xml | 2 +- http-client-gson-adapter/pom.xml | 4 ++-- http-client/pom.xml | 4 ++-- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 2 +- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-inject-plugin/pom.xml | 2 +- pom.xml | 2 +- tests/pom.xml | 2 +- tests/test-client-generation/pom.xml | 2 +- tests/test-client/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- 19 files changed, 21 insertions(+), 21 deletions(-) diff --git a/http-api-javalin/pom.xml b/http-api-javalin/pom.xml index afa876497..f08d57f93 100644 --- a/http-api-javalin/pom.xml +++ b/http-api-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.3-RC2 + 2.3 .. diff --git a/http-api/pom.xml b/http-api/pom.xml index 796953b08..7817e8794 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.3-RC2 + 2.3 .. diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index c45680c03..817ba847a 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.3-RC2 + 2.3 avaje-http-client-gson @@ -20,7 +20,7 @@ io.avaje avaje-http-client - 2.3-RC2 + 2.3 provided diff --git a/http-client/pom.xml b/http-client/pom.xml index 6dfd31353..b971aea1a 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.3-RC2 + 2.3 avaje-http-client @@ -66,7 +66,7 @@ io.avaje avaje-http-api - 2.3-RC2 + 2.3 diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index 146b08cf4..4bd568b06 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.3-RC2 + 2.3 avaje-http-client-generator diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index e34af456a..58b050565 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.3-RC2 + 2.3 avaje-http-generator-core diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index de1347cc5..522678732 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.3-RC2 + 2.3 avaje-http-helidon-generator diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index eb3343594..6d6239da0 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.3-RC2 + 2.3 avaje-http-javalin-generator diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index 7d9e2dd62..bb1a1bea1 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.3-RC2 + 2.3 avaje-http-jex-generator diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index e191c46eb..64cd73ced 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.3-RC2 + 2.3 .. diff --git a/pom.xml b/pom.xml index 28e360790..6ee6f892e 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-parent - 2.3-RC2 + 2.3 pom diff --git a/tests/pom.xml b/tests/pom.xml index 3b15015a1..2212e5dbb 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.3-RC2 + 2.3 tests diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index 3b8573a74..7a85b78c9 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.3-RC2 + 2.3 test-client-generation diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index 0ee97e666..3736ac7bc 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.3-RC2 + 2.3 test-client diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 513404162..d1a776b29 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 2.3-RC2 + 2.3 test-javalin-jsonb diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 7496e44e7..a31c78b26 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.3-RC2 + 2.3 test-javalin diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 6b9983345..36c6356d2 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.3-RC2 + 2.3 test-jex diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 33682c8ea..c1717af13 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.3-RC2 + 2.3 test-nima-jsonb diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index 123dc0123..12772a5a0 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.3-RC2 + 2.3 test-nima From ed65106d7db7cdc2737f7cc7163dd291b8ad891c Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 9 Apr 2024 22:58:58 +1200 Subject: [PATCH 1058/1323] Bump to next snapshot --- http-api-javalin/pom.xml | 2 +- http-api/pom.xml | 2 +- http-client-gson-adapter/pom.xml | 4 ++-- http-client/pom.xml | 4 ++-- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 2 +- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-inject-plugin/pom.xml | 2 +- pom.xml | 2 +- tests/pom.xml | 2 +- tests/test-client-generation/pom.xml | 2 +- tests/test-client/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- 19 files changed, 21 insertions(+), 21 deletions(-) diff --git a/http-api-javalin/pom.xml b/http-api-javalin/pom.xml index f08d57f93..24372c536 100644 --- a/http-api-javalin/pom.xml +++ b/http-api-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.3 + 2.4-SNAPSHOT .. diff --git a/http-api/pom.xml b/http-api/pom.xml index 7817e8794..db75655b6 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.3 + 2.4-SNAPSHOT .. diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index 817ba847a..d7a35538e 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.3 + 2.4-SNAPSHOT avaje-http-client-gson @@ -20,7 +20,7 @@ io.avaje avaje-http-client - 2.3 + 2.4-SNAPSHOT provided diff --git a/http-client/pom.xml b/http-client/pom.xml index b971aea1a..f635e8836 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.3 + 2.4-SNAPSHOT avaje-http-client @@ -66,7 +66,7 @@ io.avaje avaje-http-api - 2.3 + 2.4-SNAPSHOT diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index 4bd568b06..27a711e0e 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.3 + 2.4-SNAPSHOT avaje-http-client-generator diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 58b050565..78a39774e 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.3 + 2.4-SNAPSHOT avaje-http-generator-core diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index 522678732..8a4d0b7b8 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.3 + 2.4-SNAPSHOT avaje-http-helidon-generator diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index 6d6239da0..171d78cc7 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.3 + 2.4-SNAPSHOT avaje-http-javalin-generator diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index bb1a1bea1..b651e510c 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.3 + 2.4-SNAPSHOT avaje-http-jex-generator diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index 64cd73ced..dc6dc3b50 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.3 + 2.4-SNAPSHOT .. diff --git a/pom.xml b/pom.xml index 6ee6f892e..95e57e43c 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-parent - 2.3 + 2.4-SNAPSHOT pom diff --git a/tests/pom.xml b/tests/pom.xml index 2212e5dbb..ae893d59a 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.3 + 2.4-SNAPSHOT tests diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index 7a85b78c9..b5919ae08 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.3 + 2.4-SNAPSHOT test-client-generation diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index 3736ac7bc..5cdd0b774 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.3 + 2.4-SNAPSHOT test-client diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index d1a776b29..cbb5b8ca4 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 2.3 + 2.4-SNAPSHOT test-javalin-jsonb diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index a31c78b26..c66f38e51 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.3 + 2.4-SNAPSHOT test-javalin diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 36c6356d2..2b0b1ee35 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.3 + 2.4-SNAPSHOT test-jex diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index c1717af13..5f3a44fdb 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.3 + 2.4-SNAPSHOT test-nima-jsonb diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index 12772a5a0..1d14685c3 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.3 + 2.4-SNAPSHOT test-nima From 7aa900f284f010fd3873970be34e9de95f777f54 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Tue, 9 Apr 2024 08:06:46 -0400 Subject: [PATCH 1059/1323] Support the Avaje Build Plugin (#397) * Update ProcessingContext.java * Update ProcessingContext.java * Use resourceExists * Use resourceExists --------- Co-authored-by: Rob Bygrave --- .../generator/core/ProcessingContext.java | 64 +++++++++++-------- 1 file changed, 38 insertions(+), 26 deletions(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java index ea81a0ccd..f99a34b16 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java @@ -4,6 +4,7 @@ import java.io.IOException; import java.io.InputStreamReader; import java.net.URI; +import java.nio.file.Paths; import java.util.Collection; import java.util.List; import java.util.Objects; @@ -32,7 +33,7 @@ import io.avaje.http.generator.core.openapi.DocContext; -public class ProcessingContext { +public final class ProcessingContext { private static final ThreadLocal CTX = new ThreadLocal<>(); @@ -202,7 +203,7 @@ public static boolean instrumentAllWebMethods() { public static boolean useJsonb() { try { return CTX.get().elementUtils.getTypeElement("io.avaje.jsonb.Jsonb") != null - || Class.forName("io.avaje.jsonb.Jsonb") != null; + || Class.forName("io.avaje.jsonb.Jsonb") != null; } catch (final ClassNotFoundException e) { return false; } @@ -253,33 +254,24 @@ public static void validateModule(String fqn) { if (module != null && !CTX.get().validated && !module.isUnnamed()) { CTX.get().validated = true; - try (var inputStream = - CTX.get() - .filer - .getResource(StandardLocation.SOURCE_PATH, "", "module-info.java") - .toUri() - .toURL() - .openStream(); + CTX.get() + .filer + .getResource(StandardLocation.SOURCE_PATH, "", "module-info.java") + .toUri() + .toURL() + .openStream(); var reader = new BufferedReader(new InputStreamReader(inputStream))) { - var noProvides = - reader - .lines() - .map( - s -> { - if (s.contains("io.avaje.http.api.javalin") && !s.contains("static")) { - logWarn( - "io.avaje.http.api.javalin only contains SOURCE retention annotations. It should added as `requires static`"); - } - return s; - }) - .noneMatch(s -> s.contains(fqn)); - if (noProvides) { - logError( - module, - "Missing `provides io.avaje.http.client.HttpClient.GeneratedComponent with %s;`", - fqn); + var noProvides = reader.lines().map(s -> { + if (s.contains("io.avaje.http.api.javalin") && !s.contains("static")) { + logWarn("io.avaje.http.api.javalin only contains SOURCE retention annotations. It should added as `requires static`"); + } + return s; + }) + .noneMatch(s -> s.contains(fqn)); + if (noProvides && !buildPluginAvailable()) { + logError(module, "Missing `provides io.avaje.http.client.HttpClient.GeneratedComponent with %s;`", fqn); } } catch (Exception e) { // can't read module @@ -297,4 +289,24 @@ static ModuleElement getModuleElement(Element e) { static Elements elements() { return CTX.get().elementUtils; } + + private static boolean buildPluginAvailable() { + return resourceExists("target/avaje-plugin-exists.txt") + || resourceExists("build/avaje-plugin-exists.txt"); + } + + private static boolean resourceExists(String relativeName) { + try { + final String resource = + filer() + .getResource(StandardLocation.CLASS_OUTPUT, "", relativeName) + .toUri() + .toString() + .replaceFirst("/target/classes", "") + .replaceFirst("/build/classes/java/main", ""); + return Paths.get(new URI(resource)).toFile().exists(); + } catch (final Exception e) { + return false; + } + } } From ac79eaf5dbb4f7aa65c9e61d520f520caaa16631 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Wed, 10 Apr 2024 00:15:56 +1200 Subject: [PATCH 1060/1323] Bump parent pom and avaje junit --- http-api/pom.xml | 1 - http-client/pom.xml | 13 ------------- http-generator-client/pom.xml | 4 ++-- http-inject-plugin/pom.xml | 1 - pom.xml | 16 ++-------------- tests/test-client/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 8 +------- 10 files changed, 9 insertions(+), 42 deletions(-) diff --git a/http-api/pom.xml b/http-api/pom.xml index db75655b6..a71570bf2 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -36,7 +36,6 @@ org.apache.maven.plugins maven-surefire-plugin - 3.0.0 0 diff --git a/http-client/pom.xml b/http-client/pom.xml index f635e8836..d423a6620 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -86,19 +86,6 @@ - - org.apache.maven.plugins - maven-failsafe-plugin - 3.2.5 - - - org.apache.maven.plugins - maven-surefire-plugin - 3.2.5 - - -XX:+EnableDynamicAgentLoading -Dnet.bytebuddy.experimental=true - - org.apache.maven.plugins maven-compiler-plugin diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index 27a711e0e..cf7ea03c8 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -10,8 +10,9 @@ avaje-http-client-generator - 11 + 11 + io.avaje @@ -48,7 +49,6 @@ org.apache.maven.plugins maven-surefire-plugin - ${maven-surefire-plugin.version} false diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index dc6dc3b50..f4ae6f45d 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -37,7 +37,6 @@ org.apache.maven.plugins maven-surefire-plugin - 3.0.0 0 diff --git a/pom.xml b/pom.xml index 95e57e43c..3cd1d1c77 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ org.avaje java11-oss - 4.0 + 4.1 io.avaje @@ -26,22 +26,10 @@ - - net.bytebuddy - byte-buddy - 1.14.13 - test - - - net.bytebuddy - byte-buddy-agent - 1.14.13 - test - io.avaje junit - 1.4 + 1.5 test diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index 5cdd0b774..3cd46a82b 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -44,7 +44,7 @@ io.avaje junit - 1.4 + 1.5 test diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index cbb5b8ca4..04bfd0f6d 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -94,7 +94,7 @@ io.avaje junit - 1.4 + 1.5 test diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index c66f38e51..7577433b3 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -87,7 +87,7 @@ io.avaje junit - 1.4 + 1.5 test diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 2b0b1ee35..b0c6054e5 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -87,7 +87,7 @@ io.avaje junit - 1.4 + 1.5 test diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 5f3a44fdb..4a86d6e0d 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -17,7 +17,6 @@ false - io.avaje @@ -58,7 +57,7 @@ io.avaje junit - 1.4 + 1.5 test @@ -96,11 +95,6 @@ - - org.apache.maven.plugins - maven-surefire-plugin - 3.0.0 - io.repaint.maven tiles-maven-plugin From 85e4877bc4dca8a2ec68e0bce33686c89cd8f4a5 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Wed, 10 Apr 2024 00:24:35 +1200 Subject: [PATCH 1061/1323] Version 2.4 --- http-api-javalin/pom.xml | 2 +- http-api/pom.xml | 2 +- http-client-gson-adapter/pom.xml | 4 ++-- http-client/pom.xml | 4 ++-- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 2 +- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-inject-plugin/pom.xml | 2 +- pom.xml | 2 +- tests/pom.xml | 2 +- tests/test-client-generation/pom.xml | 2 +- tests/test-client/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- 18 files changed, 20 insertions(+), 20 deletions(-) diff --git a/http-api-javalin/pom.xml b/http-api-javalin/pom.xml index 24372c536..5df431fef 100644 --- a/http-api-javalin/pom.xml +++ b/http-api-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.4-SNAPSHOT + 2.4 .. diff --git a/http-api/pom.xml b/http-api/pom.xml index a71570bf2..911934358 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.4-SNAPSHOT + 2.4 .. diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index d7a35538e..99058445a 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.4-SNAPSHOT + 2.4 avaje-http-client-gson @@ -20,7 +20,7 @@ io.avaje avaje-http-client - 2.4-SNAPSHOT + 2.4 provided diff --git a/http-client/pom.xml b/http-client/pom.xml index d423a6620..0575a088a 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.4-SNAPSHOT + 2.4 avaje-http-client @@ -66,7 +66,7 @@ io.avaje avaje-http-api - 2.4-SNAPSHOT + 2.4 diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index cf7ea03c8..a03b4f3f0 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.4-SNAPSHOT + 2.4 avaje-http-client-generator diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 78a39774e..ecbffb4ce 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.4-SNAPSHOT + 2.4 avaje-http-generator-core diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index 8a4d0b7b8..38426cf54 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.4-SNAPSHOT + 2.4 avaje-http-helidon-generator diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index 171d78cc7..b1dfaa379 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.4-SNAPSHOT + 2.4 avaje-http-javalin-generator diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index b651e510c..faba46f1b 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.4-SNAPSHOT + 2.4 avaje-http-jex-generator diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index f4ae6f45d..b7b8a7218 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.4-SNAPSHOT + 2.4 .. diff --git a/pom.xml b/pom.xml index 3cd1d1c77..d1dbfa443 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-parent - 2.4-SNAPSHOT + 2.4 pom diff --git a/tests/pom.xml b/tests/pom.xml index ae893d59a..c5e35977c 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.4-SNAPSHOT + 2.4 tests diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index b5919ae08..c1b8ed195 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.4-SNAPSHOT + 2.4 test-client-generation diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index 3cd46a82b..fe83652d7 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.4-SNAPSHOT + 2.4 test-client diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 04bfd0f6d..82d05a1bd 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 2.4-SNAPSHOT + 2.4 test-javalin-jsonb diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 7577433b3..283306a75 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.4-SNAPSHOT + 2.4 test-javalin diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index b0c6054e5..5f3ff1c7e 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.4-SNAPSHOT + 2.4 test-jex diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index 1d14685c3..9c9335b15 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.4-SNAPSHOT + 2.4 test-nima From bda445e934a06bf4f0d7291373c0d2b547cd0cde Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Wed, 10 Apr 2024 00:25:04 +1200 Subject: [PATCH 1062/1323] Bump to next snapshot --- http-api-javalin/pom.xml | 2 +- http-api/pom.xml | 2 +- http-client-gson-adapter/pom.xml | 4 ++-- http-client/pom.xml | 4 ++-- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 2 +- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-inject-plugin/pom.xml | 2 +- pom.xml | 2 +- tests/pom.xml | 2 +- tests/test-client-generation/pom.xml | 2 +- tests/test-client/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- 19 files changed, 21 insertions(+), 21 deletions(-) diff --git a/http-api-javalin/pom.xml b/http-api-javalin/pom.xml index 5df431fef..b9bebbf26 100644 --- a/http-api-javalin/pom.xml +++ b/http-api-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.4 + 2.5-SNAPSHOT .. diff --git a/http-api/pom.xml b/http-api/pom.xml index 911934358..126998d02 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.4 + 2.5-SNAPSHOT .. diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index 99058445a..a2b39bcd6 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.4 + 2.5-SNAPSHOT avaje-http-client-gson @@ -20,7 +20,7 @@ io.avaje avaje-http-client - 2.4 + 2.5-SNAPSHOT provided diff --git a/http-client/pom.xml b/http-client/pom.xml index 0575a088a..89ab82dda 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.4 + 2.5-SNAPSHOT avaje-http-client @@ -66,7 +66,7 @@ io.avaje avaje-http-api - 2.4 + 2.5-SNAPSHOT diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index a03b4f3f0..0501361fd 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.4 + 2.5-SNAPSHOT avaje-http-client-generator diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index ecbffb4ce..132422803 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.4 + 2.5-SNAPSHOT avaje-http-generator-core diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index 38426cf54..f40240138 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.4 + 2.5-SNAPSHOT avaje-http-helidon-generator diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index b1dfaa379..d5ba95269 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.4 + 2.5-SNAPSHOT avaje-http-javalin-generator diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index faba46f1b..58d0f0da1 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.4 + 2.5-SNAPSHOT avaje-http-jex-generator diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index b7b8a7218..bc7ea3528 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.4 + 2.5-SNAPSHOT .. diff --git a/pom.xml b/pom.xml index d1dbfa443..93d149d0f 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-parent - 2.4 + 2.5-SNAPSHOT pom diff --git a/tests/pom.xml b/tests/pom.xml index c5e35977c..5100daf1e 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.4 + 2.5-SNAPSHOT tests diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index c1b8ed195..4db55d91b 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.4 + 2.5-SNAPSHOT test-client-generation diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index fe83652d7..716310082 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.4 + 2.5-SNAPSHOT test-client diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 82d05a1bd..518f99963 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 2.4 + 2.5-SNAPSHOT test-javalin-jsonb diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 283306a75..822e06813 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.4 + 2.5-SNAPSHOT test-javalin diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 5f3ff1c7e..c5036eeb6 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.4 + 2.5-SNAPSHOT test-jex diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 4a86d6e0d..eb7f440e4 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.4-SNAPSHOT + 2.5-SNAPSHOT test-nima-jsonb diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index 9c9335b15..4fead22fc 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.4 + 2.5-SNAPSHOT test-nima From 4c92329ea7d820a1aa630f961c6a1853a689b7f7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 9 Apr 2024 19:56:40 +0000 Subject: [PATCH 1063/1323] Bump io.avaje:avaje-jsonb-generator from 1.10 to 1.11 Bumps io.avaje:avaje-jsonb-generator from 1.10 to 1.11. --- updated-dependencies: - dependency-name: io.avaje:avaje-jsonb-generator dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 518f99963..9a96f4a23 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -86,7 +86,7 @@ io.avaje avaje-jsonb-generator - 1.10 + 1.11 provided diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index eb7f440e4..a9056aede 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -90,7 +90,7 @@ io.avaje avaje-jsonb-generator - 1.10 + 1.11 From f2bdf4fcf18a06adb93366163bb6d2e026cab8f5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 9 Apr 2024 19:56:58 +0000 Subject: [PATCH 1064/1323] Bump io.avaje:avaje-jsonb from 1.10 to 1.11 Bumps [io.avaje:avaje-jsonb](https://github.com/avaje/avaje-jsonb) from 1.10 to 1.11. - [Release notes](https://github.com/avaje/avaje-jsonb/releases) - [Commits](https://github.com/avaje/avaje-jsonb/compare/1.10...1.11) --- updated-dependencies: - dependency-name: io.avaje:avaje-jsonb dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- http-client/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/http-client/pom.xml b/http-client/pom.xml index 89ab82dda..046acdea2 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -36,7 +36,7 @@ io.avaje avaje-jsonb - 1.10 + 1.11 true diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 518f99963..f76460ed4 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -80,7 +80,7 @@ io.avaje avaje-jsonb - 1.10 + 1.11 diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index eb7f440e4..8009345be 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -31,7 +31,7 @@ io.avaje avaje-jsonb - 1.10 + 1.11 io.avaje From f64f22e0373fe9d17e3d1dcb44acf2bf72d58215 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Tue, 9 Apr 2024 15:57:45 -0400 Subject: [PATCH 1065/1323] Update dependabot.yml --- .github/dependabot.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 0852ee27e..c48f697b9 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -5,6 +5,8 @@ updates: schedule: interval: "weekly" open-pull-requests-limit: 10 + ignore: + - dependency-name: "jakarta.inject:jakarta.inject-api" groups: dev-deps: dependency-type: "development" From 2a1969b72cf427415437817d741f8c68afd8a576 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Tue, 9 Apr 2024 15:58:30 -0400 Subject: [PATCH 1066/1323] Update dependabot.yml --- .github/dependabot.yml | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index c48f697b9..de2383d88 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,19 +1,16 @@ version: 2 updates: -- package-ecosystem: maven - directory: "/" - schedule: - interval: "weekly" - open-pull-requests-limit: 10 - ignore: - - dependency-name: "jakarta.inject:jakarta.inject-api" - groups: - dev-deps: - dependency-type: "development" - prod-deps: - dependency-type: "production" + - package-ecosystem: "maven" + directory: "/" + schedule: + interval: "weekly" + open-pull-requests-limit: 10 + labels: + - "dependencies" + target-branch: "master" + -- package-ecosystem: "github-actions" + - package-ecosystem: "github-actions" directory: "/" schedule: interval: "weekly" From 38d0340587d360210aa3d70e4be6322bc0f35baf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 9 Apr 2024 19:58:31 +0000 Subject: [PATCH 1067/1323] Bump avaje-inject.version from 9.11 to 9.12 Bumps `avaje-inject.version` from 9.11 to 9.12. Updates `io.avaje:avaje-inject` from 9.11 to 9.12 - [Release notes](https://github.com/avaje/avaje-inject/releases) - [Commits](https://github.com/avaje/avaje-inject/compare/9.11...9.12) Updates `io.avaje:avaje-inject-generator` from 9.11 to 9.12 --- updated-dependencies: - dependency-name: io.avaje:avaje-inject dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: io.avaje:avaje-inject-generator dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- http-client/pom.xml | 4 ++-- http-inject-plugin/pom.xml | 2 +- tests/pom.xml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/http-client/pom.xml b/http-client/pom.xml index 89ab82dda..294ae4a9c 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -43,7 +43,7 @@ io.avaje avaje-inject - 9.11 + 9.12 true @@ -98,7 +98,7 @@ io.avaje avaje-inject-generator - 9.11 + 9.12
    diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index bc7ea3528..88d81da1f 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -19,7 +19,7 @@ io.avaje avaje-inject - 9.11 + 9.12 provided true diff --git a/tests/pom.xml b/tests/pom.xml index 5100daf1e..3ca49279b 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -16,7 +16,7 @@ 3.25.3 2.17.0 2.5 - 9.11 + 9.12 4.0.7 6.1.3 From 90c4cc24670d7add934963f26c3f8ef253d797a2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 9 Apr 2024 20:01:58 +0000 Subject: [PATCH 1068/1323] [workflow]: Bump actions/checkout from 3 to 4 Bumps [actions/checkout](https://github.com/actions/checkout) from 3 to 4. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v3...v4) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/build.yml | 2 +- .github/workflows/jdk-ea.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 5cc2e69cd..f873b2cf7 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -14,7 +14,7 @@ jobs: os: [ubuntu-latest] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Java uses: actions/setup-java@v3 with: diff --git a/.github/workflows/jdk-ea.yml b/.github/workflows/jdk-ea.yml index 136a846cb..d62757e13 100644 --- a/.github/workflows/jdk-ea.yml +++ b/.github/workflows/jdk-ea.yml @@ -20,7 +20,7 @@ jobs: os: [ubuntu-latest] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Java uses: oracle-actions/setup-java@v1 with: From 60c8cafcff063ab4a18932b1b6401bd3dc811ef8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 9 Apr 2024 20:03:53 +0000 Subject: [PATCH 1069/1323] [workflow]: Bump actions/cache from 3 to 4 Bumps [actions/cache](https://github.com/actions/cache) from 3 to 4. - [Release notes](https://github.com/actions/cache/releases) - [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md) - [Commits](https://github.com/actions/cache/compare/v3...v4) --- updated-dependencies: - dependency-name: actions/cache dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/build.yml | 2 +- .github/workflows/jdk-ea.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f873b2cf7..003c1c651 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -21,7 +21,7 @@ jobs: java-version: ${{ matrix.java_version }} distribution: "zulu" - name: Maven cache - uses: actions/cache@v3 + uses: actions/cache@v4 env: cache-name: maven-cache with: diff --git a/.github/workflows/jdk-ea.yml b/.github/workflows/jdk-ea.yml index d62757e13..6dec68f0c 100644 --- a/.github/workflows/jdk-ea.yml +++ b/.github/workflows/jdk-ea.yml @@ -27,7 +27,7 @@ jobs: website: jdk.java.net release: ${{ matrix.java_version }} - name: Maven cache - uses: actions/cache@v3 + uses: actions/cache@v4 env: cache-name: maven-cache with: From cb96d7d5328219b5ade1b8833a28867284cf1507 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 9 Apr 2024 20:05:30 +0000 Subject: [PATCH 1070/1323] [workflow]: Bump dependabot/fetch-metadata from 1 to 2 Bumps [dependabot/fetch-metadata](https://github.com/dependabot/fetch-metadata) from 1 to 2. - [Release notes](https://github.com/dependabot/fetch-metadata/releases) - [Commits](https://github.com/dependabot/fetch-metadata/compare/v1...v2) --- updated-dependencies: - dependency-name: dependabot/fetch-metadata dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/dependabot-merge.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dependabot-merge.yml b/.github/workflows/dependabot-merge.yml index 0328be627..4ad1f85dd 100644 --- a/.github/workflows/dependabot-merge.yml +++ b/.github/workflows/dependabot-merge.yml @@ -12,7 +12,7 @@ jobs: steps: - name: Dependabot metadata id: metadata - uses: dependabot/fetch-metadata@v1 + uses: dependabot/fetch-metadata@v2 with: github-token: "${{ secrets.GITHUB_TOKEN }}" - name: Approve a PR From 373e1f0f4a3425a8e4beb5b9b9d62967422f393a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 9 Apr 2024 20:07:35 +0000 Subject: [PATCH 1071/1323] [workflow]: Bump actions/setup-java from 3 to 4 Bumps [actions/setup-java](https://github.com/actions/setup-java) from 3 to 4. - [Release notes](https://github.com/actions/setup-java/releases) - [Commits](https://github.com/actions/setup-java/compare/v3...v4) --- updated-dependencies: - dependency-name: actions/setup-java dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 003c1c651..dbe4de9c7 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -16,7 +16,7 @@ jobs: steps: - uses: actions/checkout@v4 - name: Set up Java - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: java-version: ${{ matrix.java_version }} distribution: "zulu" From 7ebbc5bfb1208eec6583a2d5045973afaceea727 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sun, 21 Apr 2024 16:49:00 -0400 Subject: [PATCH 1072/1323] [http-client] Adds Moshi Body Adapter (#424) * adds moshi adapter * Move moshi module to be consistent with gson module * Use UncheckedIOException and format --------- Co-authored-by: Rob Bygrave --- .../src/main/java/module-info.java | 4 +- http-client-moshi-adapter/pom.xml | 37 +++++ .../http/client/moshi/MoshiBodyAdapter.java | 139 ++++++++++++++++++ .../src/main/java/module-info.java | 7 + .../java/io/avaje/http/client/moshi/Foo.java | 9 ++ .../client/moshi/MoshiBodyAdapterTest.java | 58 ++++++++ pom.xml | 1 + 7 files changed, 253 insertions(+), 2 deletions(-) create mode 100644 http-client-moshi-adapter/pom.xml create mode 100644 http-client-moshi-adapter/src/main/java/io/avaje/http/client/moshi/MoshiBodyAdapter.java create mode 100644 http-client-moshi-adapter/src/main/java/module-info.java create mode 100644 http-client-moshi-adapter/src/test/java/io/avaje/http/client/moshi/Foo.java create mode 100644 http-client-moshi-adapter/src/test/java/io/avaje/http/client/moshi/MoshiBodyAdapterTest.java diff --git a/http-client-gson-adapter/src/main/java/module-info.java b/http-client-gson-adapter/src/main/java/module-info.java index 9933af689..0a9b1f4e4 100644 --- a/http-client-gson-adapter/src/main/java/module-info.java +++ b/http-client-gson-adapter/src/main/java/module-info.java @@ -2,6 +2,6 @@ exports io.avaje.http.client.gson; - requires io.avaje.http.client; - requires com.google.gson; + requires transitive io.avaje.http.client; + requires transitive com.google.gson; } diff --git a/http-client-moshi-adapter/pom.xml b/http-client-moshi-adapter/pom.xml new file mode 100644 index 000000000..152e5dcae --- /dev/null +++ b/http-client-moshi-adapter/pom.xml @@ -0,0 +1,37 @@ + + 4.0.0 + + io.avaje + avaje-http-parent + 2.4 + + avaje-http-client-moshi + + + + + com.squareup.moshi + moshi + 1.15.1 + true + + + + io.avaje + avaje-http-client + ${project.version} + provided + + + + + + io.avaje + junit + 1.4 + test + + + + + \ No newline at end of file diff --git a/http-client-moshi-adapter/src/main/java/io/avaje/http/client/moshi/MoshiBodyAdapter.java b/http-client-moshi-adapter/src/main/java/io/avaje/http/client/moshi/MoshiBodyAdapter.java new file mode 100644 index 000000000..80e754bc5 --- /dev/null +++ b/http-client-moshi-adapter/src/main/java/io/avaje/http/client/moshi/MoshiBodyAdapter.java @@ -0,0 +1,139 @@ +package io.avaje.http.client.moshi; + +import java.io.IOException; +import java.io.UncheckedIOException; +import java.lang.reflect.Type; +import java.util.List; +import java.util.concurrent.ConcurrentHashMap; + +import com.squareup.moshi.JsonAdapter; +import com.squareup.moshi.Moshi; +import com.squareup.moshi.Types; + +import io.avaje.http.client.BodyAdapter; +import io.avaje.http.client.BodyContent; +import io.avaje.http.client.BodyReader; +import io.avaje.http.client.BodyWriter; + +/** + * Moshi BodyAdapter to read and write beans as JSON. + * + *
    {@code
    + * HttpClient.builder()
    + *     .baseUrl(baseUrl)
    + *     .bodyAdapter(new MoshiBodyAdapter())
    + *     .build();
    + *
    + * }
    + */ +public final class MoshiBodyAdapter implements BodyAdapter { + + private final Moshi moshi; + private final ConcurrentHashMap> beanWriterCache = new ConcurrentHashMap<>(); + private final ConcurrentHashMap> beanReaderCache = new ConcurrentHashMap<>(); + private final ConcurrentHashMap> listReaderCache = new ConcurrentHashMap<>(); + + /** + * Create passing the Moshi to use. + */ + public MoshiBodyAdapter(Moshi moshi) { + this.moshi = moshi; + } + + /** + * Create with a default Moshi that allows unknown properties. + */ + public MoshiBodyAdapter() { + this(new Moshi.Builder().build()); + } + + @SuppressWarnings("unchecked") + @Override + public BodyWriter beanWriter(Class cls) { + return (BodyWriter) beanWriterCache.computeIfAbsent(cls, aClass -> new JWriter<>(moshi.adapter(cls))); + } + + @SuppressWarnings("unchecked") + @Override + public BodyWriter beanWriter(Type type) { + return (BodyWriter) beanWriterCache.computeIfAbsent(type, aClass -> new JWriter<>(moshi.adapter(type))); + } + + @SuppressWarnings("unchecked") + @Override + public BodyReader beanReader(Class cls) { + return (BodyReader) beanReaderCache.computeIfAbsent(cls, aClass -> new JReader<>(moshi.adapter(cls))); + } + + @SuppressWarnings("unchecked") + @Override + public BodyReader beanReader(Type type) { + return (BodyReader) beanReaderCache.computeIfAbsent(type, aClass -> new JReader<>(moshi.adapter(type))); + } + + @SuppressWarnings("unchecked") + @Override + public BodyReader> listReader(Type type) { + return (BodyReader>) + listReaderCache.computeIfAbsent( + type, + aClass -> new JReader<>(moshi.adapter(Types.newParameterizedType(List.class, type)))); + } + + @SuppressWarnings("unchecked") + @Override + public BodyReader> listReader(Class cls) { + return (BodyReader>) + listReaderCache.computeIfAbsent( + cls, + aClass -> new JReader<>(moshi.adapter(Types.newParameterizedType(List.class, cls)))); + } + + private static class JReader implements BodyReader { + + private final JsonAdapter reader; + + JReader(JsonAdapter reader) { + this.reader = reader; + } + + @Override + public T readBody(String content) { + try { + return reader.fromJson(content); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + @Override + public T read(BodyContent bodyContent) { + try { + return reader.fromJson(bodyContent.contentAsUtf8()); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + } + + private static class JWriter implements BodyWriter { + + private final JsonAdapter writer; + + public JWriter(JsonAdapter writer) { + this.writer = writer; + } + + @Override + public BodyContent write(T bean, String contentType) { + // ignoring the requested contentType and always + // writing the body as json content + return write(bean); + } + + @Override + public BodyContent write(T bean) { + return BodyContent.of(writer.toJson(bean)); + } + } +} diff --git a/http-client-moshi-adapter/src/main/java/module-info.java b/http-client-moshi-adapter/src/main/java/module-info.java new file mode 100644 index 000000000..4c68c474e --- /dev/null +++ b/http-client-moshi-adapter/src/main/java/module-info.java @@ -0,0 +1,7 @@ +module io.avaje.http.client.gson { + + exports io.avaje.http.client.moshi; + + requires transitive io.avaje.http.client; + requires transitive com.squareup.moshi; +} diff --git a/http-client-moshi-adapter/src/test/java/io/avaje/http/client/moshi/Foo.java b/http-client-moshi-adapter/src/test/java/io/avaje/http/client/moshi/Foo.java new file mode 100644 index 000000000..ec78ac267 --- /dev/null +++ b/http-client-moshi-adapter/src/test/java/io/avaje/http/client/moshi/Foo.java @@ -0,0 +1,9 @@ +package io.avaje.http.client.moshi; + +public class Foo { + + public long id; + + public String name; + +} diff --git a/http-client-moshi-adapter/src/test/java/io/avaje/http/client/moshi/MoshiBodyAdapterTest.java b/http-client-moshi-adapter/src/test/java/io/avaje/http/client/moshi/MoshiBodyAdapterTest.java new file mode 100644 index 000000000..1dcc4649a --- /dev/null +++ b/http-client-moshi-adapter/src/test/java/io/avaje/http/client/moshi/MoshiBodyAdapterTest.java @@ -0,0 +1,58 @@ +package io.avaje.http.client.moshi; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.nio.charset.StandardCharsets; +import java.util.List; + +import org.junit.jupiter.api.Test; + +import io.avaje.http.client.BodyContent; +import io.avaje.http.client.BodyReader; +import io.avaje.http.client.BodyWriter; + +class MoshiBodyAdapterTest { + + private final MoshiBodyAdapter adapter = new MoshiBodyAdapter(); + + @Test + void beanWriter() { + + final Foo foo = new Foo(); + foo.id = 42; + foo.name = "bar"; + + final BodyWriter writer = adapter.beanWriter(Foo.class); + final BodyContent content = writer.write(foo); + + final String json = new String(content.content(), StandardCharsets.UTF_8); + assertEquals("{\"id\":42,\"name\":\"bar\"}", json); + } + + @Test + void beanReader() { + + final BodyReader reader = adapter.beanReader(Foo.class); + + final Foo read = reader.read(content("{\"id\":42, \"name\":\"bar\"}")); + assertEquals(42, read.id); + assertEquals("bar", read.name); + } + + @Test + void listReader() { + + final BodyReader> reader = adapter.listReader(Foo.class); + + final List read = + reader.read(content("[{\"id\":42, \"name\":\"bar\"},{\"id\":43, \"name\":\"baz\"}]")); + + assertEquals(2, read.size()); + assertEquals(42, read.get(0).id); + assertEquals(43, read.get(1).id); + } + + BodyContent content(String raw) { + return BodyContent.of(raw.getBytes()); + } +} diff --git a/pom.xml b/pom.xml index 93d149d0f..2f73594d7 100644 --- a/pom.xml +++ b/pom.xml @@ -39,6 +39,7 @@ http-api-javalin http-client http-client-gson-adapter + http-client-moshi-adapter http-inject-plugin http-generator-core http-generator-javalin From 2571b8d6943ada001b475a4af94f2328b45309db Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Mon, 22 Apr 2024 08:56:18 +1200 Subject: [PATCH 1073/1323] Version 2.4 avaje-http-client-moshi --- http-client-moshi-adapter/pom.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/http-client-moshi-adapter/pom.xml b/http-client-moshi-adapter/pom.xml index 152e5dcae..dceadf32f 100644 --- a/http-client-moshi-adapter/pom.xml +++ b/http-client-moshi-adapter/pom.xml @@ -6,9 +6,9 @@ 2.4 avaje-http-client-moshi - + - + com.squareup.moshi moshi @@ -19,7 +19,7 @@ io.avaje avaje-http-client - ${project.version} + 2.4 provided @@ -28,10 +28,10 @@ io.avaje junit - 1.4 + 1.5 test - \ No newline at end of file + From 98dbf567738703e05ce0db4f4db4ffd27aff6d3b Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Mon, 22 Apr 2024 08:57:37 +1200 Subject: [PATCH 1074/1323] Bump avaje-http-client-moshi to 2.5-SNAPSHOT --- http-client-moshi-adapter/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/http-client-moshi-adapter/pom.xml b/http-client-moshi-adapter/pom.xml index dceadf32f..a6fd9a4d3 100644 --- a/http-client-moshi-adapter/pom.xml +++ b/http-client-moshi-adapter/pom.xml @@ -3,7 +3,7 @@ io.avaje avaje-http-parent - 2.4 + 2.5-SNAPSHOT avaje-http-client-moshi @@ -19,7 +19,7 @@ io.avaje avaje-http-client - 2.4 + 2.5-SNAPSHOT provided From d058c43b094dcb6cfd3764d8da8d76684c3c2207 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 29 Apr 2024 19:03:54 +0000 Subject: [PATCH 1075/1323] Bump nima.version from 4.0.7 to 4.0.8 Bumps `nima.version` from 4.0.7 to 4.0.8. Updates `io.helidon.webserver:helidon-webserver` from 4.0.7 to 4.0.8 Updates `io.helidon.http.media:helidon-http-media-jsonb` from 4.0.7 to 4.0.8 --- updated-dependencies: - dependency-name: io.helidon.webserver:helidon-webserver dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: io.helidon.http.media:helidon-http-media-jsonb dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- tests/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/pom.xml b/tests/pom.xml index 3ca49279b..fb264ccdd 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -17,7 +17,7 @@ 2.17.0 2.5 9.12 - 4.0.7 + 4.0.8 6.1.3 From 33048982418db2eade59c8b03a2ab376868f134f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 May 2024 19:16:09 +0000 Subject: [PATCH 1076/1323] Bump com.fasterxml.jackson.core:jackson-databind from 2.17.0 to 2.17.1 Bumps [com.fasterxml.jackson.core:jackson-databind](https://github.com/FasterXML/jackson) from 2.17.0 to 2.17.1. - [Commits](https://github.com/FasterXML/jackson/commits) --- updated-dependencies: - dependency-name: com.fasterxml.jackson.core:jackson-databind dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- http-client/pom.xml | 2 +- tests/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/http-client/pom.xml b/http-client/pom.xml index 25ec7ea45..948e49421 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -29,7 +29,7 @@ com.fasterxml.jackson.core jackson-databind - 2.17.0 + 2.17.1 true diff --git a/tests/pom.xml b/tests/pom.xml index fb264ccdd..a7066b887 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -14,7 +14,7 @@ true 5.10.2 3.25.3 - 2.17.0 + 2.17.1 2.5 9.12 4.0.8 From 79ebe9b83358453dbe4916dc54cf53c2fcda37d5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 May 2024 19:18:09 +0000 Subject: [PATCH 1077/1323] Bump io.javalin:javalin from 6.1.3 to 6.1.4 Bumps [io.javalin:javalin](https://github.com/javalin/javalin) from 6.1.3 to 6.1.4. - [Release notes](https://github.com/javalin/javalin/releases) - [Commits](https://github.com/javalin/javalin/compare/javalin-parent-6.1.3...javalin-parent-6.1.4) --- updated-dependencies: - dependency-name: io.javalin:javalin dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- http-api/pom.xml | 2 +- http-client/pom.xml | 2 +- tests/pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/http-api/pom.xml b/http-api/pom.xml index 126998d02..10e778f72 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -24,7 +24,7 @@ io.javalin javalin - 6.1.3 + 6.1.4 provided true diff --git a/http-client/pom.xml b/http-client/pom.xml index 948e49421..f14345d06 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -59,7 +59,7 @@ io.javalin javalin - 6.1.3 + 6.1.4 test diff --git a/tests/pom.xml b/tests/pom.xml index a7066b887..0c2367fce 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -18,7 +18,7 @@ 2.5 9.12 4.0.8 - 6.1.3 + 6.1.4 From 566c7b726ebec1b8eb981d8107ce3cbca59ea6d4 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 7 May 2024 21:25:01 +1200 Subject: [PATCH 1078/1323] httpclient: #426 Fix support for 204 no response body for HttpClient reading content (#430) * httpclient: #427 Fix support for 204 no response body for HttpClient reading content * Update test NimaProcessorTest to use release 21 --- .../io/avaje/http/client/BodyAdapter.java | 1 - .../io/avaje/http/client/BodyContent.java | 5 +++ .../io/avaje/http/client/DBodyContent.java | 5 +++ .../io/avaje/http/client/DBodyContentS.java | 5 +++ .../avaje/http/client/DHttpClientContext.java | 13 +++++++ .../main/java/org/example/TestController.java | 15 +++++--- .../http/generator/NimaProcessorTest.java | 4 +-- .../java/org/example/TestControllerTest.java | 35 +++++++++++++++++++ 8 files changed, 76 insertions(+), 7 deletions(-) diff --git a/http-client/src/main/java/io/avaje/http/client/BodyAdapter.java b/http-client/src/main/java/io/avaje/http/client/BodyAdapter.java index 5cb9f2ee3..ef6ee6de3 100644 --- a/http-client/src/main/java/io/avaje/http/client/BodyAdapter.java +++ b/http-client/src/main/java/io/avaje/http/client/BodyAdapter.java @@ -23,7 +23,6 @@ public interface BodyAdapter { * @param type The type of the bean this writer is for */ default BodyWriter beanWriter(Type type) { - throw new UnsupportedOperationException("java.lang.reflect.Type is not supported for this adapter"); } diff --git a/http-client/src/main/java/io/avaje/http/client/BodyContent.java b/http-client/src/main/java/io/avaje/http/client/BodyContent.java index 2f95d166a..6e6f0e42d 100644 --- a/http-client/src/main/java/io/avaje/http/client/BodyContent.java +++ b/http-client/src/main/java/io/avaje/http/client/BodyContent.java @@ -56,4 +56,9 @@ static BodyContent asJson(byte[] content) { * Return the content as UTF8 string. */ String contentAsUtf8(); + + /** + * Return true if the content is empty. + */ + boolean isEmpty(); } diff --git a/http-client/src/main/java/io/avaje/http/client/DBodyContent.java b/http-client/src/main/java/io/avaje/http/client/DBodyContent.java index eec7affaa..5770c05dd 100644 --- a/http-client/src/main/java/io/avaje/http/client/DBodyContent.java +++ b/http-client/src/main/java/io/avaje/http/client/DBodyContent.java @@ -36,6 +36,11 @@ public byte[] content() { return content; } + @Override + public boolean isEmpty() { + return content.length == 0; + } + @Override public String contentAsUtf8() { return new String(content, StandardCharsets.UTF_8); diff --git a/http-client/src/main/java/io/avaje/http/client/DBodyContentS.java b/http-client/src/main/java/io/avaje/http/client/DBodyContentS.java index c553a3721..664adeff9 100644 --- a/http-client/src/main/java/io/avaje/http/client/DBodyContentS.java +++ b/http-client/src/main/java/io/avaje/http/client/DBodyContentS.java @@ -25,6 +25,11 @@ public byte[] content() { return content.getBytes(StandardCharsets.UTF_8); } + @Override + public boolean isEmpty() { + return content == null || content.isEmpty(); + } + @Override public String contentAsUtf8() { return content; diff --git a/http-client/src/main/java/io/avaje/http/client/DHttpClientContext.java b/http-client/src/main/java/io/avaje/http/client/DHttpClientContext.java index f7a240be3..1d2934285 100644 --- a/http-client/src/main/java/io/avaje/http/client/DHttpClientContext.java +++ b/http-client/src/main/java/io/avaje/http/client/DHttpClientContext.java @@ -5,6 +5,7 @@ import java.net.http.HttpRequest; import java.net.http.HttpResponse; import java.time.Duration; +import java.util.Collections; import java.util.List; import java.util.Map; import java.util.concurrent.CompletableFuture; @@ -274,20 +275,32 @@ BodyReader beanReader(Type type) { } T readBean(Class type, BodyContent content) { + if (content.isEmpty()) { + return null; + } return bodyAdapter.beanReader(type).read(content); } List readList(Class type, BodyContent content) { + if (content.isEmpty()) { + return Collections.emptyList(); + } return bodyAdapter.listReader(type).read(content); } @SuppressWarnings("unchecked") T readBean(Type type, BodyContent content) { + if (content.isEmpty()) { + return null; + } return (T) bodyAdapter.beanReader(type).read(content); } @SuppressWarnings("unchecked") List readList(Type type, BodyContent content) { + if (content.isEmpty()) { + return Collections.emptyList(); + } return (List) bodyAdapter.listReader(type).read(content); } diff --git a/tests/test-nima-jsonb/src/main/java/org/example/TestController.java b/tests/test-nima-jsonb/src/main/java/org/example/TestController.java index 6f8593d67..d3f0ceef6 100644 --- a/tests/test-nima-jsonb/src/main/java/org/example/TestController.java +++ b/tests/test-nima-jsonb/src/main/java/org/example/TestController.java @@ -1,10 +1,7 @@ package org.example; import java.io.InputStream; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; import io.avaje.http.api.BodyString; import io.avaje.http.api.Controller; @@ -155,4 +152,14 @@ String pattern(String patty) { String patternPlus(String plus) { return plus.toString(); } + + @Get("/maybe/{maybe}") + Person maybePerson(boolean maybe) { + return maybe ? new Person(9, "hi") : null; + } + + @Get("/maybeList/{maybe}") + List maybePersonList(boolean maybe) { + return maybe ? List.of(new Person(9, "hi")) : null; // Collections.emptyList(); + } } diff --git a/tests/test-nima-jsonb/src/test/java/io/avaje/http/generator/NimaProcessorTest.java b/tests/test-nima-jsonb/src/test/java/io/avaje/http/generator/NimaProcessorTest.java index 963e3b91f..8f22b8177 100644 --- a/tests/test-nima-jsonb/src/test/java/io/avaje/http/generator/NimaProcessorTest.java +++ b/tests/test-nima-jsonb/src/test/java/io/avaje/http/generator/NimaProcessorTest.java @@ -45,7 +45,7 @@ void runAnnotationProcessor() throws Exception { final var task = compiler.getTask( - new PrintWriter(System.out), null, null, List.of("--release=20", "-AdisableDirectWrites=true"), null, files); + new PrintWriter(System.out), null, null, List.of("--release=21", "-AdisableDirectWrites=true"), null, files); task.setProcessors(List.of(new HelidonProcessor())); assertThat(task.call()).isTrue(); @@ -61,7 +61,7 @@ void runAnnotationProcessorWithJsonB() throws Exception { final var task = compiler.getTask( - new PrintWriter(System.out), null, null, List.of("--release=19"), null, files); + new PrintWriter(System.out), null, null, List.of("--release=21"), null, files); task.setProcessors(List.of(new HelidonProcessor())); assertThat(task.call()).isTrue(); diff --git a/tests/test-nima-jsonb/src/test/java/org/example/TestControllerTest.java b/tests/test-nima-jsonb/src/test/java/org/example/TestControllerTest.java index 6c43551c3..1389a006c 100644 --- a/tests/test-nima-jsonb/src/test/java/org/example/TestControllerTest.java +++ b/tests/test-nima-jsonb/src/test/java/org/example/TestControllerTest.java @@ -3,6 +3,7 @@ import static org.assertj.core.api.Assertions.assertThat; import java.net.http.HttpResponse; +import java.util.List; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Test; @@ -121,4 +122,38 @@ void ithrowIllegalStateException() { assertThat(res.statusCode()).isEqualTo(503); } + + @Test + void testNoBodyResponse() { + HttpResponse res = client.request() + .path("test/maybe/true") + .GET().as(Person.class); + + assertThat(res.statusCode()).isEqualTo(200); + assertThat(res.body().name()).isEqualTo("hi"); + + HttpResponse resNoBody = client.request() + .path("test/maybe/false") + .GET().as(Person.class); + + assertThat(resNoBody.statusCode()).isEqualTo(204); + assertThat(resNoBody.body()).isNull(); + } + + @Test + void testNoBodyListResponse() { + HttpResponse> res = client.request() + .path("test/maybeList/true") + .GET().asList(Person.class); + + assertThat(res.statusCode()).isEqualTo(200); + assertThat(res.body().getFirst().name()).isEqualTo("hi"); + + HttpResponse> resNoBody = client.request() + .path("test/maybeList/false") + .GET().asList(Person.class); + + assertThat(resNoBody.statusCode()).isEqualTo(204); + assertThat(resNoBody.body()).isEmpty(); + } } From cd36b018f04f78f6bff06724f2008c4fa8d478a1 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 7 May 2024 23:17:27 +1200 Subject: [PATCH 1079/1323] [HttpClient] Generated client to use suffix of Impl or HttpClient (#431) Avoid duplicating HttpClient or Client in the generated client class name. If the client interface ends in "Client" then use the suffix of "Impl" otherwise use "HttpClient". --- .../generator/client/ClientProcessor.java | 3 +- .../http/generator/client/ClientSuffix.java | 56 +++++++++++++++++++ .../http/generator/client/ClientWriter.java | 12 ++-- .../generator/client/ComponentMetaData.java | 12 +--- .../client/SimpleComponentWriter.java | 3 +- .../generator/client/ClientSuffixTest.java | 30 ++++++++++ .../java/org/example/MyOtherHttpClient.java | 11 ++++ .../main/java/org/example/MySillyClient.java | 11 ++++ 8 files changed, 119 insertions(+), 19 deletions(-) create mode 100644 http-generator-client/src/main/java/io/avaje/http/generator/client/ClientSuffix.java create mode 100644 http-generator-client/src/test/java/io/avaje/http/generator/client/ClientSuffixTest.java create mode 100644 tests/test-client-generation/src/main/java/org/example/MyOtherHttpClient.java create mode 100644 tests/test-client-generation/src/main/java/org/example/MySillyClient.java diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java index 99a3d2512..f94aab2e8 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java @@ -101,7 +101,8 @@ private void writeClient(Element controller) { } protected String writeClientAdapter(ControllerReader reader) throws IOException { - return new ClientWriter(reader, useJsonB).write(); + var suffix = ClientSuffix.fromInterface(reader.beanType().getQualifiedName().toString()); + return new ClientWriter(reader, suffix, useJsonB).write(); } private void initialiseComponent() { diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientSuffix.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientSuffix.java new file mode 100644 index 000000000..7178513d9 --- /dev/null +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientSuffix.java @@ -0,0 +1,56 @@ +package io.avaje.http.generator.client; + +/** + * Handling client naming suffix. + *

    + * The suffix chosen should avoid repeating "HttpClient" or "Client" + * in the generated class name. + */ +final class ClientSuffix { + + private static final String SUB_PACKAGE = ".httpclient"; + + /** + * Return the suffix to use for the generated client given the + * client interface name. + */ + static String fromInterface(String fullName) { + if (fullName.endsWith("Client")) { + return "Impl"; + } else { + return "HttpClient"; + } + } + + /** + * Remove the suffix from the generated name. + */ + static String removeSuffix(String clientName) { + if (clientName.endsWith("Impl")) { + return trim(clientName, 4); + } else if (clientName.endsWith("HttpClient")) { + return trim(clientName, 10); + } else { + return clientName; + } + } + + /** + * Return the interface name from the generated client name. + */ + static String toInterface(String clientName) { + return removeSubPackage(removeSuffix(clientName)); + } + + private static String trim(String name, int length) { + return name.substring(0, name.length() - length); + } + + private static String removeSubPackage(String className) { + final int pos = className.lastIndexOf(SUB_PACKAGE); + if (pos > -1) { + return className.substring(0, pos) + className.substring(pos + SUB_PACKAGE.length()); + } + return className; + } +} diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientWriter.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientWriter.java index 459615799..275e30e80 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientWriter.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientWriter.java @@ -18,15 +18,15 @@ class ClientWriter extends BaseControllerWriter { private static final String HTTP_CLIENT = "io.avaje.http.client.HttpClient"; private static final String AT_GENERATED = "@Generated(\"avaje-http-client-generator\")"; - private static final String SUFFIX = "HttpClient"; private final List methodList = new ArrayList<>(); private final boolean useJsonb; private final Set propertyConstants = new HashSet<>(); + private final String suffix; - - ClientWriter(ControllerReader reader, boolean useJsonB) throws IOException { - super(reader, SUFFIX); + ClientWriter(ControllerReader reader, String suffix, boolean useJsonB) throws IOException { + super(reader, suffix); + this.suffix = suffix; reader.addImportType(HTTP_CLIENT); this.useJsonb = useJsonB; readMethods(); @@ -67,11 +67,11 @@ private void writeMethods() { private void writeClassStart() { writer.append(AT_GENERATED).eol(); AnnotationUtil.writeAnnotations(writer, reader.beanType()); - writer.append("public class %s%s implements %s {", shortName, SUFFIX, shortName).eol().eol(); + writer.append("public class %s%s implements %s {", shortName, suffix, shortName).eol().eol(); writer.append(" private final HttpClient client;").eol().eol(); - writer.append(" public %s%s(HttpClient client) {", shortName, SUFFIX).eol(); + writer.append(" public %s%s(HttpClient client) {", shortName, suffix).eol(); writer.append(" this.client = client;").eol(); writer.append(" }").eol().eol(); } diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ComponentMetaData.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ComponentMetaData.java index 2b30927c7..91e2517d6 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ComponentMetaData.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ComponentMetaData.java @@ -52,17 +52,9 @@ List all() { Collection allImports() { final Set packageImports = new TreeSet<>(generatedClients); generatedClients.stream() - .map(s -> removeLast(removeLast(s, ".httpclient"), "HttpClient")) - .forEach(packageImports::add); + .map(ClientSuffix::toInterface) + .forEach(packageImports::add); return packageImports; } - - public static String removeLast(String className, String search) { - final int pos = className.lastIndexOf(search); - if (pos > -1) { - return className.substring(0, pos) + className.substring(pos + search.length()); - } - return className; - } } diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/SimpleComponentWriter.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/SimpleComponentWriter.java index ad6ec6cd2..28197d3cd 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/SimpleComponentWriter.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/SimpleComponentWriter.java @@ -64,7 +64,7 @@ private void writeRegister() { for (final String clientFullName : metaData.all()) { final String clientShortName = Util.shortName(clientFullName); - final var clientInterface = ComponentMetaData.removeLast(clientShortName, "HttpClient"); + final String clientInterface = ClientSuffix.removeSuffix(clientShortName); writer.append(" providerMap.put(%s.class, %s::new);", clientInterface, clientShortName).eol(); } writer.append(" }").eol().eol(); @@ -103,7 +103,6 @@ private void writeImports() { for (final String importType : importTypes) { writer.append("import %s;", importType).eol(); - writer.append("import %s;", importType).eol(); } writer.eol(); } diff --git a/http-generator-client/src/test/java/io/avaje/http/generator/client/ClientSuffixTest.java b/http-generator-client/src/test/java/io/avaje/http/generator/client/ClientSuffixTest.java new file mode 100644 index 000000000..f3de5c6e7 --- /dev/null +++ b/http-generator-client/src/test/java/io/avaje/http/generator/client/ClientSuffixTest.java @@ -0,0 +1,30 @@ +package io.avaje.http.generator.client; + +import org.junit.jupiter.api.Test; + +import static io.avaje.http.generator.client.ClientSuffix.*; +import static org.junit.jupiter.api.Assertions.*; + +class ClientSuffixTest { + + @Test + void testFromInterface() { + assertEquals("Impl", fromInterface("foo.MyClient")); + assertEquals("Impl", fromInterface("foo.MyHttpClient")); + assertEquals("HttpClient", fromInterface("foo.My")); + } + + @Test + void testRemoveSuffix() { + assertEquals("foo.MyClient", removeSuffix("foo.MyClientImpl")); + assertEquals("foo.MyHttpClient", removeSuffix("foo.MyHttpClientImpl")); + assertEquals("foo.My", removeSuffix("foo.MyHttpClient")); + } + + @Test + void testToInterface() { + assertEquals("foo.MyClient", toInterface("foo.httpclient.MyClientImpl")); + assertEquals("foo.MyHttpClient", toInterface("foo.httpclient.MyHttpClientImpl")); + assertEquals("foo.My", toInterface("foo.httpclient.MyHttpClient")); + } +} diff --git a/tests/test-client-generation/src/main/java/org/example/MyOtherHttpClient.java b/tests/test-client-generation/src/main/java/org/example/MyOtherHttpClient.java new file mode 100644 index 000000000..8c29a1ade --- /dev/null +++ b/tests/test-client-generation/src/main/java/org/example/MyOtherHttpClient.java @@ -0,0 +1,11 @@ +package org.example; + +import io.avaje.http.api.*; + +@Client +public interface MyOtherHttpClient { + + @Post + String asPlainString(); + +} diff --git a/tests/test-client-generation/src/main/java/org/example/MySillyClient.java b/tests/test-client-generation/src/main/java/org/example/MySillyClient.java new file mode 100644 index 000000000..bfc3717b2 --- /dev/null +++ b/tests/test-client-generation/src/main/java/org/example/MySillyClient.java @@ -0,0 +1,11 @@ +package org.example; + +import io.avaje.http.api.*; + +@Client +public interface MySillyClient { + + @Post + String asPlainString(); + +} From f0e7c421c3edf1b03f333da30cc1d50bbcc25660 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 7 May 2024 23:27:40 +1200 Subject: [PATCH 1080/1323] Version 2.5-RC1 --- http-api-javalin/pom.xml | 2 +- http-api/pom.xml | 2 +- http-client-gson-adapter/pom.xml | 4 ++-- http-client-moshi-adapter/pom.xml | 4 ++-- http-client/pom.xml | 4 ++-- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 2 +- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-inject-plugin/pom.xml | 2 +- pom.xml | 2 +- tests/pom.xml | 2 +- tests/test-client-generation/pom.xml | 2 +- tests/test-client/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- 20 files changed, 23 insertions(+), 23 deletions(-) diff --git a/http-api-javalin/pom.xml b/http-api-javalin/pom.xml index b9bebbf26..baa2b44e4 100644 --- a/http-api-javalin/pom.xml +++ b/http-api-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.5-SNAPSHOT + 2.5-RC1 .. diff --git a/http-api/pom.xml b/http-api/pom.xml index 10e778f72..caacbdf6b 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.5-SNAPSHOT + 2.5-RC1 .. diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index a2b39bcd6..0bcf46f50 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.5-SNAPSHOT + 2.5-RC1 avaje-http-client-gson @@ -20,7 +20,7 @@ io.avaje avaje-http-client - 2.5-SNAPSHOT + 2.5-RC1 provided diff --git a/http-client-moshi-adapter/pom.xml b/http-client-moshi-adapter/pom.xml index a6fd9a4d3..8165a20b2 100644 --- a/http-client-moshi-adapter/pom.xml +++ b/http-client-moshi-adapter/pom.xml @@ -3,7 +3,7 @@ io.avaje avaje-http-parent - 2.5-SNAPSHOT + 2.5-RC1 avaje-http-client-moshi @@ -19,7 +19,7 @@ io.avaje avaje-http-client - 2.5-SNAPSHOT + 2.5-RC1 provided diff --git a/http-client/pom.xml b/http-client/pom.xml index f14345d06..0783e955c 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.5-SNAPSHOT + 2.5-RC1 avaje-http-client @@ -66,7 +66,7 @@ io.avaje avaje-http-api - 2.5-SNAPSHOT + 2.5-RC1 diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index 0501361fd..aa057873a 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.5-SNAPSHOT + 2.5-RC1 avaje-http-client-generator diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 132422803..ee61471d0 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.5-SNAPSHOT + 2.5-RC1 avaje-http-generator-core diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index f40240138..e04e86247 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.5-SNAPSHOT + 2.5-RC1 avaje-http-helidon-generator diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index d5ba95269..a34c55c52 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.5-SNAPSHOT + 2.5-RC1 avaje-http-javalin-generator diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index 58d0f0da1..919fe4144 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.5-SNAPSHOT + 2.5-RC1 avaje-http-jex-generator diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index 88d81da1f..4a04ce278 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.5-SNAPSHOT + 2.5-RC1 .. diff --git a/pom.xml b/pom.xml index 2f73594d7..225388f96 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-parent - 2.5-SNAPSHOT + 2.5-RC1 pom diff --git a/tests/pom.xml b/tests/pom.xml index 0c2367fce..f0f26628d 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.5-SNAPSHOT + 2.5-RC1 tests diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index 4db55d91b..15fa90363 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.5-SNAPSHOT + 2.5-RC1 test-client-generation diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index 716310082..82fcaa361 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.5-SNAPSHOT + 2.5-RC1 test-client diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index d6c1996a8..5dd3a6f6d 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 2.5-SNAPSHOT + 2.5-RC1 test-javalin-jsonb diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 822e06813..b6e29f65e 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.5-SNAPSHOT + 2.5-RC1 test-javalin diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index c5036eeb6..41199eb97 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.5-SNAPSHOT + 2.5-RC1 test-jex diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index dc90d8ad3..94eb013bb 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.5-SNAPSHOT + 2.5-RC1 test-nima-jsonb diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index 4fead22fc..35b0bc1c7 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.5-SNAPSHOT + 2.5-RC1 test-nima From 643271c6009b6a005e1af3b8a0d741e0c40b5948 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Wed, 8 May 2024 20:39:23 +1200 Subject: [PATCH 1081/1323] Format code in client generator only (#432) --- .../http/generator/client/AnnotationUtil.java | 12 ++---- .../generator/client/ClientMethodWriter.java | 43 ++++++++----------- .../client/ClientPlatformAdapter.java | 2 +- .../generator/client/ClientProcessor.java | 7 ++- .../http/generator/client/ClientWriter.java | 2 +- .../generator/client/ComponentMetaData.java | 8 ---- .../generator/client/ComponentReader.java | 7 ++- .../http/generator/client/KnownResponse.java | 2 +- 8 files changed, 30 insertions(+), 53 deletions(-) diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/AnnotationUtil.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/AnnotationUtil.java index 0445e4208..bd0d5b9b6 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/AnnotationUtil.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/AnnotationUtil.java @@ -42,6 +42,7 @@ public static void writeAnnotations(Append writer, Element element, String inden } } + @SuppressWarnings("unchecked") private static void writeVal(final StringBuilder sb, final AnnotationValue annotationValue) { final var value = annotationValue.getValue(); // handle array values @@ -50,7 +51,6 @@ private static void writeVal(final StringBuilder sb, final AnnotationValue annot boolean first = true; for (final AnnotationValue listValue : (List) value) { - if (!first) { sb.append(", "); } @@ -61,16 +61,13 @@ private static void writeVal(final StringBuilder sb, final AnnotationValue annot sb.append("}"); // Handle enum values } else if (value instanceof VariableElement) { - final var element = (VariableElement) value; - final var type = UType.parse(element.asType()); - sb.append(type.full() + "." + element.toString()); + sb.append(type.full()).append('.').append(element); // handle annotation values - } else if (value instanceof AnnotationMirror) { + } else if (value instanceof AnnotationMirror) { final var mirror = (AnnotationMirror) value; - final String annotationName = mirror.getAnnotationType().toString(); sb.append("@").append(annotationName).append("("); boolean first = true; @@ -83,10 +80,9 @@ private static void writeVal(final StringBuilder sb, final AnnotationValue annot writeVal(sb, entry.getValue()); first = false; } - sb.append(")"); } else { - sb.append(annotationValue.toString()); + sb.append(annotationValue); } } } diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java index ed838d217..4697ae336 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java @@ -59,20 +59,19 @@ final class ClientMethodWriter { this.presetHeaders = Stream.concat( - HeadersPrism.getOptionalOn(element).stream(), - HeadersPrism.getOptionalOn(element.getEnclosingElement()).stream()) - .map(HeadersPrism::value) - .map(List::stream) - .flatMap(Function.identity()) - .peek( - s -> { + HeadersPrism.getOptionalOn(element).stream(), + HeadersPrism.getOptionalOn(element.getEnclosingElement()).stream()) + .map(HeadersPrism::value) + .map(List::stream) + .flatMap(Function.identity()) + .peek(s -> { if (!s.contains(":")) { logError(element, "@Headers value must have a \":\"", method); } }) - .map(s -> s.split(":", 2)) - .filter(a -> a.length == 2) - .map(a -> Map.entry(a[0].trim(), a[1].trim())).collect(toList()); + .map(s -> s.split(":", 2)) + .filter(a -> a.length == 2) + .map(a -> Map.entry(a[0].trim(), a[1].trim())).collect(toList()); } void addImportTypes(ControllerReader reader) { @@ -357,26 +356,18 @@ private void writeBody() { private void writeErrorMapper() { method.throwsList().stream() .map(ProcessingContext::asElement) - .filter( - e -> - isAssignable2Interface( - e.getQualifiedName().toString(), "java.lang.RuntimeException")) - .filter( - e -> - ElementFilter.constructorsIn(e.getEnclosedElements()).stream() - .filter(c -> c.getParameters().size() == 1) - .map(c -> c.getParameters().get(0).asType().toString()) - .map(Util::trimAnnotations) - .anyMatch("io.avaje.http.client.HttpException"::equals)) + .filter(e -> isAssignable2Interface(e.getQualifiedName().toString(), "java.lang.RuntimeException")) + .filter(e -> + ElementFilter.constructorsIn(e.getEnclosedElements()).stream() + .filter(c -> c.getParameters().size() == 1) + .map(c -> c.getParameters().get(0).asType().toString()) + .map(Util::trimAnnotations) + .anyMatch("io.avaje.http.client.HttpException"::equals)) .findFirst() .map(TypeElement::getQualifiedName) .map(Object::toString) .map(Util::shortName) - .ifPresent( - exception -> - writer - .append(" .errorMapper(%s::new)", exception) - .eol()); + .ifPresent(exception -> writer.append(" .errorMapper(%s::new)", exception).eol()); } /** diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientPlatformAdapter.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientPlatformAdapter.java index 1e1cb04dd..2d6c0de88 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientPlatformAdapter.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientPlatformAdapter.java @@ -8,7 +8,7 @@ import io.avaje.http.generator.core.PlatformAdapter; import io.avaje.http.generator.core.UType; -class ClientPlatformAdapter implements PlatformAdapter { +final class ClientPlatformAdapter implements PlatformAdapter { @Override public boolean isContextType(String rawType) { diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java index f94aab2e8..bfa894148 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java @@ -82,9 +82,9 @@ private void readModule() { private void writeForImported(Element importedElement) { ImportPrism.getInstanceOn(importedElement).types().stream() - .map(ProcessingContext::asElement) - .filter(Objects::nonNull) - .forEach(this::writeClient); + .map(ProcessingContext::asElement) + .filter(Objects::nonNull) + .forEach(this::writeClient); } private void writeClient(Element controller) { @@ -94,7 +94,6 @@ private void writeClient(Element controller) { try { metaData.add(writeClientAdapter(reader)); } catch (final Exception e) { - e.printStackTrace(); logError(reader.beanType(), "Failed to write client class " + e); } } diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientWriter.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientWriter.java index 275e30e80..52d7d9445 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientWriter.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientWriter.java @@ -13,7 +13,7 @@ /** * Write Http client adapter. */ -class ClientWriter extends BaseControllerWriter { +final class ClientWriter extends BaseControllerWriter { private static final String HTTP_CLIENT = "io.avaje.http.client.HttpClient"; diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ComponentMetaData.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ComponentMetaData.java index 91e2517d6..ebd963150 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ComponentMetaData.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ComponentMetaData.java @@ -17,10 +17,6 @@ void initialiseFullName() { fullName(); } - boolean contains(String type) { - return generatedClients.contains(type); - } - void add(String type) { generatedClients.add(type); } @@ -40,10 +36,6 @@ String fullName() { return fullName; } - String packageName() { - return TopPackage.packageOf(fullName()); - } - List all() { return generatedClients; } diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ComponentReader.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ComponentReader.java index 88084c99e..b6d335af1 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ComponentReader.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ComponentReader.java @@ -46,9 +46,9 @@ void read() { private void readMetaData(TypeElement moduleType) { for (final AnnotationMirror annotationMirror : moduleType.getAnnotationMirrors()) { MetaDataPrism.getOptional(annotationMirror).map(MetaDataPrism::value).stream() - .flatMap(List::stream) - .map(TypeMirror::toString) - .forEach(componentMetaData::add); + .flatMap(List::stream) + .map(TypeMirror::toString) + .forEach(componentMetaData::add); } } @@ -83,7 +83,6 @@ private List loadMetaInf() { logDebug("FilerException reading services file"); } catch (final Exception e) { - e.printStackTrace(); logWarn("Error reading services file: " + e.getMessage()); } return Collections.emptyList(); diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/KnownResponse.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/KnownResponse.java index 835cfda88..b3c53f9f8 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/KnownResponse.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/KnownResponse.java @@ -6,7 +6,7 @@ /** * Known response types for Http Client methods. */ -class KnownResponse { +final class KnownResponse { private final Map map = new HashMap<>(); From c5d2438bb741d5ee57661152c204c854be9c80c8 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Wed, 8 May 2024 20:53:41 +1200 Subject: [PATCH 1082/1323] Tidy ClientMethodWriter merge .map() and flatMap(identity()) into flatMap() (#433) --- .../io/avaje/http/generator/client/ClientMethodWriter.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java index 4697ae336..fd07d316d 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java @@ -10,7 +10,6 @@ import java.util.Map.Entry; import java.util.Optional; import java.util.Set; -import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -62,8 +61,7 @@ final class ClientMethodWriter { HeadersPrism.getOptionalOn(element).stream(), HeadersPrism.getOptionalOn(element.getEnclosingElement()).stream()) .map(HeadersPrism::value) - .map(List::stream) - .flatMap(Function.identity()) + .flatMap(List::stream) .peek(s -> { if (!s.contains(":")) { logError(element, "@Headers value must have a \":\"", method); From 5f4af851faa405fbc03e511c160bd49231ae81ad Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Thu, 16 May 2024 06:14:49 -0400 Subject: [PATCH 1083/1323] [http-client] Update README.md (#434) The loom stuff is cool, but not exactly up to date since it was done on JDK 17 --- http-client/README.md | 154 +++--------------------------------------- 1 file changed, 11 insertions(+), 143 deletions(-) diff --git a/http-client/README.md b/http-client/README.md index ac996d837..fd88a663f 100644 --- a/http-client/README.md +++ b/http-client/README.md @@ -1,4 +1,4 @@ -[![Build](https://github.com/avaje/avaje-http-client/actions/workflows/build.yml/badge.svg)](https://github.com/avaje/avaje-http-client/actions/workflows/build.yml) +[![Build](https://github.com/avaje/avaje-http/actions/workflows/build.yml/badge.svg)](https://github.com/avaje/avaje-http-client/actions/workflows/build.yml) [![Maven Central](https://img.shields.io/maven-central/v/io.avaje/avaje-http-client.svg?label=Maven%20Central)](https://mvnrepository.com/artifact/io.avaje/avaje-http-client) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://github.com/avaje/avaje-http-client/blob/master/LICENSE) @@ -6,16 +6,15 @@ A lightweight wrapper to the [JDK 11+ Java Http Client](http://openjdk.java.net/groups/net/httpclient/intro.html) -- Use Java 11.0.8 or higher (some SSL related bugs prior to 11.0.8 with JDK HttpClient) -- Adds a fluid API for building URL and payload -- Adds JSON marshalling/unmarshalling of request and response using Jackson or Gson +- Requires Java 11+ +- Adds a fluid API for building URLs and payloads +- Adds JSON marshalling/unmarshalling of request/response using avaje-jsonb, Jackson, Moshi, or Gson - Gzip encoding/decoding - Logging of request/response logging - Interception of request/response -- Built in support for authorization via Basic Auth and Bearer Token +- Built in support for authorization via Basic Auth and Bearer Tokens - Provides async and sync API - ### Dependency ```xml @@ -60,13 +59,6 @@ From HttpClient: - Async processing of the request using CompletableFuture - a bean, list of beans, stream of beans, String, Void or any JDK Response.BodyHandler - - -## Limitations: -- No support for POSTing multipart-form currently -- Retry (when specified) does not apply to `async` response processing` - - ## JDK HttpClient - Introduction to JDK HttpClient at @@ -75,7 +67,6 @@ From HttpClient: - Javadoc for JDK [HttpClient](https://docs.oracle.com/en/java/javase/11/docs/api/java.net.http/java/net/http/HttpClient.html) - #### Example GET as String ```java HttpClient client = HttpClient.builder() @@ -172,7 +163,7 @@ Overview of response types for sync calls. ### HttpResponse BodyHandlers JDK HttpClient provides a number of [BodyHandlers](https://docs.oracle.com/en/java/javase/11/docs/api/java.net.http/java/net/http/HttpResponse.BodyHandler.html) -including reactive Flow based subscribers. With the `handler()` method we can use any of these or our own [`HttpResponse.BodyHandler`](https://docs.oracle.com/en/java/javase/11/docs/api/java.net.http/java/net/http/HttpResponse.BodyHandler.html) +including reactive Flow-based subscribers. With the `handler()` method we can use any of these or our own [`HttpResponse.BodyHandler`](https://docs.oracle.com/en/java/javase/11/docs/api/java.net.http/java/net/http/HttpResponse.BodyHandler.html) implementation. Refer to [HttpResponse.BodyHandlers](https://docs.oracle.com/en/java/javase/11/docs/api/java.net.http/java/net/http/HttpResponse.BodyHandlers.html) @@ -198,8 +189,6 @@ When sending body content we can use: - formParams() for url encoded form (`application/x-www-form-urlencoded`) - Any [HttpRequest.BodyPublisher](https://docs.oracle.com/en/java/javase/11/docs/api/java.net.http/java/net/http/HttpRequest.BodyPublishers.html) - - ## Examples #### GET as String @@ -345,7 +334,7 @@ HttpResponse res = client.request() assertThat(res.statusCode()).isEqualTo(201); ``` -## Retry (Sync Requests Only) +## Retry To add Retry funtionality, use `.retryHandler(yourhandler)` on the builder to provide your retry handler. The `RetryHandler` interface provides two methods, one for status exceptions (e.g. you get a 4xx/5xx from the server) and another for exceptions thrown by the underlying client (e.g. server times out or client couldn't send request). Here is example implementation of `RetryHandler`. ``` @@ -382,7 +371,7 @@ public final class ExampleRetry implements RetryHandler { ## Async processing All async requests use JDK httpClient.sendAsync(...) returning CompletableFuture. Commonly the -`whenComplete()` callback will be used to process the async responses. +`whenComplete()` callback is used to process the async responses. The `bean()`, `list()` and `stream()` responses throw a `HttpException` if the status code >= 300 (noting that by default redirects are followed apart for HTTPS to HTTP). @@ -521,10 +510,9 @@ call.async() }); ``` - ## BasicAuthIntercept - Authorization Basic / Basic Auth -We can use `BasicAuthIntercept` to intercept all requests adding a `Authorization: Basic ...` +We can use `BasicAuthIntercept` to intercept all requests by adding an `Authorization: Basic ...` header ("Basic Auth"). ##### Example @@ -541,7 +529,7 @@ HttpClient client = ## AuthTokenProvider - Authorization Bearer token -For Authorization using `Bearer` tokens that are obtained and expire, implement `AuthTokenProvider` +For authorization using `Bearer` tokens that are obtained and expire, implement `AuthTokenProvider` and register that when building the HttpClient. ### 1. Implement AuthTokenProvider @@ -580,124 +568,4 @@ and register that when building the HttpClient. All requests using the HttpClient will automatically get an `Authorization` header with `Bearer` token added. The token will be -obtained for initial request and then renewed when the token has expired. - - -# 10K requests - Loom vs Async - -The following is a very quick and rough comparison of running 10,000 requests -using `Async` vs `Loom`. - -The intention is to test the thought that in a "future Loom world" the -desire to use `async()` execution with HttpClient reduces. - -TLDR: Caveat, caveat, more caveats ... initial testing shows Loom to be just a -touch faster (~10%) than async. - -To run my tests I use [Jex](https://github.com/avaje/avaje-jex) as the server -(Jetty based) and have it running using Loom. For whatever testing you do -you will need a server that can handle a very large number of concurrent requests. - -The Loom blocking request (make 10K of these) - -```java -HttpResponse hres = httpClient.request() - .path("s200") - .GET() - .asString(); -``` -The equivalent async request (make 10K of these joining the CompletableFuture's). - -```java -CompletableFuture> future = httpClient.request() - .path("s200") - .GET() - .async() - .asString() - .whenComplete((hres, throwable) -> { - ... - }); -``` - - -### 10K requests using Async and reactive streams - -Use `.async()` to execute the requests which internally is using JDK -HttpClient's reactive streams. The `whenComplete()` callback is invoked -when the response is ready. Collect all the resulting CompletableFuture -and wait for them all to complete. - -Outline: - -```java - -// Collect all the CompletableFuture's -List>> futures = new ArrayList<>(); - -for (int i = 0; i < 10_000; i++) { - futures.add(httpClient.request().path("s200") - .GET() - .async().asString() - .whenComplete((hres, throwable) -> { - // confirm 200 response etc - ... - })); -} - -// wait for all requests to complete via join() ... -CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join(); - -``` - -### 10K requests using Loom - -With Loom Java 17 EA Release we can use `Executors.newVirtualThreadExecutor()` -to return an ExecutorService that uses Loom Virtual Threads. These are backed -by "Carrier threads" (via ForkedJoinPool). - -Outline: - -```java - -// use Loom's Executors.newVirtualThreadExecutor() - -try (ExecutorService executorService = Executors.newVirtualThreadExecutor()) { - for (int i = 0; i < 10_000; i++) { - executorService.submit(this::task); - } -} - -``` -```java -private void task() { - HttpResponse hres = - httpClient.request().path("s200") - .GET() - .asString(); - - // confirm 200 response etc - ... -} - -``` - -Caveat: Proper performance benchmarks are really hard and take a lot of -effort. - -Running some "rough/approx performance comparison tests" using `Loom` -build `17 EA 2021-09-14 / (build 17-loom+7-342)` vs `Async` for my environment -and 10K request scenarios has loom execution around 10% faster than async. - -It looks like Loom and Async run in pretty much the same time although it -currently looks that Loom is just a touch faster (perhaps due to how it does -park/unpark). More investigation required. - - -Date: 2021-06 -Build: `17 EA 2021-09-14 / (build 17-loom+7-342)`. - -``` -openjdk version "17-loom" 2021-09-14 -OpenJDK Runtime Environment (build 17-loom+7-342) -OpenJDK 64-Bit Server VM (build 17-loom+7-342, mixed mode, sharing) -``` +obtained for the initial request and then renewed when the token has expired. From d80d8fcb32486824c3761e77a7c5ee68f686c32e Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Thu, 16 May 2024 22:22:33 +1200 Subject: [PATCH 1084/1323] Version 2.5 --- http-api-javalin/pom.xml | 2 +- http-api/pom.xml | 2 +- http-client-gson-adapter/pom.xml | 4 ++-- http-client-moshi-adapter/pom.xml | 4 ++-- http-client/pom.xml | 4 ++-- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 2 +- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-inject-plugin/pom.xml | 2 +- pom.xml | 2 +- tests/pom.xml | 2 +- tests/test-client-generation/pom.xml | 2 +- tests/test-client/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- 20 files changed, 23 insertions(+), 23 deletions(-) diff --git a/http-api-javalin/pom.xml b/http-api-javalin/pom.xml index baa2b44e4..532956749 100644 --- a/http-api-javalin/pom.xml +++ b/http-api-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.5-RC1 + 2.5 .. diff --git a/http-api/pom.xml b/http-api/pom.xml index caacbdf6b..2ba529a97 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.5-RC1 + 2.5 .. diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index 0bcf46f50..7e89369e5 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.5-RC1 + 2.5 avaje-http-client-gson @@ -20,7 +20,7 @@ io.avaje avaje-http-client - 2.5-RC1 + 2.5 provided diff --git a/http-client-moshi-adapter/pom.xml b/http-client-moshi-adapter/pom.xml index 8165a20b2..e87c9bae7 100644 --- a/http-client-moshi-adapter/pom.xml +++ b/http-client-moshi-adapter/pom.xml @@ -3,7 +3,7 @@ io.avaje avaje-http-parent - 2.5-RC1 + 2.5 avaje-http-client-moshi @@ -19,7 +19,7 @@ io.avaje avaje-http-client - 2.5-RC1 + 2.5 provided diff --git a/http-client/pom.xml b/http-client/pom.xml index 0783e955c..0606242dc 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.5-RC1 + 2.5 avaje-http-client @@ -66,7 +66,7 @@ io.avaje avaje-http-api - 2.5-RC1 + 2.5 diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index aa057873a..d7f0068f4 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.5-RC1 + 2.5 avaje-http-client-generator diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index ee61471d0..3059b307e 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.5-RC1 + 2.5 avaje-http-generator-core diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index e04e86247..6433a3929 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.5-RC1 + 2.5 avaje-http-helidon-generator diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index a34c55c52..3378e6cdb 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.5-RC1 + 2.5 avaje-http-javalin-generator diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index 919fe4144..3551af043 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.5-RC1 + 2.5 avaje-http-jex-generator diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index 4a04ce278..c021b8459 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.5-RC1 + 2.5 .. diff --git a/pom.xml b/pom.xml index 225388f96..0cbcd1071 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-parent - 2.5-RC1 + 2.5 pom diff --git a/tests/pom.xml b/tests/pom.xml index f0f26628d..6a692ca54 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.5-RC1 + 2.5 tests diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index 15fa90363..96a8bd4cd 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.5-RC1 + 2.5 test-client-generation diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index 82fcaa361..d35a34aa4 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.5-RC1 + 2.5 test-client diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 5dd3a6f6d..91df37311 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 2.5-RC1 + 2.5 test-javalin-jsonb diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index b6e29f65e..8b7fc12da 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.5-RC1 + 2.5 test-javalin diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 41199eb97..958aa0b6a 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.5-RC1 + 2.5 test-jex diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 94eb013bb..c36f6beff 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.5-RC1 + 2.5 test-nima-jsonb diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index 35b0bc1c7..28602b723 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.5-RC1 + 2.5 test-nima From 521753b0c2951bbf99367e396c852465944c4636 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Thu, 16 May 2024 22:23:18 +1200 Subject: [PATCH 1085/1323] Bump to next snapshot --- http-api-javalin/pom.xml | 2 +- http-api/pom.xml | 2 +- http-client-gson-adapter/pom.xml | 4 ++-- http-client-moshi-adapter/pom.xml | 4 ++-- http-client/pom.xml | 4 ++-- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 2 +- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-inject-plugin/pom.xml | 2 +- pom.xml | 2 +- tests/pom.xml | 2 +- tests/test-client-generation/pom.xml | 2 +- tests/test-client/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- 20 files changed, 23 insertions(+), 23 deletions(-) diff --git a/http-api-javalin/pom.xml b/http-api-javalin/pom.xml index 532956749..6cdcac033 100644 --- a/http-api-javalin/pom.xml +++ b/http-api-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.5 + 2.6-SNAPSHOT .. diff --git a/http-api/pom.xml b/http-api/pom.xml index 2ba529a97..303a1196f 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.5 + 2.6-SNAPSHOT .. diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index 7e89369e5..dc5118657 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.5 + 2.6-SNAPSHOT avaje-http-client-gson @@ -20,7 +20,7 @@ io.avaje avaje-http-client - 2.5 + 2.6-SNAPSHOT provided diff --git a/http-client-moshi-adapter/pom.xml b/http-client-moshi-adapter/pom.xml index e87c9bae7..71ffef7c9 100644 --- a/http-client-moshi-adapter/pom.xml +++ b/http-client-moshi-adapter/pom.xml @@ -3,7 +3,7 @@ io.avaje avaje-http-parent - 2.5 + 2.6-SNAPSHOT avaje-http-client-moshi @@ -19,7 +19,7 @@ io.avaje avaje-http-client - 2.5 + 2.6-SNAPSHOT provided diff --git a/http-client/pom.xml b/http-client/pom.xml index 0606242dc..12e801ddc 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.5 + 2.6-SNAPSHOT avaje-http-client @@ -66,7 +66,7 @@ io.avaje avaje-http-api - 2.5 + 2.6-SNAPSHOT diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index d7f0068f4..bf5b0f49c 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.5 + 2.6-SNAPSHOT avaje-http-client-generator diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 3059b307e..8ff90d2ff 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.5 + 2.6-SNAPSHOT avaje-http-generator-core diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index 6433a3929..f730b9535 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.5 + 2.6-SNAPSHOT avaje-http-helidon-generator diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index 3378e6cdb..3ef83ad16 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.5 + 2.6-SNAPSHOT avaje-http-javalin-generator diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index 3551af043..67896a49c 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.5 + 2.6-SNAPSHOT avaje-http-jex-generator diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index c021b8459..d885de697 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.5 + 2.6-SNAPSHOT .. diff --git a/pom.xml b/pom.xml index 0cbcd1071..311a476f9 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-parent - 2.5 + 2.6-SNAPSHOT pom diff --git a/tests/pom.xml b/tests/pom.xml index 6a692ca54..9082db66f 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.5 + 2.6-SNAPSHOT tests diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index 96a8bd4cd..bd1265267 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.5 + 2.6-SNAPSHOT test-client-generation diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index d35a34aa4..72533b7b4 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.5 + 2.6-SNAPSHOT test-client diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 91df37311..b64c3af2a 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 2.5 + 2.6-SNAPSHOT test-javalin-jsonb diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 8b7fc12da..2c8ab7c01 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.5 + 2.6-SNAPSHOT test-javalin diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 958aa0b6a..7d40767ca 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.5 + 2.6-SNAPSHOT test-jex diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index c36f6beff..23ef8da65 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.5 + 2.6-SNAPSHOT test-nima-jsonb diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index 28602b723..3c652a785 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.5 + 2.6-SNAPSHOT test-nima From cda8929c06ae55aa924018bf34383ff58cb2003a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 20 May 2024 19:42:44 +0000 Subject: [PATCH 1086/1323] --- updated-dependencies: - dependency-name: com.google.code.gson:gson dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- http-client-gson-adapter/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index dc5118657..749359b5e 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -14,7 +14,7 @@ com.google.code.gson gson - 2.10.1 + 2.11.0 From 1907ec8383874c633e93e723988dee903eecfc54 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 20 May 2024 19:44:40 +0000 Subject: [PATCH 1087/1323] --- updated-dependencies: - dependency-name: io.swagger.core.v3:swagger-annotations dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: io.swagger.core.v3:swagger-models dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index 311a476f9..a6f6ba609 100644 --- a/pom.xml +++ b/pom.xml @@ -19,7 +19,7 @@ true - 2.2.21 + 2.2.22 2.14.2 1.21 ${project.build.directory}${file.separator}module-info.shade diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index b64c3af2a..acf533a58 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -13,7 +13,7 @@ true org.example.myapp.Main - 2.2.21 + 2.2.22 1.3.71 diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 2c8ab7c01..c6d580258 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -12,7 +12,7 @@ true org.example.myapp.Main - 2.2.21 + 2.2.22 1.3.71 diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 7d40767ca..8c1ed7ca2 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -13,7 +13,7 @@ true org.example.myapp.Main 2.5 - 2.2.21 + 2.2.22 From 4ae0df40411aad409b26c04f8c4e72831caf353a Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Mon, 20 May 2024 16:26:18 -0400 Subject: [PATCH 1088/1323] skip string conversion property --- .../io/avaje/http/generator/core/openapi/OpenAPISerializer.java | 1 + 1 file changed, 1 insertion(+) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/OpenAPISerializer.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/OpenAPISerializer.java index 942a05d41..7f57bc00a 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/OpenAPISerializer.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/OpenAPISerializer.java @@ -66,6 +66,7 @@ static String serialize(Object obj) throws IllegalAccessException { // skip JsonIgnored fields if ("BIND_TYPE_AND_TYPES".equals(field.getName()) + || "BINARY_STRING_CONVERSION_PROPERTY".equals(field.getName()) || "COMPONENTS_SCHEMAS_REF".equals(field.getName()) || "exampleSetFlag".equals(field.getName()) || "types".equals(field.getName()) From db5bf8b1e6d619bff31b0e81bd63e694bde344c7 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Tue, 21 May 2024 06:25:38 -0400 Subject: [PATCH 1089/1323] [http-client] Fix BeanParam on Eclipse (#436) * fix beanParam on eclipse low priority, but I guess eclipse prints out the entire method signature * Format BeanParamReader and remove test code that does not extend coverage --------- Co-authored-by: Rob Bygrave --- .../http/generator/client/ClientProcessorTest.java | 2 +- .../http/generator/client/clients/ExampleClient2.java | 10 ---------- .../io/avaje/http/generator/core/BeanParamReader.java | 4 +++- 3 files changed, 4 insertions(+), 12 deletions(-) delete mode 100644 http-generator-client/src/test/java/io/avaje/http/generator/client/clients/ExampleClient2.java diff --git a/http-generator-client/src/test/java/io/avaje/http/generator/client/ClientProcessorTest.java b/http-generator-client/src/test/java/io/avaje/http/generator/client/ClientProcessorTest.java index df788114e..43ec46466 100644 --- a/http-generator-client/src/test/java/io/avaje/http/generator/client/ClientProcessorTest.java +++ b/http-generator-client/src/test/java/io/avaje/http/generator/client/ClientProcessorTest.java @@ -50,7 +50,7 @@ void testGeneration() throws Exception { final CompilationTask task = compiler.getTask( - new PrintWriter(System.out), null, null, Arrays.asList("--release=11"), null, files); + new PrintWriter(System.out), null, null, List.of("--release=" + Integer.getInteger("java.specification.version")), null, files); task.setProcessors(Arrays.asList(new ClientProcessor())); assertThat(task.call()).isTrue(); diff --git a/http-generator-client/src/test/java/io/avaje/http/generator/client/clients/ExampleClient2.java b/http-generator-client/src/test/java/io/avaje/http/generator/client/clients/ExampleClient2.java deleted file mode 100644 index 38c0e7b49..000000000 --- a/http-generator-client/src/test/java/io/avaje/http/generator/client/clients/ExampleClient2.java +++ /dev/null @@ -1,10 +0,0 @@ -package io.avaje.http.generator.client.clients; - -import io.avaje.http.api.Client; -import io.avaje.http.api.Patch; - -@Client -public interface ExampleClient2 extends ExampleClient { - @Patch - void patchy2(); -} diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/BeanParamReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/BeanParamReader.java index 5c18b089d..8218d289e 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/BeanParamReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/BeanParamReader.java @@ -117,7 +117,9 @@ public void writeFormParams(Append writer) { ParamType paramType = field.element.paramType(); String type = propertyParamType(paramType); if (type != null) { - String accessor = (getter != null) ? getter.toString() : field.isPublic() ? field.varName() : null; + String accessor = (getter != null) + ? getter.getSimpleName() + "()" + : field.isPublic() ? field.varName() : null; if (accessor != null) { writer.append(" .%s(\"%s\", %s.%s)", type, field.paramName(), beanVarName, accessor).eol(); } From 3b40a1a2941c64f53a74e1091755152333479a03 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 21 May 2024 22:33:47 +1200 Subject: [PATCH 1090/1323] Version 2.6-RC1 --- http-api-javalin/pom.xml | 2 +- http-api/pom.xml | 2 +- http-client-gson-adapter/pom.xml | 4 ++-- http-client-moshi-adapter/pom.xml | 4 ++-- http-client/pom.xml | 4 ++-- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 2 +- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-inject-plugin/pom.xml | 2 +- pom.xml | 2 +- tests/pom.xml | 2 +- tests/test-client-generation/pom.xml | 2 +- tests/test-client/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- 20 files changed, 23 insertions(+), 23 deletions(-) diff --git a/http-api-javalin/pom.xml b/http-api-javalin/pom.xml index 6cdcac033..f38b8839f 100644 --- a/http-api-javalin/pom.xml +++ b/http-api-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.6-SNAPSHOT + 2.6-RC1 .. diff --git a/http-api/pom.xml b/http-api/pom.xml index 303a1196f..1837460cb 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.6-SNAPSHOT + 2.6-RC1 .. diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index 749359b5e..a2c4ff1d2 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.6-SNAPSHOT + 2.6-RC1 avaje-http-client-gson @@ -20,7 +20,7 @@ io.avaje avaje-http-client - 2.6-SNAPSHOT + 2.6-RC1 provided diff --git a/http-client-moshi-adapter/pom.xml b/http-client-moshi-adapter/pom.xml index 71ffef7c9..93173772b 100644 --- a/http-client-moshi-adapter/pom.xml +++ b/http-client-moshi-adapter/pom.xml @@ -3,7 +3,7 @@ io.avaje avaje-http-parent - 2.6-SNAPSHOT + 2.6-RC1 avaje-http-client-moshi @@ -19,7 +19,7 @@ io.avaje avaje-http-client - 2.6-SNAPSHOT + 2.6-RC1 provided diff --git a/http-client/pom.xml b/http-client/pom.xml index 12e801ddc..736e2013b 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.6-SNAPSHOT + 2.6-RC1 avaje-http-client @@ -66,7 +66,7 @@ io.avaje avaje-http-api - 2.6-SNAPSHOT + 2.6-RC1 diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index bf5b0f49c..305f4aa6e 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.6-SNAPSHOT + 2.6-RC1 avaje-http-client-generator diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 8ff90d2ff..370c49386 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.6-SNAPSHOT + 2.6-RC1 avaje-http-generator-core diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index f730b9535..0494b1daf 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.6-SNAPSHOT + 2.6-RC1 avaje-http-helidon-generator diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index 3ef83ad16..ea9a6ae73 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.6-SNAPSHOT + 2.6-RC1 avaje-http-javalin-generator diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index 67896a49c..787b49aca 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.6-SNAPSHOT + 2.6-RC1 avaje-http-jex-generator diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index d885de697..fc8de7fac 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.6-SNAPSHOT + 2.6-RC1 .. diff --git a/pom.xml b/pom.xml index a6f6ba609..a5f16b9ec 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-parent - 2.6-SNAPSHOT + 2.6-RC1 pom diff --git a/tests/pom.xml b/tests/pom.xml index 9082db66f..9924f0d23 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.6-SNAPSHOT + 2.6-RC1 tests diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index bd1265267..049ff4b3c 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.6-SNAPSHOT + 2.6-RC1 test-client-generation diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index 72533b7b4..d2d60d9da 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.6-SNAPSHOT + 2.6-RC1 test-client diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index acf533a58..f45031ffb 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 2.6-SNAPSHOT + 2.6-RC1 test-javalin-jsonb diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index c6d580258..6307622f1 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.6-SNAPSHOT + 2.6-RC1 test-javalin diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 8c1ed7ca2..70714c850 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.6-SNAPSHOT + 2.6-RC1 test-jex diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 23ef8da65..6b9f309a0 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.6-SNAPSHOT + 2.6-RC1 test-nima-jsonb diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index 3c652a785..3a909037e 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.6-SNAPSHOT + 2.6-RC1 test-nima From 636aeec223a0e129d8fa47442e4f704dfa357d28 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 27 May 2024 19:07:06 +0000 Subject: [PATCH 1091/1323] Bump jakarta.validation:jakarta.validation-api from 3.0.2 to 3.1.0 Bumps [jakarta.validation:jakarta.validation-api](https://github.com/jakartaee/validation) from 3.0.2 to 3.1.0. - [Release notes](https://github.com/jakartaee/validation/releases) - [Commits](https://github.com/jakartaee/validation/compare/3.0.2...3.1.0) --- updated-dependencies: - dependency-name: jakarta.validation:jakarta.validation-api dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- http-generator-core/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 370c49386..31194e098 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -55,7 +55,7 @@ jakarta.validation jakarta.validation-api - 3.0.2 + 3.1.0 true provided From 3141186cf721017ca321ec71e092b8120067c017 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 27 May 2024 19:09:05 +0000 Subject: [PATCH 1092/1323] Bump org.assertj:assertj-core from 3.25.3 to 3.26.0 Bumps [org.assertj:assertj-core](https://github.com/assertj/assertj) from 3.25.3 to 3.26.0. - [Release notes](https://github.com/assertj/assertj/releases) - [Commits](https://github.com/assertj/assertj/compare/assertj-build-3.25.3...assertj-build-3.26.0) --- updated-dependencies: - dependency-name: org.assertj:assertj-core dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- tests/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/pom.xml b/tests/pom.xml index 9924f0d23..6203416fc 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -13,7 +13,7 @@ true 5.10.2 - 3.25.3 + 3.26.0 2.17.1 2.5 9.12 From 29dd9ae0c5ea062c880ea8c56ea9ff31de7dd4f1 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Thu, 30 May 2024 03:27:27 -0400 Subject: [PATCH 1093/1323] [http-client] Remove http-api dependency (#439) * remove unused client dependencies * Update pom.xml * I guess applog is needed --- http-client/pom.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/http-client/pom.xml b/http-client/pom.xml index 736e2013b..40914a5b0 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -67,6 +67,7 @@ io.avaje avaje-http-api 2.6-RC1 + test From 2f792b341835f9ab8f14a1303d96a94203ae874c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Jun 2024 19:43:07 +0000 Subject: [PATCH 1094/1323] Bump nima.version from 4.0.8 to 4.0.9 Bumps `nima.version` from 4.0.8 to 4.0.9. Updates `io.helidon.webserver:helidon-webserver` from 4.0.8 to 4.0.9 Updates `io.helidon.http.media:helidon-http-media-jsonb` from 4.0.8 to 4.0.9 --- updated-dependencies: - dependency-name: io.helidon.webserver:helidon-webserver dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: io.helidon.http.media:helidon-http-media-jsonb dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- tests/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/pom.xml b/tests/pom.xml index 6203416fc..ccbe13554 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -17,7 +17,7 @@ 2.17.1 2.5 9.12 - 4.0.8 + 4.0.9 6.1.4 From b91ac93113587f0116e38f7dd8633c93481059b6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Jun 2024 19:45:27 +0000 Subject: [PATCH 1095/1323] Bump io.javalin:javalin from 6.1.4 to 6.1.6 Bumps [io.javalin:javalin](https://github.com/javalin/javalin) from 6.1.4 to 6.1.6. - [Release notes](https://github.com/javalin/javalin/releases) - [Commits](https://github.com/javalin/javalin/compare/javalin-parent-6.1.4...javalin-parent-6.1.6) --- updated-dependencies: - dependency-name: io.javalin:javalin dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- http-api/pom.xml | 2 +- http-client/pom.xml | 2 +- tests/pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/http-api/pom.xml b/http-api/pom.xml index 1837460cb..704fb8d12 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -24,7 +24,7 @@ io.javalin javalin - 6.1.4 + 6.1.6 provided true diff --git a/http-client/pom.xml b/http-client/pom.xml index 40914a5b0..7144e47f2 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -59,7 +59,7 @@ io.javalin javalin - 6.1.4 + 6.1.6 test diff --git a/tests/pom.xml b/tests/pom.xml index ccbe13554..61d79f2b6 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -18,7 +18,7 @@ 2.5 9.12 4.0.9 - 6.1.4 + 6.1.6 From f0e25cbfc44da64af0ba35570d1c79bfcfbe5201 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 10 Jun 2024 19:55:58 +0000 Subject: [PATCH 1096/1323] Bump org.avaje:java11-oss from 4.1 to 4.3 Bumps [org.avaje:java11-oss](https://github.com/avaje-pom/java11-oss) from 4.1 to 4.3. - [Release notes](https://github.com/avaje-pom/java11-oss/releases) - [Commits](https://github.com/avaje-pom/java11-oss/commits) --- updated-dependencies: - dependency-name: org.avaje:java11-oss dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index a5f16b9ec..722df381b 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ org.avaje java11-oss - 4.1 + 4.3 io.avaje From aacb71f57628788a53be8b41b0c8d37cd7feafd5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 10 Jun 2024 19:58:09 +0000 Subject: [PATCH 1097/1323] Bump io.avaje:avaje-prisms from 1.21 to 1.24 Bumps [io.avaje:avaje-prisms](https://github.com/avaje/avaje-prisms) from 1.21 to 1.24. - [Release notes](https://github.com/avaje/avaje-prisms/releases) - [Commits](https://github.com/avaje/avaje-prisms/compare/1.21...1.24) --- updated-dependencies: - dependency-name: io.avaje:avaje-prisms dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 722df381b..65a399d6f 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ true 2.2.22 2.14.2 - 1.21 + 1.24 ${project.build.directory}${file.separator}module-info.shade From 4005c280f938da409e94075548a83bd130c05b17 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Mon, 10 Jun 2024 22:05:45 -0400 Subject: [PATCH 1098/1323] Update proc note (#447) --- README.md | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index bfe8803b0..a47585153 100644 --- a/README.md +++ b/README.md @@ -47,17 +47,13 @@ Use source code generation to adapt annotated REST controllers `@Path, @Get, @Po ``` -### JDK 22+ +### JDK 23+ -In JDK 22+, annotation processors are disabled by default, you will need to add a flag to re-enable. +In JDK 23+, annotation processors are disabled by default, you will need to add a flag to re-enable. ```xml - - org.apache.maven.plugins - maven-compiler-plugin - - -proc:full - - + + full + ``` ## Define a Controller (These APT processors work with both Java and Kotlin) From 0619037ed2c5828faa3766c2e921b234411f42a2 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Fri, 14 Jun 2024 22:45:22 -0400 Subject: [PATCH 1099/1323] ea workflow --- .github/workflows/jdk-ea-stable.yml | 37 +++++++++++++++++++++++++++++ .github/workflows/jdk-ea.yml | 1 + 2 files changed, 38 insertions(+) create mode 100644 .github/workflows/jdk-ea-stable.yml diff --git a/.github/workflows/jdk-ea-stable.yml b/.github/workflows/jdk-ea-stable.yml new file mode 100644 index 000000000..9e093d9ad --- /dev/null +++ b/.github/workflows/jdk-ea-stable.yml @@ -0,0 +1,37 @@ + +name: JDK EA Stable + +on: + push: + pull_request: + workflow_dispatch: + schedule: + - cron: '39 1 * * 1,3,5' + +jobs: + build: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + + steps: + - uses: actions/checkout@v3 + - name: Set up Java + uses: oracle-actions/setup-java@v1 + with: + website: jdk.java.net + release: ea + version: stable + - name: Maven cache + uses: actions/cache@v3 + env: + cache-name: maven-cache + with: + path: + ~/.m2 + key: build-${{ env.cache-name }} + - name: Maven version + run: mvn --version + - name: Build with Maven + run: mvn clean verify package -Ptest diff --git a/.github/workflows/jdk-ea.yml b/.github/workflows/jdk-ea.yml index 6dec68f0c..7e3cdc1e3 100644 --- a/.github/workflows/jdk-ea.yml +++ b/.github/workflows/jdk-ea.yml @@ -2,6 +2,7 @@ name: avaje-http EA on: + pull_request: workflow_dispatch: schedule: - cron: '39 1 * * 2,5' From 1d5d2c5f9f8f2f0bbdb989740b073fa5a849edb8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 17 Jun 2024 19:01:30 +0000 Subject: [PATCH 1100/1323] Bump nima.version from 4.0.9 to 4.0.10 Bumps `nima.version` from 4.0.9 to 4.0.10. Updates `io.helidon.webserver:helidon-webserver` from 4.0.9 to 4.0.10 Updates `io.helidon.http.media:helidon-http-media-jsonb` from 4.0.9 to 4.0.10 --- updated-dependencies: - dependency-name: io.helidon.webserver:helidon-webserver dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: io.helidon.http.media:helidon-http-media-jsonb dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- tests/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/pom.xml b/tests/pom.xml index 61d79f2b6..b9d3ba293 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -17,7 +17,7 @@ 2.17.1 2.5 9.12 - 4.0.9 + 4.0.10 6.1.6 From 6a79172c23b92ec2b992df791ea02f36f0855018 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 17 Jun 2024 19:47:22 +0000 Subject: [PATCH 1101/1323] [workflow]: Bump actions/cache from 3 to 4 Bumps [actions/cache](https://github.com/actions/cache) from 3 to 4. - [Release notes](https://github.com/actions/cache/releases) - [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md) - [Commits](https://github.com/actions/cache/compare/v3...v4) --- updated-dependencies: - dependency-name: actions/cache dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/jdk-ea-stable.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/jdk-ea-stable.yml b/.github/workflows/jdk-ea-stable.yml index 9e093d9ad..c28613f57 100644 --- a/.github/workflows/jdk-ea-stable.yml +++ b/.github/workflows/jdk-ea-stable.yml @@ -24,7 +24,7 @@ jobs: release: ea version: stable - name: Maven cache - uses: actions/cache@v3 + uses: actions/cache@v4 env: cache-name: maven-cache with: From 9600094c9d04dadf142cf2f9256f6c27736daf58 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 17 Jun 2024 19:49:27 +0000 Subject: [PATCH 1102/1323] [workflow]: Bump actions/checkout from 3 to 4 Bumps [actions/checkout](https://github.com/actions/checkout) from 3 to 4. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v3...v4) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/jdk-ea-stable.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/jdk-ea-stable.yml b/.github/workflows/jdk-ea-stable.yml index c28613f57..a6c44f00f 100644 --- a/.github/workflows/jdk-ea-stable.yml +++ b/.github/workflows/jdk-ea-stable.yml @@ -16,7 +16,7 @@ jobs: packages: write steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Java uses: oracle-actions/setup-java@v1 with: From 38370c20cb7a700ca193128788b86e749615530b Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Thu, 20 Jun 2024 21:43:39 +1200 Subject: [PATCH 1103/1323] #452 The generator does not work when using @Produces to customize the JSON MIME type (#454) * #452 - The generator does not work when using `@Produces` to customize the JSON MIME type e.g. ``` @Produces(MediaType.APPLICATION_JSON + ";charset=UTF-8") ``` * #452 - The generator does not work when using `@Produces` to customize the JSON MIME type e.g. ``` @Produces(MediaType.APPLICATION_JSON + ";charset=UTF-8") ``` --- .../avaje/http/generator/core/JsonBUtil.java | 7 +++++- .../javalin/ControllerMethodWriter.java | 25 ++++++++++--------- .../generator/jex/ControllerMethodWriter.java | 9 +++---- .../example/myapp/web/HelloController.java | 1 + .../src/main/resources/public/openapi.json | 8 +++--- .../example/myapp/web/HelloController.java | 1 + .../src/main/resources/public/openapi.json | 2 +- 7 files changed, 29 insertions(+), 24 deletions(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java index a47923feb..212600c96 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java @@ -5,9 +5,14 @@ import java.util.function.Consumer; import java.util.stream.Collectors; -public class JsonBUtil { +public final class JsonBUtil { + private JsonBUtil() {} + public static boolean isJsonMimeType(String producesMimeType) { + return producesMimeType == null || producesMimeType.toLowerCase().contains("application/json"); + } + public static Map jsonTypes(ControllerReader reader) { final Map jsonTypes = new LinkedHashMap<>(); diff --git a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java index 3cda06122..799d67763 100644 --- a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java +++ b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java @@ -4,14 +4,7 @@ import java.util.List; -import io.avaje.http.generator.core.Append; -import io.avaje.http.generator.core.CoreWebMethod; -import io.avaje.http.generator.core.MethodParam; -import io.avaje.http.generator.core.MethodReader; -import io.avaje.http.generator.core.PathSegments; -import io.avaje.http.generator.core.UType; -import io.avaje.http.generator.core.Util; -import io.avaje.http.generator.core.WebMethod; +import io.avaje.http.generator.core.*; import io.avaje.http.generator.core.openapi.MediaType; /** Write code to register Web route for a given controller method. */ @@ -158,8 +151,9 @@ private void writeContextReturn() { } private void writeContextReturn(final String resultVariableName) { - final var produces = method.produces(); - if (produces == null || MediaType.APPLICATION_JSON.getValue().equalsIgnoreCase(produces)) { + var produces = method.produces(); + boolean applicationJson = produces == null || MediaType.APPLICATION_JSON.getValue().equalsIgnoreCase(produces); + if (applicationJson || JsonBUtil.isJsonMimeType(produces)) { if (useJsonB) { var uType = UType.parse(method.returnType()); final boolean isfuture = "java.util.concurrent.CompletableFuture".equals(uType.mainType()); @@ -169,12 +163,19 @@ private void writeContextReturn(final String resultVariableName) { } writer.append(" try {"); } - writer.append(" %sJsonType.toJson(%s, ctx.contentType(\"application/json\").res().getOutputStream());", uType.shortName(), resultVariableName); + if (produces == null) { + produces = MediaType.APPLICATION_JSON.getValue(); + } + writer.append(" %sJsonType.toJson(%s, ctx.contentType(\"%s\").res().getOutputStream());", uType.shortName(), resultVariableName, produces); if (isfuture || method.isErrorMethod()) { writer.append(" } catch (java.io.IOException e) { throw new java.io.UncheckedIOException(e); }"); } } else { - writer.append(" ctx.json(%s);", resultVariableName); + if (applicationJson) { + writer.append(" ctx.json(%s);", resultVariableName); + } else { + writer.append(" ctx.contentType(\"%s\").json(%s);", produces, resultVariableName); + } } } else if (MediaType.TEXT_HTML.getValue().equalsIgnoreCase(produces)) { writer.append(" ctx.html(%s);", resultVariableName); diff --git a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java index dc663e297..da6d99a86 100644 --- a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java +++ b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java @@ -3,12 +3,7 @@ import static io.avaje.http.generator.core.ProcessingContext.platform; import java.util.List; -import io.avaje.http.generator.core.Append; -import io.avaje.http.generator.core.MethodParam; -import io.avaje.http.generator.core.MethodReader; -import io.avaje.http.generator.core.PathSegments; -import io.avaje.http.generator.core.Util; -import io.avaje.http.generator.core.WebMethod; +import io.avaje.http.generator.core.*; import io.avaje.http.generator.core.openapi.MediaType; /** @@ -102,6 +97,8 @@ private void writeContextReturn() { writer.append("ctx.html("); } else if (produces.equalsIgnoreCase(MediaType.TEXT_PLAIN.getValue())) { writer.append("ctx.text("); + } else if (JsonBUtil.isJsonMimeType(produces)) { + writer.append("ctx.contentType(\"%s\").json(", produces); } else { writer.append("ctx.contentType(\"%s\").write(", produces); } diff --git a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/HelloController.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/HelloController.java index a918215ed..18f4df264 100644 --- a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/HelloController.java +++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/HelloController.java @@ -82,6 +82,7 @@ List findByName(String name, @QueryParam("my-param") @Default("one") S /** * Simple example post with JSON body response. */ + @Produces(MediaType.APPLICATION_JSON_PATCH_JSON) @Post HelloDto post(HelloDto dto) { dto.name = "posted"; diff --git a/tests/test-javalin-jsonb/src/main/resources/public/openapi.json b/tests/test-javalin-jsonb/src/main/resources/public/openapi.json index 087e3dd87..bb9b03bdd 100644 --- a/tests/test-javalin-jsonb/src/main/resources/public/openapi.json +++ b/tests/test-javalin-jsonb/src/main/resources/public/openapi.json @@ -1,7 +1,7 @@ { "openapi" : "3.0.1", "info" : { - "title" : "Example service showing off the Path extension method of controller", + "title" : "Example service", "description" : "Example Javalin controllers with Java and Maven", "version" : "" }, @@ -14,11 +14,11 @@ "tags" : [ { "name" : "tag1", - "description" : "this is added to openapi tags" + "description" : "it's somethin" }, { "name" : "tag1", - "description" : "it's somethin" + "description" : "this is added to openapi tags" } ], "paths" : { @@ -320,7 +320,7 @@ "201" : { "description" : "", "content" : { - "application/json" : { + "application/json-patch+json" : { "schema" : { "$ref" : "#/components/schemas/HelloDto" } diff --git a/tests/test-javalin/src/main/java/org/example/myapp/web/HelloController.java b/tests/test-javalin/src/main/java/org/example/myapp/web/HelloController.java index 4ddd454ba..bfad1c72a 100644 --- a/tests/test-javalin/src/main/java/org/example/myapp/web/HelloController.java +++ b/tests/test-javalin/src/main/java/org/example/myapp/web/HelloController.java @@ -82,6 +82,7 @@ List findByName(String name, @QueryParam("my-param") @Default("one") S /** * Simple example post with JSON body response. */ + @Produces(MediaType.APPLICATION_JSON + ";charset=UTF-8") @Post HelloDto post(HelloDto dto) { dto.name = "posted"; diff --git a/tests/test-javalin/src/main/resources/public/openapi.json b/tests/test-javalin/src/main/resources/public/openapi.json index ff158eb08..76a5ad5b4 100644 --- a/tests/test-javalin/src/main/resources/public/openapi.json +++ b/tests/test-javalin/src/main/resources/public/openapi.json @@ -310,7 +310,7 @@ "201" : { "description" : "", "content" : { - "application/json" : { + "application/json;charset=UTF-8" : { "schema" : { "$ref" : "#/components/schemas/HelloDto" } From b885da362e57f1d5040f9750c5c4d326ba6aeb88 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Thu, 20 Jun 2024 22:19:27 +1200 Subject: [PATCH 1104/1323] #453 - Compile error with nested enum type not imported in generated server code (#455) e.g. ``` public class Foo { public enum NestedEnum { A, B, C } } ``` ``` @Controller class TestController { @Post void foo(Foo.NestedEnum value) { System.out.println(value); } ``` --- .../io/avaje/http/generator/core/TypeMap.java | 4 +-- .../io/avaje/http/generator/core/UType.java | 12 +++++++ .../avaje/http/generator/core/UTypeTest.java | 9 +++++ .../example/myapp/web/HelloController.java | 7 ++++ .../java/org/example/myapp/web/other/Foo.java | 7 ++++ .../src/main/resources/public/openapi.json | 35 +++++++++++++++++++ 6 files changed, 72 insertions(+), 2 deletions(-) create mode 100644 tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/other/Foo.java diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/TypeMap.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/TypeMap.java index 1594766f2..037b69507 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/TypeMap.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/TypeMap.java @@ -316,12 +316,12 @@ static class EnumHandler extends ObjectHandler { @Override public String toMethod() { - return "(" + type.shortType() + ") toEnum(" + type.shortType() + ".class, "; + return "(" + type.shortTypeNested() + ") toEnum(" + type.shortTypeNested() + ".class, "; } @Override public String asMethod() { - return "(" + type.shortType() + ") asEnum(" + type.shortType() + ".class, "; + return "(" + type.shortTypeNested() + ") asEnum(" + type.shortTypeNested() + ".class, "; } } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java index f22658b2b..24738fdb3 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java @@ -31,6 +31,13 @@ static UType parse(String type) { */ String shortType(); + /** + * Return the short type taking nested type into account. + */ + default String shortTypeNested() { + return shortType(); + } + /** * Return the short name. */ @@ -152,6 +159,11 @@ public String shortType() { return Util.shortName(rawType); } + @Override + public String shortTypeNested() { + return Util.shortName(rawType, true); + } + @Override public String shortName() { return Util.initLower(shortType()).replace(".", "$"); diff --git a/http-generator-core/src/test/java/io/avaje/http/generator/core/UTypeTest.java b/http-generator-core/src/test/java/io/avaje/http/generator/core/UTypeTest.java index 12dea5d6d..51e79c70b 100644 --- a/http-generator-core/src/test/java/io/avaje/http/generator/core/UTypeTest.java +++ b/http-generator-core/src/test/java/io/avaje/http/generator/core/UTypeTest.java @@ -2,6 +2,7 @@ import org.junit.jupiter.api.Test; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.*; class UTypeTest { @@ -17,4 +18,12 @@ void isJavaLangPackage_expect_false() { assertFalse(UType.isJavaLangPackage("java.lang.other.Foo")); assertFalse(UType.isJavaLangPackage("not.lang.Foo")); } + + @Test + void parseNestedEnum() { + UType uType = UType.parse("my.pack.Foo.NestedEnum"); + assertThat(uType.mainType()).isEqualTo("my.pack.Foo.NestedEnum"); + assertThat(uType.shortType()).isEqualTo("Foo.NestedEnum"); + assertThat(uType.shortTypeNested()).isEqualTo("NestedEnum"); + } } diff --git a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/HelloController.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/HelloController.java index 18f4df264..fb6d8ecf5 100644 --- a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/HelloController.java +++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/HelloController.java @@ -25,6 +25,7 @@ import io.javalin.http.Context; import io.swagger.v3.oas.annotations.Hidden; import jakarta.inject.Inject; +import org.example.myapp.web.other.Foo; /** * Hello resource manager. @@ -183,4 +184,10 @@ String controlStatusCode(Context ctx) { ctx.status(201); return "controlStatusCode"; } + + @Produces(value = "text/plain") + @Get("takesNestedEnum") + String takesNestedEnum(Foo.NestedEnum myEnum) { + return "takesNestedEnum-" + myEnum; + } } diff --git a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/other/Foo.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/other/Foo.java new file mode 100644 index 000000000..f3ed0507a --- /dev/null +++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/other/Foo.java @@ -0,0 +1,7 @@ +package org.example.myapp.web.other; + +public class Foo { + public enum NestedEnum { + A, B, C + } +} diff --git a/tests/test-javalin-jsonb/src/main/resources/public/openapi.json b/tests/test-javalin-jsonb/src/main/resources/public/openapi.json index bb9b03bdd..549828b2d 100644 --- a/tests/test-javalin-jsonb/src/main/resources/public/openapi.json +++ b/tests/test-javalin-jsonb/src/main/resources/public/openapi.json @@ -646,6 +646,41 @@ } } }, + "/hello/takesNestedEnum" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "parameters" : [ + { + "name" : "myEnum", + "in" : "query", + "schema" : { + "type" : "string", + "enum" : [ + "A", + "B", + "C" + ] + } + } + ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, "/hello/withMatrix/{year_segment}/{other}" : { "get" : { "tags" : [ From 5c2ee0dc146a06ea9e964996cb9bfda76a4b6467 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Thu, 20 Jun 2024 22:25:54 +1200 Subject: [PATCH 1105/1323] Version 2.6-RC2 --- http-api-javalin/pom.xml | 2 +- http-api/pom.xml | 2 +- http-client-gson-adapter/pom.xml | 4 ++-- http-client-moshi-adapter/pom.xml | 4 ++-- http-client/pom.xml | 4 ++-- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 2 +- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-inject-plugin/pom.xml | 2 +- pom.xml | 2 +- tests/pom.xml | 2 +- tests/test-client-generation/pom.xml | 2 +- tests/test-client/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- 20 files changed, 23 insertions(+), 23 deletions(-) diff --git a/http-api-javalin/pom.xml b/http-api-javalin/pom.xml index f38b8839f..afc54dfe3 100644 --- a/http-api-javalin/pom.xml +++ b/http-api-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.6-RC1 + 2.6-RC2 .. diff --git a/http-api/pom.xml b/http-api/pom.xml index 704fb8d12..83427c7ed 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.6-RC1 + 2.6-RC2 .. diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index a2c4ff1d2..2f35cbb0b 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.6-RC1 + 2.6-RC2 avaje-http-client-gson @@ -20,7 +20,7 @@ io.avaje avaje-http-client - 2.6-RC1 + 2.6-RC2 provided diff --git a/http-client-moshi-adapter/pom.xml b/http-client-moshi-adapter/pom.xml index 93173772b..99ecf68a0 100644 --- a/http-client-moshi-adapter/pom.xml +++ b/http-client-moshi-adapter/pom.xml @@ -3,7 +3,7 @@ io.avaje avaje-http-parent - 2.6-RC1 + 2.6-RC2 avaje-http-client-moshi @@ -19,7 +19,7 @@ io.avaje avaje-http-client - 2.6-RC1 + 2.6-RC2 provided diff --git a/http-client/pom.xml b/http-client/pom.xml index 7144e47f2..d6e8df727 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.6-RC1 + 2.6-RC2 avaje-http-client @@ -66,7 +66,7 @@ io.avaje avaje-http-api - 2.6-RC1 + 2.6-RC2 test diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index 305f4aa6e..316cc747a 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.6-RC1 + 2.6-RC2 avaje-http-client-generator diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 31194e098..7acd999ae 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.6-RC1 + 2.6-RC2 avaje-http-generator-core diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index 0494b1daf..bf1e98bff 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.6-RC1 + 2.6-RC2 avaje-http-helidon-generator diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index ea9a6ae73..1fbd7a61e 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.6-RC1 + 2.6-RC2 avaje-http-javalin-generator diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index 787b49aca..27295f6c2 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.6-RC1 + 2.6-RC2 avaje-http-jex-generator diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index fc8de7fac..208214eaf 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.6-RC1 + 2.6-RC2 .. diff --git a/pom.xml b/pom.xml index 65a399d6f..38b391f54 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-parent - 2.6-RC1 + 2.6-RC2 pom diff --git a/tests/pom.xml b/tests/pom.xml index b9d3ba293..7f729efdb 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.6-RC1 + 2.6-RC2 tests diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index 049ff4b3c..fa354fd46 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.6-RC1 + 2.6-RC2 test-client-generation diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index d2d60d9da..9d42f0bbb 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.6-RC1 + 2.6-RC2 test-client diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index f45031ffb..2978328b5 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 2.6-RC1 + 2.6-RC2 test-javalin-jsonb diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 6307622f1..eb7d58c5b 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.6-RC1 + 2.6-RC2 test-javalin diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 70714c850..d13b2502d 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.6-RC1 + 2.6-RC2 test-jex diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 6b9f309a0..12d29b7df 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.6-RC1 + 2.6-RC2 test-nima-jsonb diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index 3a909037e..2d9680a63 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.6-RC1 + 2.6-RC2 test-nima From e477f136887898fc63a643684149d85da2964797 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Mon, 24 Jun 2024 04:37:07 -0400 Subject: [PATCH 1106/1323] Use avaje spi for service validation when available (#456) * use avaje spi for service validation if possible * Update pom.xml * Format changes only --------- Co-authored-by: Rob Bygrave --- .../generator/client/ClientProcessor.java | 7 +- .../http/generator/core/BaseProcessor.java | 9 ++- .../generator/core/ProcessingContext.java | 78 +++++++++---------- pom.xml | 2 +- 4 files changed, 50 insertions(+), 46 deletions(-) diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java index bfa894148..2ba487244 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java @@ -17,6 +17,7 @@ import javax.lang.model.element.Element; import javax.lang.model.element.TypeElement; +import io.avaje.http.generator.core.APContext; import io.avaje.http.generator.core.ClientPrism; import io.avaje.http.generator.core.ControllerReader; import io.avaje.http.generator.core.ImportPrism; @@ -44,6 +45,7 @@ public SourceVersion getSupportedSourceVersion() { public synchronized void init(ProcessingEnvironment processingEnv) { super.init(processingEnv); this.processingEnv = processingEnv; + APContext.init(processingEnv); ProcessingContext.init(processingEnv, new ClientPlatformAdapter(), false); this.componentWriter = new SimpleComponentWriter(metaData); useJsonB = ProcessingContext.useJsonb(); @@ -51,7 +53,7 @@ public synchronized void init(ProcessingEnvironment processingEnv) { @Override public boolean process(Set annotations, RoundEnvironment round) { - ProcessingContext.findModule(annotations, round); + APContext.setProjectModuleElement(annotations, round); final var platform = platform(); if (!(platform instanceof ClientPlatformAdapter)) { setPlatform(new ClientPlatformAdapter()); @@ -107,7 +109,8 @@ protected String writeClientAdapter(ControllerReader reader) throws IOException private void initialiseComponent() { metaData.initialiseFullName(); if (!metaData.all().isEmpty()) { - ProcessingContext.validateModule(metaData.fullName()); + ProcessingContext.addClientComponent(metaData.fullName()); + ProcessingContext.validateModule(); } try { componentWriter.init(); diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java index 595014b7a..485835fa3 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java @@ -22,6 +22,11 @@ import javax.lang.model.element.TypeElement; import javax.lang.model.util.ElementFilter; +import io.avaje.prism.GenerateAPContext; +import io.avaje.prism.GenerateModuleInfoReader; + +@GenerateAPContext +@GenerateModuleInfoReader @SupportedOptions({"useJavax", "useSingleton", "instrumentRequests","disableDirectWrites"}) public abstract class BaseProcessor extends AbstractProcessor { @@ -42,6 +47,7 @@ public Set getSupportedAnnotationTypes() { @Override public synchronized void init(ProcessingEnvironment processingEnv) { super.init(processingEnv); + APContext.init(processingEnv); ProcessingContext.init(processingEnv, providePlatformAdapter()); } @@ -51,7 +57,7 @@ public synchronized void init(ProcessingEnvironment processingEnv) { @Override public boolean process(Set annotations, RoundEnvironment round) { var pathElements = round.getElementsAnnotatedWith(typeElement(PathPrism.PRISM_TYPE)); - + APContext.setProjectModuleElement(annotations, round); if (contextPathString == null) { contextPathString = ElementFilter.modulesIn(pathElements).stream() @@ -79,6 +85,7 @@ public boolean process(Set annotations, RoundEnvironment if (round.processingOver()) { writeOpenAPI(); + ProcessingContext.validateModule(); } return false; } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java index f99a34b16..6cab59ba9 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java @@ -1,22 +1,17 @@ package io.avaje.http.generator.core; -import java.io.BufferedReader; import java.io.IOException; -import java.io.InputStreamReader; import java.net.URI; import java.nio.file.Paths; -import java.util.Collection; import java.util.List; import java.util.Objects; import java.util.Optional; -import java.util.Set; import java.util.stream.Collectors; import java.util.stream.Stream; import javax.annotation.processing.Filer; import javax.annotation.processing.Messager; import javax.annotation.processing.ProcessingEnvironment; -import javax.annotation.processing.RoundEnvironment; import javax.lang.model.element.Element; import javax.lang.model.element.ExecutableElement; import javax.lang.model.element.ModuleElement; @@ -31,6 +26,7 @@ import javax.tools.JavaFileObject; import javax.tools.StandardLocation; +import io.avaje.http.generator.core.ModuleInfoReader.Provides; import io.avaje.http.generator.core.openapi.DocContext; public final class ProcessingContext { @@ -53,8 +49,9 @@ private static final class Ctx { private final boolean instrumentAllMethods; private final boolean disableDirectWrites; private final boolean javalin6; - private ModuleElement module; + private final boolean spiPresent = APContext.typeElement("io.avaje.spi.internal.ServiceProcessor") != null; private boolean validated; + private String clientFQN; Ctx(ProcessingEnvironment env, PlatformAdapter adapter, boolean generateOpenAPI) { readAdapter = adapter; @@ -146,7 +143,12 @@ public static JavaFileObject createWriter(String cls, Element origin) throws IOE /** Create a file writer for the META-INF services file. */ public static FileObject createMetaInfWriter(String target) throws IOException { - return CTX.get().filer.createResource(StandardLocation.CLASS_OUTPUT, "", target); + var serviceFile = + CTX.get().spiPresent + ? target.replace("META-INF/services/", "META-INF/generated-services/") + : target; + + return filer().createResource(StandardLocation.CLASS_OUTPUT, "", serviceFile); } public static JavaFileObject createWriter(String cls) throws IOException { @@ -175,7 +177,7 @@ public static List superMethods(Element element, String metho .filter(type -> !type.toString().contains("java.lang.Object")) .map(superType -> { final var superClass = (TypeElement) types.asElement(superType); - for (final ExecutableElement method : ElementFilter.methodsIn(CTX.get().elementUtils.getAllMembers(superClass))) { + for (final var method : ElementFilter.methodsIn(CTX.get().elementUtils.getAllMembers(superClass))) { if (method.getSimpleName().contentEquals(methodName)) { return method; } @@ -231,45 +233,33 @@ public static boolean isAssignable2Interface(String type, String superType) { static Stream superTypes(Element element) { final Types types = CTX.get().typeUtils; return types.directSupertypes(element.asType()).stream() - .filter(type -> !type.toString().contains("java.lang.Object")) - .map(superType -> (TypeElement) types.asElement(superType)) - .flatMap(e -> Stream.concat(superTypes(e), Stream.of(e))) - .map(Object::toString); - } - - public static void findModule(Set annotations, RoundEnvironment roundEnv) { - if (CTX.get().module == null) { - CTX.get().module = - annotations.stream() - .map(roundEnv::getElementsAnnotatedWith) - .flatMap(Collection::stream) - .findAny() - .map(ProcessingContext::getModuleElement) - .orElse(null); - } + .filter(type -> !type.toString().contains("java.lang.Object")) + .map(superType -> (TypeElement) types.asElement(superType)) + .flatMap(e -> Stream.concat(superTypes(e), Stream.of(e))) + .map(Object::toString); } - public static void validateModule(String fqn) { - var module = CTX.get().module; + public static void validateModule() { + var module = APContext.getProjectModuleElement(); if (module != null && !CTX.get().validated && !module.isUnnamed()) { - CTX.get().validated = true; - try (var inputStream = - CTX.get() - .filer - .getResource(StandardLocation.SOURCE_PATH, "", "module-info.java") - .toUri() - .toURL() - .openStream(); - var reader = new BufferedReader(new InputStreamReader(inputStream))) { - - var noProvides = reader.lines().map(s -> { - if (s.contains("io.avaje.http.api.javalin") && !s.contains("static")) { - logWarn("io.avaje.http.api.javalin only contains SOURCE retention annotations. It should added as `requires static`"); - } - return s; - }) + try (var bufferedReader = APContext.getModuleInfoReader()) { + var reader = new ModuleInfoReader(module, bufferedReader); + reader.requires().forEach(r -> { + if (!r.isStatic() && r.getDependency().getQualifiedName().contentEquals("io.avaje.http.api.javalin")) { + logWarn(module, "io.avaje.http.api.javalin only contains SOURCE retention annotations. It should added as `requires static`"); + } + }); + var fqn = CTX.get().clientFQN; + if (CTX.get().spiPresent || fqn == null) { + return; + } + var noProvides = reader.provides().stream() + .filter(p -> "io.avaje.http.client.HttpClient.GeneratedComponent".equals(p.service())) + .map(Provides::implementations) + .flatMap(List::stream) .noneMatch(s -> s.contains(fqn)); + if (noProvides && !buildPluginAvailable()) { logError(module, "Missing `provides io.avaje.http.client.HttpClient.GeneratedComponent with %s;`", fqn); } @@ -309,4 +299,8 @@ private static boolean resourceExists(String relativeName) { return false; } } + + public static void addClientComponent(String clientFQN) { + CTX.get().clientFQN = clientFQN; + } } diff --git a/pom.xml b/pom.xml index 38b391f54..e82b7fe20 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ true 2.2.22 2.14.2 - 1.24 + 1.25 ${project.build.directory}${file.separator}module-info.shade From 44285f3eda1f2c95d1016e04beb7358f182a22f3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 24 Jun 2024 19:39:57 +0000 Subject: [PATCH 1107/1323] Bump io.avaje:avaje-prisms from 1.25 to 1.26 Bumps [io.avaje:avaje-prisms](https://github.com/avaje/avaje-prisms) from 1.25 to 1.26. - [Release notes](https://github.com/avaje/avaje-prisms/releases) - [Commits](https://github.com/avaje/avaje-prisms/compare/1.25...1.26) --- updated-dependencies: - dependency-name: io.avaje:avaje-prisms dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index e82b7fe20..6f2aabc4f 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ true 2.2.22 2.14.2 - 1.25 + 1.26 ${project.build.directory}${file.separator}module-info.shade From be5ae7b7d60321fefcc64924c4ddc8fc580e64fb Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Tue, 25 Jun 2024 19:01:28 -0400 Subject: [PATCH 1108/1323] use prisms to validate modules (#458) --- .../generator/core/ProcessingContext.java | 28 ++++--------------- pom.xml | 2 +- 2 files changed, 7 insertions(+), 23 deletions(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java index 6cab59ba9..f15a9ebc0 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java @@ -6,6 +6,7 @@ import java.util.List; import java.util.Objects; import java.util.Optional; +import java.util.Set; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -26,7 +27,6 @@ import javax.tools.JavaFileObject; import javax.tools.StandardLocation; -import io.avaje.http.generator.core.ModuleInfoReader.Provides; import io.avaje.http.generator.core.openapi.DocContext; public final class ProcessingContext { @@ -49,8 +49,6 @@ private static final class Ctx { private final boolean instrumentAllMethods; private final boolean disableDirectWrites; private final boolean javalin6; - private final boolean spiPresent = APContext.typeElement("io.avaje.spi.internal.ServiceProcessor") != null; - private boolean validated; private String clientFQN; Ctx(ProcessingEnvironment env, PlatformAdapter adapter, boolean generateOpenAPI) { @@ -143,12 +141,8 @@ public static JavaFileObject createWriter(String cls, Element origin) throws IOE /** Create a file writer for the META-INF services file. */ public static FileObject createMetaInfWriter(String target) throws IOException { - var serviceFile = - CTX.get().spiPresent - ? target.replace("META-INF/services/", "META-INF/generated-services/") - : target; - return filer().createResource(StandardLocation.CLASS_OUTPUT, "", serviceFile); + return filer().createResource(StandardLocation.CLASS_OUTPUT, "", target); } public static JavaFileObject createWriter(String cls) throws IOException { @@ -241,8 +235,7 @@ static Stream superTypes(Element element) { public static void validateModule() { var module = APContext.getProjectModuleElement(); - if (module != null && !CTX.get().validated && !module.isUnnamed()) { - CTX.get().validated = true; + if (module != null && !module.isUnnamed()) { try (var bufferedReader = APContext.getModuleInfoReader()) { var reader = new ModuleInfoReader(module, bufferedReader); reader.requires().forEach(r -> { @@ -251,18 +244,9 @@ public static void validateModule() { } }); var fqn = CTX.get().clientFQN; - if (CTX.get().spiPresent || fqn == null) { - return; - } - var noProvides = reader.provides().stream() - .filter(p -> "io.avaje.http.client.HttpClient.GeneratedComponent".equals(p.service())) - .map(Provides::implementations) - .flatMap(List::stream) - .noneMatch(s -> s.contains(fqn)); - - if (noProvides && !buildPluginAvailable()) { - logError(module, "Missing `provides io.avaje.http.client.HttpClient.GeneratedComponent with %s;`", fqn); - } + + reader.validateServices("io.avaje.http.client.HttpClient.GeneratedComponent", Set.of(fqn)); + } catch (Exception e) { // can't read module } diff --git a/pom.xml b/pom.xml index 6f2aabc4f..36d1e56a0 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ true 2.2.22 2.14.2 - 1.26 + 1.27 ${project.build.directory}${file.separator}module-info.shade From 2d6d5cd064960affc8b55ef9fa288a93c543a0f3 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Wed, 26 Jun 2024 17:40:50 +1200 Subject: [PATCH 1109/1323] Version 2.6 --- http-api-javalin/pom.xml | 2 +- http-api/pom.xml | 2 +- http-client-gson-adapter/pom.xml | 4 ++-- http-client-moshi-adapter/pom.xml | 4 ++-- http-client/pom.xml | 4 ++-- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 2 +- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-inject-plugin/pom.xml | 2 +- pom.xml | 2 +- tests/pom.xml | 2 +- tests/test-client-generation/pom.xml | 2 +- tests/test-client/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- 20 files changed, 23 insertions(+), 23 deletions(-) diff --git a/http-api-javalin/pom.xml b/http-api-javalin/pom.xml index afc54dfe3..40cb40957 100644 --- a/http-api-javalin/pom.xml +++ b/http-api-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.6-RC2 + 2.6 .. diff --git a/http-api/pom.xml b/http-api/pom.xml index 83427c7ed..1b12be119 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.6-RC2 + 2.6 .. diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index 2f35cbb0b..c13e087d6 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.6-RC2 + 2.6 avaje-http-client-gson @@ -20,7 +20,7 @@ io.avaje avaje-http-client - 2.6-RC2 + 2.6 provided diff --git a/http-client-moshi-adapter/pom.xml b/http-client-moshi-adapter/pom.xml index 99ecf68a0..20a151454 100644 --- a/http-client-moshi-adapter/pom.xml +++ b/http-client-moshi-adapter/pom.xml @@ -3,7 +3,7 @@ io.avaje avaje-http-parent - 2.6-RC2 + 2.6 avaje-http-client-moshi @@ -19,7 +19,7 @@ io.avaje avaje-http-client - 2.6-RC2 + 2.6 provided diff --git a/http-client/pom.xml b/http-client/pom.xml index d6e8df727..822d5807e 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.6-RC2 + 2.6 avaje-http-client @@ -66,7 +66,7 @@ io.avaje avaje-http-api - 2.6-RC2 + 2.6 test diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index 316cc747a..b15c4e49b 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.6-RC2 + 2.6 avaje-http-client-generator diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 7acd999ae..290d21487 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.6-RC2 + 2.6 avaje-http-generator-core diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index bf1e98bff..10b2ec246 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.6-RC2 + 2.6 avaje-http-helidon-generator diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index 1fbd7a61e..01c87dd9a 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.6-RC2 + 2.6 avaje-http-javalin-generator diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index 27295f6c2..6e81bfc97 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.6-RC2 + 2.6 avaje-http-jex-generator diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index 208214eaf..dce01eb0a 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.6-RC2 + 2.6 .. diff --git a/pom.xml b/pom.xml index 36d1e56a0..e13bb33ec 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-parent - 2.6-RC2 + 2.6 pom diff --git a/tests/pom.xml b/tests/pom.xml index 7f729efdb..05a44921d 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.6-RC2 + 2.6 tests diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index fa354fd46..479ce1f1e 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.6-RC2 + 2.6 test-client-generation diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index 9d42f0bbb..20b60b03e 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.6-RC2 + 2.6 test-client diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 2978328b5..ab9d8af61 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 2.6-RC2 + 2.6 test-javalin-jsonb diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index eb7d58c5b..037db37f5 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.6-RC2 + 2.6 test-javalin diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index d13b2502d..d9b36affe 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.6-RC2 + 2.6 test-jex diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 12d29b7df..45d42f4fc 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.6-RC2 + 2.6 test-nima-jsonb diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index 2d9680a63..c38763988 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.6-RC2 + 2.6 test-nima From ea9e46880194ca663e3bb446797582ca24f65eb5 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Wed, 26 Jun 2024 17:41:26 +1200 Subject: [PATCH 1110/1323] Bump to next snapshot --- http-api-javalin/pom.xml | 2 +- http-api/pom.xml | 2 +- http-client-gson-adapter/pom.xml | 4 ++-- http-client-moshi-adapter/pom.xml | 4 ++-- http-client/pom.xml | 4 ++-- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 2 +- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-inject-plugin/pom.xml | 2 +- pom.xml | 2 +- tests/pom.xml | 2 +- tests/test-client-generation/pom.xml | 2 +- tests/test-client/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- 20 files changed, 23 insertions(+), 23 deletions(-) diff --git a/http-api-javalin/pom.xml b/http-api-javalin/pom.xml index 40cb40957..9d52bc92d 100644 --- a/http-api-javalin/pom.xml +++ b/http-api-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.6 + 2.7-SNAPSHOT .. diff --git a/http-api/pom.xml b/http-api/pom.xml index 1b12be119..60bf18d76 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.6 + 2.7-SNAPSHOT .. diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index c13e087d6..5ac5b4c05 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.6 + 2.7-SNAPSHOT avaje-http-client-gson @@ -20,7 +20,7 @@ io.avaje avaje-http-client - 2.6 + 2.7-SNAPSHOT provided diff --git a/http-client-moshi-adapter/pom.xml b/http-client-moshi-adapter/pom.xml index 20a151454..a22e41891 100644 --- a/http-client-moshi-adapter/pom.xml +++ b/http-client-moshi-adapter/pom.xml @@ -3,7 +3,7 @@ io.avaje avaje-http-parent - 2.6 + 2.7-SNAPSHOT avaje-http-client-moshi @@ -19,7 +19,7 @@ io.avaje avaje-http-client - 2.6 + 2.7-SNAPSHOT provided diff --git a/http-client/pom.xml b/http-client/pom.xml index 822d5807e..e7eb57aa1 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.6 + 2.7-SNAPSHOT avaje-http-client @@ -66,7 +66,7 @@ io.avaje avaje-http-api - 2.6 + 2.7-SNAPSHOT test diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index b15c4e49b..cc906a76f 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.6 + 2.7-SNAPSHOT avaje-http-client-generator diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 290d21487..a9a13ad6d 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.6 + 2.7-SNAPSHOT avaje-http-generator-core diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index 10b2ec246..b4b49849a 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.6 + 2.7-SNAPSHOT avaje-http-helidon-generator diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index 01c87dd9a..5bb515f57 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.6 + 2.7-SNAPSHOT avaje-http-javalin-generator diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index 6e81bfc97..6271a0908 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.6 + 2.7-SNAPSHOT avaje-http-jex-generator diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index dce01eb0a..babbd7470 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.6 + 2.7-SNAPSHOT .. diff --git a/pom.xml b/pom.xml index e13bb33ec..7e9066f9e 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-parent - 2.6 + 2.7-SNAPSHOT pom diff --git a/tests/pom.xml b/tests/pom.xml index 05a44921d..25b08684f 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.6 + 2.7-SNAPSHOT tests diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index 479ce1f1e..3e5bb87fb 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.6 + 2.7-SNAPSHOT test-client-generation diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index 20b60b03e..cc226f862 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.6 + 2.7-SNAPSHOT test-client diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index ab9d8af61..37fa3206d 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 2.6 + 2.7-SNAPSHOT test-javalin-jsonb diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 037db37f5..cc7c555fe 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.6 + 2.7-SNAPSHOT test-javalin diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index d9b36affe..4c187c2d2 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.6 + 2.7-SNAPSHOT test-jex diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 45d42f4fc..9b90aa2e5 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.6 + 2.7-SNAPSHOT test-nima-jsonb diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index c38763988..59d2ba44b 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.6 + 2.7-SNAPSHOT test-nima From 6345352532a2cc7049abdd4cb567b40fc167a63e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Jul 2024 19:41:26 +0000 Subject: [PATCH 1111/1323] Bump junit.version from 5.10.2 to 5.10.3 Bumps `junit.version` from 5.10.2 to 5.10.3. Updates `org.junit.jupiter:junit-jupiter-api` from 5.10.2 to 5.10.3 - [Release notes](https://github.com/junit-team/junit5/releases) - [Commits](https://github.com/junit-team/junit5/compare/r5.10.2...r5.10.3) Updates `org.junit.jupiter:junit-jupiter-engine` from 5.10.2 to 5.10.3 - [Release notes](https://github.com/junit-team/junit5/releases) - [Commits](https://github.com/junit-team/junit5/compare/r5.10.2...r5.10.3) --- updated-dependencies: - dependency-name: org.junit.jupiter:junit-jupiter-api dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: org.junit.jupiter:junit-jupiter-engine dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- tests/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/pom.xml b/tests/pom.xml index 25b08684f..4c2c1179e 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -12,7 +12,7 @@ true - 5.10.2 + 5.10.3 3.26.0 2.17.1 2.5 From ec9cb063ed1cc4fdceb0d07b82f02685f7362b61 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Jul 2024 19:43:22 +0000 Subject: [PATCH 1112/1323] Bump io.avaje:avaje-jsonb from 1.11 to 1.12 Bumps [io.avaje:avaje-jsonb](https://github.com/avaje/avaje-jsonb) from 1.11 to 1.12. - [Release notes](https://github.com/avaje/avaje-jsonb/releases) - [Commits](https://github.com/avaje/avaje-jsonb/compare/1.11...1.12) --- updated-dependencies: - dependency-name: io.avaje:avaje-jsonb dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- http-client/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/http-client/pom.xml b/http-client/pom.xml index e7eb57aa1..b3e1df9c8 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -36,7 +36,7 @@ io.avaje avaje-jsonb - 1.11 + 1.12 true diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 37fa3206d..bf6312658 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -80,7 +80,7 @@ io.avaje avaje-jsonb - 1.11 + 1.12 diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 9b90aa2e5..4c574c3e9 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -31,7 +31,7 @@ io.avaje avaje-jsonb - 1.11 + 1.12 io.avaje From 85b1d3facc88de6fc19d4289f6b6ff0b60372263 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Jul 2024 19:45:18 +0000 Subject: [PATCH 1113/1323] Bump io.avaje:avaje-jsonb-generator from 1.11 to 1.12 Bumps io.avaje:avaje-jsonb-generator from 1.11 to 1.12. --- updated-dependencies: - dependency-name: io.avaje:avaje-jsonb-generator dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index bf6312658..9d39db6a6 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -86,7 +86,7 @@ io.avaje avaje-jsonb-generator - 1.11 + 1.12 provided diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 4c574c3e9..3259d44a1 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -90,7 +90,7 @@ io.avaje avaje-jsonb-generator - 1.11 + 1.12 From 8698c39a84c682af346e0c6946354e2c53fdf908 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Jul 2024 19:49:31 +0000 Subject: [PATCH 1114/1323] Bump io.rest-assured:rest-assured from 5.4.0 to 5.5.0 Bumps [io.rest-assured:rest-assured](https://github.com/rest-assured/rest-assured) from 5.4.0 to 5.5.0. - [Changelog](https://github.com/rest-assured/rest-assured/blob/master/changelog.txt) - [Commits](https://github.com/rest-assured/rest-assured/compare/rest-assured-5.4.0...rest-assured-5.5.0) --- updated-dependencies: - dependency-name: io.rest-assured:rest-assured dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 9d39db6a6..087d6bba5 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -101,7 +101,7 @@ io.rest-assured rest-assured - 5.4.0 + 5.5.0 test diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index cc7c555fe..8b4e2a6e2 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -94,7 +94,7 @@ io.rest-assured rest-assured - 5.4.0 + 5.5.0 test From f19146557e207821263d86808b0ba7aeeba3025a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Jul 2024 19:51:10 +0000 Subject: [PATCH 1115/1323] Bump com.fasterxml.jackson.core:jackson-databind from 2.17.1 to 2.17.2 Bumps [com.fasterxml.jackson.core:jackson-databind](https://github.com/FasterXML/jackson) from 2.17.1 to 2.17.2. - [Commits](https://github.com/FasterXML/jackson/commits) --- updated-dependencies: - dependency-name: com.fasterxml.jackson.core:jackson-databind dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- http-client/pom.xml | 2 +- tests/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/http-client/pom.xml b/http-client/pom.xml index b3e1df9c8..87cca63e1 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -29,7 +29,7 @@ com.fasterxml.jackson.core jackson-databind - 2.17.1 + 2.17.2 true diff --git a/tests/pom.xml b/tests/pom.xml index 4c2c1179e..43e395e85 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -14,7 +14,7 @@ true 5.10.3 3.26.0 - 2.17.1 + 2.17.2 2.5 9.12 4.0.10 From 88effbd84b776f38f17990daf933b94949bdb9cc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Jul 2024 19:53:05 +0000 Subject: [PATCH 1116/1323] Bump io.avaje:avaje-prisms from 1.27 to 1.28 Bumps [io.avaje:avaje-prisms](https://github.com/avaje/avaje-prisms) from 1.27 to 1.28. - [Release notes](https://github.com/avaje/avaje-prisms/releases) - [Commits](https://github.com/avaje/avaje-prisms/compare/1.27...1.28) --- updated-dependencies: - dependency-name: io.avaje:avaje-prisms dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 7e9066f9e..24bc5608d 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ true 2.2.22 2.14.2 - 1.27 + 1.28 ${project.build.directory}${file.separator}module-info.shade From 0fd3277b04c220c5380708b257913f47ed53f73c Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Wed, 10 Jul 2024 21:17:22 +1200 Subject: [PATCH 1117/1323] Version 2.7 --- http-api-javalin/pom.xml | 2 +- http-api/pom.xml | 2 +- http-client-gson-adapter/pom.xml | 4 ++-- http-client-moshi-adapter/pom.xml | 4 ++-- http-client/pom.xml | 4 ++-- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 2 +- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-inject-plugin/pom.xml | 2 +- pom.xml | 2 +- tests/pom.xml | 2 +- tests/test-client-generation/pom.xml | 2 +- tests/test-client/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- 20 files changed, 23 insertions(+), 23 deletions(-) diff --git a/http-api-javalin/pom.xml b/http-api-javalin/pom.xml index 9d52bc92d..ac78d243d 100644 --- a/http-api-javalin/pom.xml +++ b/http-api-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.7-SNAPSHOT + 2.7 .. diff --git a/http-api/pom.xml b/http-api/pom.xml index 60bf18d76..14980b37a 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.7-SNAPSHOT + 2.7 .. diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index 5ac5b4c05..87d5d4fd0 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.7-SNAPSHOT + 2.7 avaje-http-client-gson @@ -20,7 +20,7 @@ io.avaje avaje-http-client - 2.7-SNAPSHOT + 2.7 provided diff --git a/http-client-moshi-adapter/pom.xml b/http-client-moshi-adapter/pom.xml index a22e41891..e0e01a110 100644 --- a/http-client-moshi-adapter/pom.xml +++ b/http-client-moshi-adapter/pom.xml @@ -3,7 +3,7 @@ io.avaje avaje-http-parent - 2.7-SNAPSHOT + 2.7 avaje-http-client-moshi @@ -19,7 +19,7 @@ io.avaje avaje-http-client - 2.7-SNAPSHOT + 2.7 provided diff --git a/http-client/pom.xml b/http-client/pom.xml index 87cca63e1..1cb4dd67c 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.7-SNAPSHOT + 2.7 avaje-http-client @@ -66,7 +66,7 @@ io.avaje avaje-http-api - 2.7-SNAPSHOT + 2.7 test diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index cc906a76f..85186fad1 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.7-SNAPSHOT + 2.7 avaje-http-client-generator diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index a9a13ad6d..817ca4211 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.7-SNAPSHOT + 2.7 avaje-http-generator-core diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index b4b49849a..3d5349a21 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.7-SNAPSHOT + 2.7 avaje-http-helidon-generator diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index 5bb515f57..396494614 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.7-SNAPSHOT + 2.7 avaje-http-javalin-generator diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index 6271a0908..ebd49a795 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.7-SNAPSHOT + 2.7 avaje-http-jex-generator diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index babbd7470..1563ddc4f 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.7-SNAPSHOT + 2.7 .. diff --git a/pom.xml b/pom.xml index 24bc5608d..ed308983a 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-parent - 2.7-SNAPSHOT + 2.7 pom diff --git a/tests/pom.xml b/tests/pom.xml index 43e395e85..fe5e6be0d 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.7-SNAPSHOT + 2.7 tests diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index 3e5bb87fb..ee5c1e62c 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.7-SNAPSHOT + 2.7 test-client-generation diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index cc226f862..f0750b0fb 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.7-SNAPSHOT + 2.7 test-client diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 087d6bba5..54aa5f468 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 2.7-SNAPSHOT + 2.7 test-javalin-jsonb diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 8b4e2a6e2..d2e89b31e 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.7-SNAPSHOT + 2.7 test-javalin diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 4c187c2d2..e93722d1b 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.7-SNAPSHOT + 2.7 test-jex diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 3259d44a1..645ef853a 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.7-SNAPSHOT + 2.7 test-nima-jsonb diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index 59d2ba44b..a27501e10 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.7-SNAPSHOT + 2.7 test-nima From f368e2ad990a1d512830fa5afd06fd64889adff0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 Jul 2024 19:32:44 +0000 Subject: [PATCH 1118/1323] Bump avaje-inject.version from 9.12 to 10.0 Bumps `avaje-inject.version` from 9.12 to 10.0. Updates `io.avaje:avaje-inject` from 9.12 to 10.0 - [Release notes](https://github.com/avaje/avaje-inject/releases) - [Commits](https://github.com/avaje/avaje-inject/compare/9.12...10.0) Updates `io.avaje:avaje-inject-generator` from 9.12 to 10.0 --- updated-dependencies: - dependency-name: io.avaje:avaje-inject dependency-type: direct:production update-type: version-update:semver-major - dependency-name: io.avaje:avaje-inject-generator dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- http-client/pom.xml | 4 ++-- http-inject-plugin/pom.xml | 2 +- tests/pom.xml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/http-client/pom.xml b/http-client/pom.xml index 1cb4dd67c..a824705c5 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -43,7 +43,7 @@ io.avaje avaje-inject - 9.12 + 10.0 true @@ -99,7 +99,7 @@ io.avaje avaje-inject-generator - 9.12 + 10.0 diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index 1563ddc4f..c62ab590d 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -19,7 +19,7 @@ io.avaje avaje-inject - 9.12 + 10.0 provided true diff --git a/tests/pom.xml b/tests/pom.xml index fe5e6be0d..ec4abdcc5 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -16,7 +16,7 @@ 3.26.0 2.17.2 2.5 - 9.12 + 10.0 4.0.10 6.1.6 From 009d2f860a2ad9cd362b2dfb5a128d0283d63ad2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 Jul 2024 19:35:00 +0000 Subject: [PATCH 1119/1323] Bump org.assertj:assertj-core from 3.26.0 to 3.26.3 Bumps [org.assertj:assertj-core](https://github.com/assertj/assertj) from 3.26.0 to 3.26.3. - [Release notes](https://github.com/assertj/assertj/releases) - [Commits](https://github.com/assertj/assertj/compare/assertj-build-3.26.0...assertj-build-3.26.3) --- updated-dependencies: - dependency-name: org.assertj:assertj-core dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- tests/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/pom.xml b/tests/pom.xml index ec4abdcc5..8f4fc5cd3 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -13,7 +13,7 @@ true 5.10.3 - 3.26.0 + 3.26.3 2.17.2 2.5 10.0 From 604dd3cd5258d58c793dec8598d15753ccde2bee Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 Jul 2024 19:37:17 +0000 Subject: [PATCH 1120/1323] Bump io.avaje:avaje-inject-maven-plugin from 1.2 to 10.0 Bumps io.avaje:avaje-inject-maven-plugin from 1.2 to 10.0. --- updated-dependencies: - dependency-name: io.avaje:avaje-inject-maven-plugin dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- tests/test-nima-jsonb/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 645ef853a..ad9568afe 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -109,7 +109,7 @@ io.avaje avaje-inject-maven-plugin - 1.2 + 10.0 process-sources From e6dfe89f87e04919d744bd976f48e8eba36d3f0b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 Jul 2024 19:39:41 +0000 Subject: [PATCH 1121/1323] Bump io.avaje:avaje-jsonb from 1.12 to 2.0 Bumps [io.avaje:avaje-jsonb](https://github.com/avaje/avaje-jsonb) from 1.12 to 2.0. - [Release notes](https://github.com/avaje/avaje-jsonb/releases) - [Commits](https://github.com/avaje/avaje-jsonb/compare/1.12...2.0) --- updated-dependencies: - dependency-name: io.avaje:avaje-jsonb dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- http-client/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/http-client/pom.xml b/http-client/pom.xml index a824705c5..1a59e62de 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -36,7 +36,7 @@ io.avaje avaje-jsonb - 1.12 + 2.0 true diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 54aa5f468..03cbcadbd 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -80,7 +80,7 @@ io.avaje avaje-jsonb - 1.12 + 2.0 diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index ad9568afe..40e116799 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -31,7 +31,7 @@ io.avaje avaje-jsonb - 1.12 + 2.0 io.avaje From ff7c8f1e90bdc61e55a4a0747dc388e73a5a84e6 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Mon, 15 Jul 2024 16:31:57 -0400 Subject: [PATCH 1122/1323] bump generator --- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 03cbcadbd..bfd2059d7 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -86,7 +86,7 @@ io.avaje avaje-jsonb-generator - 1.12 + 2.0 provided diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 40e116799..b9a77740a 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -90,7 +90,7 @@ io.avaje avaje-jsonb-generator - 1.12 + 2.0 From 31960571ec3e0101507f7e3bfb818a0b893442a1 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Mon, 15 Jul 2024 16:35:03 -0400 Subject: [PATCH 1123/1323] Update JavalinProcessorTest.java --- .../avaje/http/generator/JavalinProcessorTest.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/JavalinProcessorTest.java b/tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/JavalinProcessorTest.java index cc5441088..b2262c874 100644 --- a/tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/JavalinProcessorTest.java +++ b/tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/JavalinProcessorTest.java @@ -25,7 +25,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import io.avaje.http.generator.javalin.JavalinProcessor; -import io.avaje.jsonb.generator.Processor; +import io.avaje.jsonb.generator.JsonbProcessor; class JavalinProcessorTest { @@ -76,7 +76,7 @@ public void runAnnotationProcessorJsonB() throws Exception { final var task = compiler.getTask( new PrintWriter(System.out), null, null, List.of("--release=11"), null, files); - task.setProcessors(List.of(new JavalinProcessor(), new Processor())); + task.setProcessors(List.of(new JavalinProcessor(), new JsonbProcessor())); assertThat(task.call()).isTrue(); assert Files.readString( @@ -104,7 +104,7 @@ public void runAnnotationProcessorJavax() throws Exception { "-AdisableDirectWrites=true"), null, files); - task.setProcessors(List.of(new JavalinProcessor(), new Processor())); + task.setProcessors(List.of(new JavalinProcessor(), new JsonbProcessor())); // we don't have javax on the cp assertThat(task.call()).isFalse(); @@ -133,7 +133,7 @@ public void runAnnotationProcessorJakarta() throws Exception { "-AdisableDirectWrites=true"), null, files); - task.setProcessors(List.of(new JavalinProcessor(), new Processor())); + task.setProcessors(List.of(new JavalinProcessor(), new JsonbProcessor())); assertThat(task.call()).isTrue(); @@ -163,7 +163,7 @@ public void testOpenAPIGeneration() throws Exception { List.of("--release=11", "-AdisableDirectWrites=true"), null, openAPIController); - task.setProcessors(List.of(new JavalinProcessor(), new Processor())); + task.setProcessors(List.of(new JavalinProcessor(), new JsonbProcessor())); assertThat(task.call()).isTrue(); @@ -197,7 +197,7 @@ public void testInheritableOpenAPIGeneration() throws Exception { List.of("--release=11", "-AdisableDirectWrites=true"), null, openAPIController); - task.setProcessors(List.of(new JavalinProcessor(), new Processor())); + task.setProcessors(List.of(new JavalinProcessor(), new JsonbProcessor())); assertThat(task.call()).isTrue(); From 6a84f9b5b11d5efe9e3de058e2626a650ff726d5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Jul 2024 19:13:57 +0000 Subject: [PATCH 1124/1323] Bump avaje-inject.version from 10.0 to 10.1 Bumps `avaje-inject.version` from 10.0 to 10.1. Updates `io.avaje:avaje-inject` from 10.0 to 10.1 - [Release notes](https://github.com/avaje/avaje-inject/releases) - [Commits](https://github.com/avaje/avaje-inject/compare/10.0...10.1) Updates `io.avaje:avaje-inject-generator` from 10.0 to 10.1 --- updated-dependencies: - dependency-name: io.avaje:avaje-inject dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: io.avaje:avaje-inject-generator dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- http-client/pom.xml | 4 ++-- http-inject-plugin/pom.xml | 2 +- tests/pom.xml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/http-client/pom.xml b/http-client/pom.xml index 1a59e62de..799ba4395 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -43,7 +43,7 @@ io.avaje avaje-inject - 10.0 + 10.1 true @@ -99,7 +99,7 @@ io.avaje avaje-inject-generator - 10.0 + 10.1 diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index c62ab590d..8d844bc42 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -19,7 +19,7 @@ io.avaje avaje-inject - 10.0 + 10.1 provided true diff --git a/tests/pom.xml b/tests/pom.xml index 8f4fc5cd3..e6ce1d2dd 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -16,7 +16,7 @@ 3.26.3 2.17.2 2.5 - 10.0 + 10.1 4.0.10 6.1.6 From 2548b73104e40e75e1307b11641727e977040feb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Jul 2024 19:16:10 +0000 Subject: [PATCH 1125/1323] Bump io.avaje:avaje-prisms from 1.28 to 1.29 Bumps [io.avaje:avaje-prisms](https://github.com/avaje/avaje-prisms) from 1.28 to 1.29. - [Release notes](https://github.com/avaje/avaje-prisms/releases) - [Commits](https://github.com/avaje/avaje-prisms/compare/1.28...1.29) --- updated-dependencies: - dependency-name: io.avaje:avaje-prisms dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ed308983a..e4f95c7a3 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ true 2.2.22 2.14.2 - 1.28 + 1.29 ${project.build.directory}${file.separator}module-info.shade From 5a4f3cf35a0c47b5b3b2cb71da462b6b0d338b3e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Jul 2024 19:18:07 +0000 Subject: [PATCH 1126/1323] Bump nima.version from 4.0.10 to 4.0.11 Bumps `nima.version` from 4.0.10 to 4.0.11. Updates `io.helidon.webserver:helidon-webserver` from 4.0.10 to 4.0.11 Updates `io.helidon.http.media:helidon-http-media-jsonb` from 4.0.10 to 4.0.11 --- updated-dependencies: - dependency-name: io.helidon.webserver:helidon-webserver dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: io.helidon.http.media:helidon-http-media-jsonb dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- tests/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/pom.xml b/tests/pom.xml index e6ce1d2dd..f1880d503 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -17,7 +17,7 @@ 2.17.2 2.5 10.1 - 4.0.10 + 4.0.11 6.1.6 From 327f622f1572d8910a99e332a960202538de6e50 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Jul 2024 19:20:03 +0000 Subject: [PATCH 1127/1323] Bump io.javalin:javalin from 6.1.6 to 6.2.0 Bumps [io.javalin:javalin](https://github.com/javalin/javalin) from 6.1.6 to 6.2.0. - [Release notes](https://github.com/javalin/javalin/releases) - [Commits](https://github.com/javalin/javalin/compare/javalin-parent-6.1.6...javalin-parent-6.2.0) --- updated-dependencies: - dependency-name: io.javalin:javalin dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- http-api/pom.xml | 2 +- http-client/pom.xml | 2 +- tests/pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/http-api/pom.xml b/http-api/pom.xml index 14980b37a..4c5548bdf 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -24,7 +24,7 @@ io.javalin javalin - 6.1.6 + 6.2.0 provided true diff --git a/http-client/pom.xml b/http-client/pom.xml index 799ba4395..78fefba5e 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -59,7 +59,7 @@ io.javalin javalin - 6.1.6 + 6.2.0 test diff --git a/tests/pom.xml b/tests/pom.xml index f1880d503..a9fcf3b12 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -18,7 +18,7 @@ 2.5 10.1 4.0.11 - 6.1.6 + 6.2.0 From a9e714892d0f6cfdde3dff956a7fa81b1bd47b68 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Jul 2024 19:22:35 +0000 Subject: [PATCH 1128/1323] Bump io.avaje:avaje-inject-maven-plugin from 10.0 to 10.1 Bumps io.avaje:avaje-inject-maven-plugin from 10.0 to 10.1. --- updated-dependencies: - dependency-name: io.avaje:avaje-inject-maven-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- tests/test-nima-jsonb/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index b9a77740a..02756bd8d 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -109,7 +109,7 @@ io.avaje avaje-inject-maven-plugin - 10.0 + 10.1 process-sources From 2a3a664741cc47086af4d5cbcb0993211d27447b Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Tue, 23 Jul 2024 00:24:48 -0400 Subject: [PATCH 1129/1323] update hibernate validator (#476) --- http-hibernate-validator/pom.xml | 8 ++++---- .../avaje/http/hibernate/validator/ValidatorProvider.java | 2 +- http-hibernate-validator/src/main/java/module-info.java | 2 +- ...ect.spi.Plugin => io.avaje.inject.spi.InjectExtension} | 0 4 files changed, 6 insertions(+), 6 deletions(-) rename http-hibernate-validator/src/main/resources/META-INF/services/{io.avaje.inject.spi.Plugin => io.avaje.inject.spi.InjectExtension} (100%) diff --git a/http-hibernate-validator/pom.xml b/http-hibernate-validator/pom.xml index 2990065c8..323d53949 100644 --- a/http-hibernate-validator/pom.xml +++ b/http-hibernate-validator/pom.xml @@ -5,12 +5,12 @@ io.avaje avaje-http-hibernate-validator - 3.5-RC3 + 3.5 org.avaje java11-oss - 3.10 + 4.3 @@ -36,14 +36,14 @@ io.avaje avaje-http-api - 2.0-RC1 + 2.6 provided io.avaje avaje-inject - 9.3 + 10.1 provided diff --git a/http-hibernate-validator/src/main/java/io/avaje/http/hibernate/validator/ValidatorProvider.java b/http-hibernate-validator/src/main/java/io/avaje/http/hibernate/validator/ValidatorProvider.java index ce2d3356a..cb8759224 100644 --- a/http-hibernate-validator/src/main/java/io/avaje/http/hibernate/validator/ValidatorProvider.java +++ b/http-hibernate-validator/src/main/java/io/avaje/http/hibernate/validator/ValidatorProvider.java @@ -6,7 +6,7 @@ /** * Plugin for avaje inject that provides a default BeanValidator instance. */ -public final class ValidatorProvider implements io.avaje.inject.spi.Plugin { +public final class ValidatorProvider implements io.avaje.inject.spi.InjectPlugin { @Override public Class[] provides() { diff --git a/http-hibernate-validator/src/main/java/module-info.java b/http-hibernate-validator/src/main/java/module-info.java index dbd4a1f54..2d1c0f6f9 100644 --- a/http-hibernate-validator/src/main/java/module-info.java +++ b/http-hibernate-validator/src/main/java/module-info.java @@ -8,5 +8,5 @@ requires io.avaje.inject; requires jakarta.validation; - provides io.avaje.inject.spi.Plugin with ValidatorProvider; + provides io.avaje.inject.spi.InjectExtension with ValidatorProvider; } diff --git a/http-hibernate-validator/src/main/resources/META-INF/services/io.avaje.inject.spi.Plugin b/http-hibernate-validator/src/main/resources/META-INF/services/io.avaje.inject.spi.InjectExtension similarity index 100% rename from http-hibernate-validator/src/main/resources/META-INF/services/io.avaje.inject.spi.Plugin rename to http-hibernate-validator/src/main/resources/META-INF/services/io.avaje.inject.spi.InjectExtension From 9a44222f014c8b69cd760cdc5b29451a9fbed02e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 29 Jul 2024 19:46:23 +0000 Subject: [PATCH 1130/1323] Bump io.avaje:avaje-prisms from 1.29 to 1.31 Bumps [io.avaje:avaje-prisms](https://github.com/avaje/avaje-prisms) from 1.29 to 1.31. - [Release notes](https://github.com/avaje/avaje-prisms/releases) - [Commits](https://github.com/avaje/avaje-prisms/compare/1.29...1.31) --- updated-dependencies: - dependency-name: io.avaje:avaje-prisms dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index e4f95c7a3..34d114bc1 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ true 2.2.22 2.14.2 - 1.29 + 1.31 ${project.build.directory}${file.separator}module-info.shade From 689efa666c91412b69579340c6044104db3c0aa4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 1 Aug 2024 11:22:23 +0000 Subject: [PATCH 1131/1323] Bump avaje-inject.version from 10.1 to 10.3 Bumps `avaje-inject.version` from 10.1 to 10.3. Updates `io.avaje:avaje-inject` from 10.1 to 10.3 - [Release notes](https://github.com/avaje/avaje-inject/releases) - [Commits](https://github.com/avaje/avaje-inject/compare/10.1...10.3) Updates `io.avaje:avaje-inject-generator` from 10.1 to 10.3 --- updated-dependencies: - dependency-name: io.avaje:avaje-inject dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: io.avaje:avaje-inject-generator dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- http-client/pom.xml | 4 ++-- http-inject-plugin/pom.xml | 2 +- tests/pom.xml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/http-client/pom.xml b/http-client/pom.xml index 78fefba5e..e88445b0d 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -43,7 +43,7 @@ io.avaje avaje-inject - 10.1 + 10.3 true @@ -99,7 +99,7 @@ io.avaje avaje-inject-generator - 10.1 + 10.3 diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index 8d844bc42..732c22b5a 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -19,7 +19,7 @@ io.avaje avaje-inject - 10.1 + 10.3 provided true diff --git a/tests/pom.xml b/tests/pom.xml index a9fcf3b12..c4173ff3a 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -16,7 +16,7 @@ 3.26.3 2.17.2 2.5 - 10.1 + 10.3 4.0.11 6.2.0 From de6e2151985e343b3aa852c6db5ab87d494afe0c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 1 Aug 2024 11:24:29 +0000 Subject: [PATCH 1132/1323] Bump io.avaje:avaje-inject-maven-plugin from 10.1 to 10.3 Bumps io.avaje:avaje-inject-maven-plugin from 10.1 to 10.3. --- updated-dependencies: - dependency-name: io.avaje:avaje-inject-maven-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- tests/test-nima-jsonb/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 02756bd8d..4684f52a4 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -109,7 +109,7 @@ io.avaje avaje-inject-maven-plugin - 10.1 + 10.3 process-sources From 7aed283d1035f08722c7cc8054e68c041cd4bcc1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 5 Aug 2024 19:48:19 +0000 Subject: [PATCH 1133/1323] Bump io.avaje:avaje-jsonb from 2.0 to 2.1 Bumps [io.avaje:avaje-jsonb](https://github.com/avaje/avaje-jsonb) from 2.0 to 2.1. - [Release notes](https://github.com/avaje/avaje-jsonb/releases) - [Commits](https://github.com/avaje/avaje-jsonb/compare/2.0...2.1) --- updated-dependencies: - dependency-name: io.avaje:avaje-jsonb dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- http-client/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/http-client/pom.xml b/http-client/pom.xml index e88445b0d..b0a81dd9a 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -36,7 +36,7 @@ io.avaje avaje-jsonb - 2.0 + 2.1 true diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index bfd2059d7..353afaf48 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -80,7 +80,7 @@ io.avaje avaje-jsonb - 2.0 + 2.1 diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 4684f52a4..571a277e5 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -31,7 +31,7 @@ io.avaje avaje-jsonb - 2.0 + 2.1 io.avaje From 650f21c6aae1a1cc2f12c0ab6d455d0789714a5d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 5 Aug 2024 19:50:31 +0000 Subject: [PATCH 1134/1323] Bump io.avaje:avaje-jsonb-generator from 2.0 to 2.1 Bumps io.avaje:avaje-jsonb-generator from 2.0 to 2.1. --- updated-dependencies: - dependency-name: io.avaje:avaje-jsonb-generator dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 353afaf48..e628758ab 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -86,7 +86,7 @@ io.avaje avaje-jsonb-generator - 2.0 + 2.1 provided diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 571a277e5..9c54fb44b 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -90,7 +90,7 @@ io.avaje avaje-jsonb-generator - 2.0 + 2.1 From a4de3ba5e412b2a70acb9f964f88b5217a4938da Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 13 Aug 2024 23:34:49 +1200 Subject: [PATCH 1135/1323] htmx: Initial add of htmx-api, htmx-nima request support and initial example (#435) * htmx: Initial add of htmx-api, htmx-nima request support and initial example * Bump parent version * Bump parent version * Conditionally build htmx-nima JDK 21+ * Add TemplateRender interface * Add Jscahe TemplateRender for @Htmx * Javadoc, tests pom fix * Bump version * Bump version * Bump htmlx versions to 2.7 --- htmx-api/pom.xml | 25 ++++ .../java/io/avaje/htmx/api/DHxRequest.java | 141 ++++++++++++++++++ .../src/main/java/io/avaje/htmx/api/Html.java | 18 +++ .../java/io/avaje/htmx/api/HtmxRequest.java | 106 +++++++++++++ .../java/io/avaje/htmx/api/HxRequest.java | 54 +++++++ htmx-api/src/main/java/module-info.java | 6 + htmx-nima-jstache/pom.xml | 47 ++++++ .../nima/jstache/DefaultTemplateProvider.java | 21 +++ .../nima/jstache/JStacheTemplateRender.java | 15 ++ .../src/main/java/module-info.java | 11 ++ .../services/io.avaje.inject.spi.Plugin | 1 + htmx-nima/pom.xml | 32 ++++ .../java/io/avaje/htmx/nima/DHxHandler.java | 50 +++++++ .../io/avaje/htmx/nima/DHxHandlerBuilder.java | 38 +++++ .../java/io/avaje/htmx/nima/HxHandler.java | 46 ++++++ .../java/io/avaje/htmx/nima/HxHeaders.java | 65 ++++++++ .../main/java/io/avaje/htmx/nima/HxReq.java | 49 ++++++ .../io/avaje/htmx/nima/TemplateRender.java | 16 ++ htmx-nima/src/main/java/module-info.java | 7 + http-generator-core/pom.xml | 8 + .../http/generator/core/ControllerReader.java | 18 ++- .../http/generator/core/MethodReader.java | 9 ++ .../http/generator/core/package-info.java | 2 + .../src/main/java/module-info.java | 1 + .../helidon/nima/ControllerMethodWriter.java | 48 ++++-- .../helidon/nima/ControllerWriter.java | 23 ++- pom.xml | 12 ++ tests/pom.xml | 1 + tests/test-nima-htmx/pom.xml | 100 +++++++++++++ .../src/main/java/org/example/htmx/Main.java | 15 ++ .../java/org/example/htmx/UIController.java | 29 ++++ .../main/java/org/example/htmx/ViewHome.java | 7 + .../main/java/org/example/htmx/ViewName.java | 13 ++ .../java/org/example/htmx/package-info.java | 4 + .../htmx/template/JstacheTemplateRender.java | 17 +++ .../resources/ui/fragments/layout.mustache | 11 ++ .../src/main/resources/ui/home.mustache | 8 + .../src/main/resources/ui/name.mustache | 6 + .../nest => htmx}/PathNestController.java | 2 +- .../{path/nest => htmx}/package-info.java | 2 +- .../org/example/path/PathTestController.java | 2 +- 41 files changed, 1067 insertions(+), 19 deletions(-) create mode 100644 htmx-api/pom.xml create mode 100644 htmx-api/src/main/java/io/avaje/htmx/api/DHxRequest.java create mode 100644 htmx-api/src/main/java/io/avaje/htmx/api/Html.java create mode 100644 htmx-api/src/main/java/io/avaje/htmx/api/HtmxRequest.java create mode 100644 htmx-api/src/main/java/io/avaje/htmx/api/HxRequest.java create mode 100644 htmx-api/src/main/java/module-info.java create mode 100644 htmx-nima-jstache/pom.xml create mode 100644 htmx-nima-jstache/src/main/java/io/avaje/htmx/nima/jstache/DefaultTemplateProvider.java create mode 100644 htmx-nima-jstache/src/main/java/io/avaje/htmx/nima/jstache/JStacheTemplateRender.java create mode 100644 htmx-nima-jstache/src/main/java/module-info.java create mode 100644 htmx-nima-jstache/src/main/resources/META-INF/services/io.avaje.inject.spi.Plugin create mode 100644 htmx-nima/pom.xml create mode 100644 htmx-nima/src/main/java/io/avaje/htmx/nima/DHxHandler.java create mode 100644 htmx-nima/src/main/java/io/avaje/htmx/nima/DHxHandlerBuilder.java create mode 100644 htmx-nima/src/main/java/io/avaje/htmx/nima/HxHandler.java create mode 100644 htmx-nima/src/main/java/io/avaje/htmx/nima/HxHeaders.java create mode 100644 htmx-nima/src/main/java/io/avaje/htmx/nima/HxReq.java create mode 100644 htmx-nima/src/main/java/io/avaje/htmx/nima/TemplateRender.java create mode 100644 htmx-nima/src/main/java/module-info.java create mode 100644 tests/test-nima-htmx/pom.xml create mode 100644 tests/test-nima-htmx/src/main/java/org/example/htmx/Main.java create mode 100644 tests/test-nima-htmx/src/main/java/org/example/htmx/UIController.java create mode 100644 tests/test-nima-htmx/src/main/java/org/example/htmx/ViewHome.java create mode 100644 tests/test-nima-htmx/src/main/java/org/example/htmx/ViewName.java create mode 100644 tests/test-nima-htmx/src/main/java/org/example/htmx/package-info.java create mode 100644 tests/test-nima-htmx/src/main/java/org/example/htmx/template/JstacheTemplateRender.java create mode 100644 tests/test-nima-htmx/src/main/resources/ui/fragments/layout.mustache create mode 100644 tests/test-nima-htmx/src/main/resources/ui/home.mustache create mode 100644 tests/test-nima-htmx/src/main/resources/ui/name.mustache rename tests/test-nima-jsonb/src/main/java/org/example/{path/nest => htmx}/PathNestController.java (92%) rename tests/test-nima-jsonb/src/main/java/org/example/{path/nest => htmx}/package-info.java (61%) diff --git a/htmx-api/pom.xml b/htmx-api/pom.xml new file mode 100644 index 000000000..ad4b7e30c --- /dev/null +++ b/htmx-api/pom.xml @@ -0,0 +1,25 @@ + + + 4.0.0 + + io.avaje + avaje-http-parent + 2.7 + + + avaje-htmx-api + + + + + + + io.avaje + avaje-lang + 1.0 + + + + diff --git a/htmx-api/src/main/java/io/avaje/htmx/api/DHxRequest.java b/htmx-api/src/main/java/io/avaje/htmx/api/DHxRequest.java new file mode 100644 index 000000000..c213b6e13 --- /dev/null +++ b/htmx-api/src/main/java/io/avaje/htmx/api/DHxRequest.java @@ -0,0 +1,141 @@ +package io.avaje.htmx.api; + +import io.avaje.lang.Nullable; + +final class DHxRequest implements HtmxRequest { + + private final boolean htmxRequest; + + private final boolean boosted; + private final String currentUrl; + private final boolean historyRestoreRequest; + private final String promptResponse; + private final String target; + private final String triggerName; + private final String triggerId; + + DHxRequest() { + this.htmxRequest = false; + this.boosted = false; + this.currentUrl = null; + this.historyRestoreRequest = false; + this.promptResponse = null; + this.target = null; + this.triggerName = null; + this.triggerId = null; + } + + DHxRequest(boolean boosted, String currentUrl, boolean historyRestoreRequest, String promptResponse, String target, String triggerName, String triggerId) { + this.htmxRequest = true; + this.boosted = boosted; + this.currentUrl = currentUrl; + this.historyRestoreRequest = historyRestoreRequest; + this.promptResponse = promptResponse; + this.target = target; + this.triggerName = triggerName; + this.triggerId = triggerId; + } + + @Override + public boolean isHtmxRequest() { + return htmxRequest; + } + + @Override + public boolean isBoosted() { + return boosted; + } + + @Nullable + @Override + public String currentUrl() { + return currentUrl; + } + + @Override + public boolean isHistoryRestoreRequest() { + return historyRestoreRequest; + } + + @Nullable + @Override + public String promptResponse() { + return promptResponse; + } + + @Nullable + @Override + public String target() { + return target; + } + + @Nullable + @Override + public String triggerName() { + return triggerName; + } + + @Nullable + public String triggerId() { + return triggerId; + } + + static final class DBuilder implements Builder { + + private boolean boosted; + private String currentUrl; + private boolean historyRestoreRequest; + private String promptResponse; + private String target; + private String triggerName; + private String triggerId; + + @Override + public DBuilder boosted(boolean boosted) { + this.boosted = boosted; + return this; + } + + @Override + public DBuilder currentUrl(String currentUrl) { + this.currentUrl = currentUrl; + return this; + } + + @Override + public DBuilder historyRestoreRequest(boolean historyRestoreRequest) { + this.historyRestoreRequest = historyRestoreRequest; + return this; + } + + @Override + public DBuilder promptResponse(String promptResponse) { + this.promptResponse = promptResponse; + return this; + } + + @Override + public DBuilder target(String target) { + this.target = target; + return this; + } + + @Override + public DBuilder triggerName(String triggerName) { + this.triggerName = triggerName; + return this; + } + + @Override + public DBuilder triggerId(String triggerId) { + this.triggerId = triggerId; + return this; + } + + @Override + public HtmxRequest build() { + return new DHxRequest(boosted, currentUrl, historyRestoreRequest, promptResponse, target, triggerName, triggerId); + } + } + +} diff --git a/htmx-api/src/main/java/io/avaje/htmx/api/Html.java b/htmx-api/src/main/java/io/avaje/htmx/api/Html.java new file mode 100644 index 000000000..bedae0ded --- /dev/null +++ b/htmx-api/src/main/java/io/avaje/htmx/api/Html.java @@ -0,0 +1,18 @@ +package io.avaje.htmx.api; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +/** + * Mark a controller as producing HTML by default and using "Templating" + * meaning that response objects are expected to a "Model View" passed to + * the "Templating" library. + */ +@Target(TYPE) +@Retention(RUNTIME) +public @interface Html { + +} diff --git a/htmx-api/src/main/java/io/avaje/htmx/api/HtmxRequest.java b/htmx-api/src/main/java/io/avaje/htmx/api/HtmxRequest.java new file mode 100644 index 000000000..d8a47a22c --- /dev/null +++ b/htmx-api/src/main/java/io/avaje/htmx/api/HtmxRequest.java @@ -0,0 +1,106 @@ +package io.avaje.htmx.api; + +import io.avaje.lang.Nullable; + +/** + * This class can be used as a controller method argument to access + * the htmx Request Headers. + * + *

    {@code
    + *
    + *   @HxRequest
    + *   @Get("/users")
    + *   String users(HtmxRequest htmxRequest) {
    + *     if (htmxRequest.isBoosted()) {
    + *         ...
    + *     }
    + *   }
    + *
    + * }
    + * + * @see Request Headers Reference + */ +public interface HtmxRequest { + + /** + * Represents a non-Htmx request. + */ + HtmxRequest EMPTY = new DHxRequest(); + + /** + * Return a new builder for the HtmxRequest. + */ + static Builder builder() { + return new DHxRequest.DBuilder(); + } + + /** + * Return true if this is an Htmx request. + */ + boolean isHtmxRequest(); + + /** + * Indicates that the request is via an element using hx-boost. + * + * @return true if the request was made via HX-Boost, false otherwise + */ + boolean isBoosted(); + + /** + * Return the current URL of the browser when the htmx request was made. + */ + @Nullable + String currentUrl(); + + /** + * Indicates if the request is for history restoration after a miss in the local history cache + * + * @return true if this request is for history restoration, false otherwise + */ + boolean isHistoryRestoreRequest(); + + /** + * Return the user response to an HX-Prompt. + */ + @Nullable + String promptResponse(); + + /** + * Return the id of the target element if it exists. + */ + @Nullable + String target(); + + /** + * Return the name of the triggered element if it exists. + */ + @Nullable + String triggerName(); + + /** + * Return the id of the triggered element if it exists. + */ + @Nullable + String triggerId(); + + /** + * Builder for {@link HtmxRequest}. + */ + interface Builder { + Builder boosted(boolean boosted); + + Builder currentUrl(String currentUrl); + + Builder historyRestoreRequest(boolean historyRestoreRequest); + + Builder promptResponse(String promptResponse); + + Builder target(String target); + + Builder triggerName(String triggerName); + + Builder triggerId(String triggerId); + + HtmxRequest build(); + } +} diff --git a/htmx-api/src/main/java/io/avaje/htmx/api/HxRequest.java b/htmx-api/src/main/java/io/avaje/htmx/api/HxRequest.java new file mode 100644 index 000000000..e643f31e5 --- /dev/null +++ b/htmx-api/src/main/java/io/avaje/htmx/api/HxRequest.java @@ -0,0 +1,54 @@ +package io.avaje.htmx.api; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +/** + * Mark a controller method as handling Htmx requests and potentially restrict + * the handler to only be used for specific Htmx target or Htmx trigger. + *

    + * Controller methods with {@code @HxRequest} require the {@code HX-Request} + * HTTP Header to be set for the handler to process the request. Additionally, + * we can specify {@link #target()}, {@link #triggerId()}, or {@link #triggerName()} + * such that the handler is only invoked specifically for requests with those + * matching headers. + */ +@Target({TYPE, METHOD}) +@Retention(RUNTIME) +public @interface HxRequest { + + /** + * Restricts the mapping to the {@code id} of a specific target element. + * + * @see HX-Target + */ + String target() default ""; + + /** + * Restricts the mapping to the {@code id} of a specific triggered element. + * + * @see HX-Trigger + */ + String triggerId() default ""; + + /** + * Restricts the mapping to the {@code name} of a specific triggered element. + * + * @see HX-Trigger-Name + */ + String triggerName() default ""; + + /** + * Restricts the mapping to the {@code id}, if any, or to the {@code name} of a specific triggered element. + *

    + * If you want to be explicit use {@link #triggerId()} or {@link #triggerName()}. + * + * @see HX-Trigger + * @see HX-Trigger-Name + */ + String value() default ""; +} diff --git a/htmx-api/src/main/java/module-info.java b/htmx-api/src/main/java/module-info.java new file mode 100644 index 000000000..c018025a9 --- /dev/null +++ b/htmx-api/src/main/java/module-info.java @@ -0,0 +1,6 @@ +module io.avaje.htmx.api { + + exports io.avaje.htmx.api; + + requires static io.avaje.lang; +} diff --git a/htmx-nima-jstache/pom.xml b/htmx-nima-jstache/pom.xml new file mode 100644 index 000000000..3305f71c0 --- /dev/null +++ b/htmx-nima-jstache/pom.xml @@ -0,0 +1,47 @@ + + + 4.0.0 + + io.avaje + avaje-http-parent + 2.7 + + + avaje-htmx-nima-jstache + + + 21 + 21 + 21 + UTF-8 + false + 1.3.5 + + + + + io.jstach + jstachio + ${io.jstach.version} + + + io.avaje + avaje-htmx-api + ${project.version} + + + io.avaje + avaje-htmx-nima + ${project.version} + + + io.avaje + avaje-inject + 10.3 + provided + true + + + diff --git a/htmx-nima-jstache/src/main/java/io/avaje/htmx/nima/jstache/DefaultTemplateProvider.java b/htmx-nima-jstache/src/main/java/io/avaje/htmx/nima/jstache/DefaultTemplateProvider.java new file mode 100644 index 000000000..342e2bd45 --- /dev/null +++ b/htmx-nima-jstache/src/main/java/io/avaje/htmx/nima/jstache/DefaultTemplateProvider.java @@ -0,0 +1,21 @@ +package io.avaje.htmx.nima.jstache; + +import io.avaje.htmx.nima.TemplateRender; +import io.avaje.inject.BeanScopeBuilder; +import io.avaje.inject.spi.Plugin; + +/** + * Plugin for avaje inject that provides a default TemplateRender instance. + */ +public final class DefaultTemplateProvider implements Plugin { + + @Override + public Class[] provides() { + return new Class[]{TemplateRender.class}; + } + + @Override + public void apply(BeanScopeBuilder builder) { + builder.provideDefault(null, TemplateRender.class, JStacheTemplateRender::new); + } +} diff --git a/htmx-nima-jstache/src/main/java/io/avaje/htmx/nima/jstache/JStacheTemplateRender.java b/htmx-nima-jstache/src/main/java/io/avaje/htmx/nima/jstache/JStacheTemplateRender.java new file mode 100644 index 000000000..beb4bff60 --- /dev/null +++ b/htmx-nima-jstache/src/main/java/io/avaje/htmx/nima/jstache/JStacheTemplateRender.java @@ -0,0 +1,15 @@ +package io.avaje.htmx.nima.jstache; + +import io.avaje.htmx.nima.TemplateRender; +import io.helidon.webserver.http.ServerRequest; +import io.helidon.webserver.http.ServerResponse; +import io.jstach.jstachio.JStachio; + +public final class JStacheTemplateRender implements TemplateRender { + + @Override + public void render(Object viewModel, ServerRequest req, ServerResponse res) { + var content = JStachio.render(viewModel); + res.send(content); + } +} diff --git a/htmx-nima-jstache/src/main/java/module-info.java b/htmx-nima-jstache/src/main/java/module-info.java new file mode 100644 index 000000000..2da4668b1 --- /dev/null +++ b/htmx-nima-jstache/src/main/java/module-info.java @@ -0,0 +1,11 @@ +module io.avaje.htmx.nima.jstache { + + exports io.avaje.htmx.nima.jstache; + + requires transitive io.avaje.htmx.nima; + requires transitive io.helidon.webserver; + requires transitive io.jstach.jstachio; + requires io.avaje.inject; + + provides io.avaje.inject.spi.Plugin with io.avaje.htmx.nima.jstache.DefaultTemplateProvider; +} diff --git a/htmx-nima-jstache/src/main/resources/META-INF/services/io.avaje.inject.spi.Plugin b/htmx-nima-jstache/src/main/resources/META-INF/services/io.avaje.inject.spi.Plugin new file mode 100644 index 000000000..456aa71f2 --- /dev/null +++ b/htmx-nima-jstache/src/main/resources/META-INF/services/io.avaje.inject.spi.Plugin @@ -0,0 +1 @@ +io.avaje.htmx.nima.jstache.DefaultTemplateProvider diff --git a/htmx-nima/pom.xml b/htmx-nima/pom.xml new file mode 100644 index 000000000..bc405cfec --- /dev/null +++ b/htmx-nima/pom.xml @@ -0,0 +1,32 @@ + + + 4.0.0 + + io.avaje + avaje-http-parent + 2.7 + + + avaje-htmx-nima + + + 21 + false + UTF-8 + + + + + io.avaje + avaje-htmx-api + 2.7 + + + io.helidon.webserver + helidon-webserver + 4.0.7 + + + diff --git a/htmx-nima/src/main/java/io/avaje/htmx/nima/DHxHandler.java b/htmx-nima/src/main/java/io/avaje/htmx/nima/DHxHandler.java new file mode 100644 index 000000000..6b44530a1 --- /dev/null +++ b/htmx-nima/src/main/java/io/avaje/htmx/nima/DHxHandler.java @@ -0,0 +1,50 @@ +package io.avaje.htmx.nima; + +import io.helidon.http.Header; +import io.helidon.http.ServerRequestHeaders; +import io.helidon.webserver.http.Handler; +import io.helidon.webserver.http.ServerRequest; +import io.helidon.webserver.http.ServerResponse; + +import static io.avaje.htmx.nima.HxHeaders.*; + +final class DHxHandler implements Handler { + + + private final Handler delegate; + private final String target; + private final String trigger; + private final String triggerName; + + DHxHandler(Handler delegate, String target, String trigger, String triggerName) { + this.delegate = delegate; + this.target = target; + this.trigger = trigger; + this.triggerName = triggerName; + } + + @Override + public void handle(ServerRequest req, ServerResponse res) throws Exception { + final var headers = req.headers(); + if (headers.contains(HX_REQUEST) && matched(headers)) { + delegate.handle(req, res); + } else { + res.next(); + } + } + + private boolean matched(ServerRequestHeaders headers) { + if (target != null && notMatched(headers.get(HX_TARGET), target)) { + return false; + } + if (trigger != null && notMatched(headers.get(HX_TRIGGER), trigger)) { + return false; + } + return triggerName == null || !notMatched(headers.get(HX_TRIGGER_NAME), triggerName); + } + + private boolean notMatched(Header header, String matchValue) { + return header == null || !matchValue.equals(header.get()); + } + +} diff --git a/htmx-nima/src/main/java/io/avaje/htmx/nima/DHxHandlerBuilder.java b/htmx-nima/src/main/java/io/avaje/htmx/nima/DHxHandlerBuilder.java new file mode 100644 index 000000000..b9370074c --- /dev/null +++ b/htmx-nima/src/main/java/io/avaje/htmx/nima/DHxHandlerBuilder.java @@ -0,0 +1,38 @@ +package io.avaje.htmx.nima; + +import io.helidon.webserver.http.Handler; + +final class DHxHandlerBuilder implements HxHandler.Builder { + + private final Handler delegate; + private String target; + private String trigger; + private String triggerName; + + DHxHandlerBuilder(Handler delegate) { + this.delegate = delegate; + } + + @Override + public DHxHandlerBuilder target(String target) { + this.target = target; + return this; + } + + @Override + public DHxHandlerBuilder trigger(String trigger) { + this.trigger = trigger; + return this; + } + + @Override + public DHxHandlerBuilder triggerName(String triggerName) { + this.triggerName = triggerName; + return this; + } + + @Override + public Handler build() { + return new DHxHandler(delegate, target, trigger, triggerName); + } +} diff --git a/htmx-nima/src/main/java/io/avaje/htmx/nima/HxHandler.java b/htmx-nima/src/main/java/io/avaje/htmx/nima/HxHandler.java new file mode 100644 index 000000000..0c28dbbd5 --- /dev/null +++ b/htmx-nima/src/main/java/io/avaje/htmx/nima/HxHandler.java @@ -0,0 +1,46 @@ +package io.avaje.htmx.nima; + +import io.helidon.webserver.http.Handler; + +/** + * Wrap a Handler with filtering for Htmx specific headers. + *

    + * The underlying Handler will not be invoked unless the request + * is a Htmx request and matches the required attributes. + */ +public interface HxHandler { + + /** + * Create a builder that wraps the underlying handler with Htmx + * specific attribute matching. + */ + static Builder builder(Handler delegate) { + return new DHxHandlerBuilder(delegate); + } + + /** + * Build the Htmx request handler. + */ + interface Builder { + + /** + * Match on the given target. + */ + Builder target(String target); + + /** + * Match on the given trigger. + */ + Builder trigger(String trigger); + + /** + * Match on the given trigger name. + */ + Builder triggerName(String triggerName); + + /** + * Build and return the Handler. + */ + Handler build(); + } +} diff --git a/htmx-nima/src/main/java/io/avaje/htmx/nima/HxHeaders.java b/htmx-nima/src/main/java/io/avaje/htmx/nima/HxHeaders.java new file mode 100644 index 000000000..156798d29 --- /dev/null +++ b/htmx-nima/src/main/java/io/avaje/htmx/nima/HxHeaders.java @@ -0,0 +1,65 @@ +package io.avaje.htmx.nima; + +import io.helidon.http.HeaderName; +import io.helidon.http.HeaderNames; + +/** + * HTMX request headers. + * + * @see Request Headers Reference + */ +public interface HxHeaders { + + /** + * Indicates that the request comes from an element that uses hx-boost. + * + * @see HX-Boosted + */ + HeaderName HX_BOOSTED = HeaderNames.create("HX-Boosted"); + + /** + * The current URL of the browser + * + * @see HX-Current-URL + */ + HeaderName HX_CURRENT_URL = HeaderNames.create("HX-Current-URL"); + + /** + * Indicates if the request is for history restoration after a miss in the local history cache. + * + * @see HX-History-Restore-Request + */ + HeaderName HX_HISTORY_RESTORE_REQUEST = HeaderNames.create("HX-History-Restore-Request"); + + /** + * Contains the user response to a hx-prompt. + * + * @see HX-Prompt + */ + HeaderName HX_PROMPT = HeaderNames.create("HX-Prompt"); + /** + * Only present and {@code true} if the request is issued by htmx. + * + * @see HX-Request + */ + HeaderName HX_REQUEST = HeaderNames.create("HX-Request"); + /** + * The {@code id} of the target element if it exists. + * + * @see HX-Target + */ + HeaderName HX_TARGET = HeaderNames.create("HX-Target"); + /** + * The {@code name} of the triggered element if it exists + * + * @see HX-Trigger-Name + */ + HeaderName HX_TRIGGER_NAME = HeaderNames.create("HX-Trigger-Name"); + /** + * The {@code id} of the triggered element if it exists. + * + * @see HX-Trigger + */ + HeaderName HX_TRIGGER = HeaderNames.create("HX-Trigger"); + +} diff --git a/htmx-nima/src/main/java/io/avaje/htmx/nima/HxReq.java b/htmx-nima/src/main/java/io/avaje/htmx/nima/HxReq.java new file mode 100644 index 000000000..2dda4c675 --- /dev/null +++ b/htmx-nima/src/main/java/io/avaje/htmx/nima/HxReq.java @@ -0,0 +1,49 @@ +package io.avaje.htmx.nima; + +import io.avaje.htmx.api.HtmxRequest; +import io.helidon.webserver.http.ServerRequest; + +/** + * Obtain the HtmxRequest for the given Helidon ServerRequest. + */ +public class HxReq { + + /** + * Create given the server request. + */ + public static HtmxRequest of(ServerRequest request) { + final var headers = request.headers(); + if (!headers.contains(HxHeaders.HX_REQUEST)) { + return HtmxRequest.EMPTY; + } + + var builder = HtmxRequest.builder(); + if (headers.contains(HxHeaders.HX_BOOSTED)) { + builder.boosted(true); + } + if (headers.contains(HxHeaders.HX_HISTORY_RESTORE_REQUEST)) { + builder.historyRestoreRequest(true); + } + var currentUrl = headers.get(HxHeaders.HX_CURRENT_URL); + if (currentUrl != null) { + builder.currentUrl(currentUrl.get()); + } + var prompt = headers.get(HxHeaders.HX_PROMPT); + if (prompt != null) { + builder.promptResponse(prompt.get()); + } + var target = headers.get(HxHeaders.HX_TARGET); + if (target != null) { + builder.target(target.get()); + } + var triggerName = headers.get(HxHeaders.HX_TRIGGER_NAME); + if (triggerName != null) { + builder.triggerName(triggerName.get()); + } + var trigger = headers.get(HxHeaders.HX_TRIGGER); + if (trigger != null) { + builder.triggerId(trigger.get()); + } + return builder.build(); + } +} diff --git a/htmx-nima/src/main/java/io/avaje/htmx/nima/TemplateRender.java b/htmx-nima/src/main/java/io/avaje/htmx/nima/TemplateRender.java new file mode 100644 index 000000000..4cc1a62fa --- /dev/null +++ b/htmx-nima/src/main/java/io/avaje/htmx/nima/TemplateRender.java @@ -0,0 +1,16 @@ +package io.avaje.htmx.nima; + + +import io.helidon.webserver.http.ServerRequest; +import io.helidon.webserver.http.ServerResponse; + +/** + * Template render API for Helidon. + */ +public interface TemplateRender { + + /** + * Render the given template view model to the server response. + */ + void render(Object viewModel, ServerRequest req, ServerResponse res); +} diff --git a/htmx-nima/src/main/java/module-info.java b/htmx-nima/src/main/java/module-info.java new file mode 100644 index 000000000..8adfb5b45 --- /dev/null +++ b/htmx-nima/src/main/java/module-info.java @@ -0,0 +1,7 @@ +module io.avaje.htmx.nima { + + requires io.avaje.htmx.api; + requires io.helidon.webserver; + + exports io.avaje.htmx.nima; +} diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 817ca4211..2f386802c 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -26,6 +26,14 @@ provided + + io.avaje + avaje-htmx-api + ${project.version} + true + provided + + io.swagger.core.v3 swagger-annotations diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java index 3914821cc..12e89fdd6 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java @@ -47,6 +47,8 @@ public final class ControllerReader { private final String producesPrism; private final boolean hasValid; + /** Set true via {@code @Html} to indicate use of Templating */ + private final boolean html; private boolean methodHasValid; /** @@ -70,7 +72,8 @@ public ControllerReader(TypeElement beanType, String contextPath) { docHidden = initDocHidden(); } this.hasValid = initHasValid(); - this.producesPrism = initProduces(); + this.html = initHtml(); + this.producesPrism = initProduces(html); this.apiResponses = buildApiResponses(); hasInstrument = instrumentAllWebMethods() @@ -172,8 +175,13 @@ private boolean matchMethod(ExecutableElement interfaceMethod, ExecutableElement return interfaceMethod.toString().equals(element.toString()); } - private String initProduces() { - return findAnnotation(ProducesPrism::getOptionalOn).map(ProducesPrism::value).orElse(null); + private boolean initHtml() { + return findAnnotation(HtmlPrism::getOptionalOn).isPresent(); + } + + private String initProduces(boolean html) { + String defaultProduces = html ? "text/html;charset=UTF8" : null; + return findAnnotation(ProducesPrism::getOptionalOn).map(ProducesPrism::value).orElse(defaultProduces); } private boolean initDocHidden() { @@ -188,6 +196,10 @@ String produces() { return producesPrism; } + public boolean html() { + return html; + } + public TypeElement beanType() { return beanType; } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java index 2ffa86e20..e679f267e 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java @@ -43,6 +43,7 @@ public class MethodReader { private final boolean hasValid; private final List superMethods; private final Optional timeout; + private final HxRequestPrism hxRequest; private WebMethod webMethod; private int statusCode; @@ -77,6 +78,7 @@ public class MethodReader { this.securityRequirements = readSecurityRequirements(); this.apiResponses = buildApiResponses(); this.javadoc = buildJavadoc(element); + this.hxRequest = HxRequestPrism.getInstanceOn(element); this.timeout = RequestTimeoutPrism.getOptionalOn(element); timeout.ifPresent( p -> { @@ -190,6 +192,13 @@ private void initSetWebMethod(WebMethod webMethod, ExceptionHandlerPrism excepti bean.addImportType(exType); } + /** + * Return the Htmx request annotation for this method. + */ + public HxRequestPrism hxRequest() { + return hxRequest; + } + public Javadoc javadoc() { return javadoc; } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/package-info.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/package-info.java index 129ae8cc7..efdbc2609 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/package-info.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/package-info.java @@ -34,6 +34,8 @@ @GeneratePrism(value = io.swagger.v3.oas.annotations.Hidden.class, publicAccess = true) @GeneratePrism(value = io.avaje.http.api.Client.Import.class, publicAccess = true) @GeneratePrism(value = io.avaje.http.api.RequestTimeout.class, publicAccess = true) +@GeneratePrism(value = io.avaje.htmx.api.HxRequest.class, publicAccess = true) +@GeneratePrism(value = io.avaje.htmx.api.Html.class, publicAccess = true) package io.avaje.http.generator.core; import io.avaje.prism.GeneratePrism; diff --git a/http-generator-core/src/main/java/module-info.java b/http-generator-core/src/main/java/module-info.java index 0d5787e3f..f5142424b 100644 --- a/http-generator-core/src/main/java/module-info.java +++ b/http-generator-core/src/main/java/module-info.java @@ -10,6 +10,7 @@ // SHADED: All content after this line will be removed at package time requires static io.avaje.prism; requires static io.avaje.http.api; + requires static io.avaje.htmx.api; requires static io.swagger.v3.oas.models; requires static io.swagger.v3.oas.annotations; requires static java.validation; diff --git a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java index 8a31e3a51..ee7bf699b 100644 --- a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java +++ b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java @@ -7,14 +7,7 @@ import java.util.Map; import java.util.Optional; -import io.avaje.http.generator.core.Append; -import io.avaje.http.generator.core.CoreWebMethod; -import io.avaje.http.generator.core.MethodParam; -import io.avaje.http.generator.core.MethodReader; -import io.avaje.http.generator.core.ParamType; -import io.avaje.http.generator.core.PathSegments; -import io.avaje.http.generator.core.UType; -import io.avaje.http.generator.core.WebMethod; +import io.avaje.http.generator.core.*; import io.avaje.http.generator.core.openapi.MediaType; import javax.lang.model.type.TypeMirror; @@ -67,8 +60,10 @@ final class ControllerMethodWriter { private final boolean useJsonB; private final boolean instrumentContext; private final boolean isFilter; + private final ControllerReader reader; - ControllerMethodWriter(MethodReader method, Append writer, boolean useJsonB) { + ControllerMethodWriter(MethodReader method, Append writer, boolean useJsonB, ControllerReader reader) { + this.reader = reader; this.method = method; this.writer = writer; this.webMethod = method.webMethod(); @@ -92,10 +87,35 @@ void writeRule() { } else if (isFilter) { writer.append(" routing.addFilter(this::_%s);", method.simpleName()).eol(); } else { - writer.append(" routing.%s(\"%s\", this::_%s);", webMethod.name().toLowerCase(), method.fullPath().replace("\\", "\\\\"), method.simpleName()).eol(); + writer.append(" routing.%s(\"%s\", ", webMethod.name().toLowerCase(), method.fullPath().replace("\\", "\\\\")); + var hxRequest = method.hxRequest(); + if (hxRequest != null) { + writer.append("HxHandler.builder(this::_%s)", method.simpleName()); + if (hasValue(hxRequest.target())) { + writer.append(".target(\"%s\")", hxRequest.target()); + } + if (hasValue(hxRequest.triggerId())) { + writer.append(".trigger(\"%s\")", hxRequest.triggerId()); + } else if (hasValue(hxRequest.value())) { + writer.append(".trigger(\"%s\")", hxRequest.value()); + } + if (hasValue(hxRequest.triggerName())) { + writer.append(".triggerName(\"%s\")", hxRequest.triggerName()); + } else if (hasValue(hxRequest.value())) { + writer.append(".triggerName(\"%s\")", hxRequest.value()); + } + writer.append(".build());").eol(); + + } else { + writer.append("this::_%s);", method.simpleName()).eol(); + } } } + private static boolean hasValue(String value) { + return value != null && !value.isBlank(); + } + void writeHandler(boolean requestScoped) { if (method.isErrorMethod()) { writer.append(" private void _%s(ServerRequest req, ServerResponse res, %s ex) {", method.simpleName(), method.exceptionShortName()).eol(); @@ -205,6 +225,8 @@ void writeHandler(boolean requestScoped) { final var uType = UType.parse(method.returnType()); writer.append(indent).append("%sJsonType.toJson(result, JsonOutput.of(res));", uType.shortName()).eol(); } + } else if (useTemplating()) { + writer.append(indent).append("renderer.render(result, req, res);").eol(); } else { writer.append(indent).append("res.send(result);").eol(); } @@ -215,6 +237,12 @@ void writeHandler(boolean requestScoped) { writer.append(" }").eol().eol(); } + private boolean useTemplating() { + return reader.html() + && !"byte[]".equals(method.returnType().toString()) + && (method.produces() == null || method.produces().toLowerCase().contains("html")); + } + private static boolean isExceptionOrFilterChain(MethodParam param) { return isAssignable2Interface(param.utype().mainType(), "java.lang.Exception") || "FilterChain".equals(param.shortType()); diff --git a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java index e192f9d05..e3254ba39 100644 --- a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java +++ b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java @@ -6,6 +6,7 @@ import java.io.IOException; import java.util.List; import java.util.Map; +import java.util.Objects; import io.avaje.http.generator.core.BaseControllerWriter; import io.avaje.http.generator.core.Constants; @@ -59,6 +60,14 @@ class ControllerWriter extends BaseControllerWriter { reader.addImportType("io.helidon.webserver.http.RoutingRequest"); reader.addImportType("io.helidon.webserver.http.RoutingResponse"); } + if (reader.methods().stream() + .map(MethodReader::hxRequest) + .anyMatch(Objects::nonNull)) { + reader.addImportType("io.avaje.htmx.nima.HxHandler"); + } + if (reader.html()) { + reader.addImportType("io.avaje.htmx.nima.TemplateRender"); + } } void write() { @@ -80,7 +89,7 @@ protected void writeImports() { private List writerMethods() { return reader.methods().stream() .filter(MethodReader::isWebMethod) - .map(it -> new ControllerMethodWriter(it, writer, useJsonB)) + .map(it -> new ControllerMethodWriter(it, writer, useJsonB, reader)) .toList(); } @@ -126,10 +135,12 @@ private void writeClassStart() { if (reader.isIncludeValidator()) { writer.append(" private final Validator validator;").eol(); } - if (instrumentContext) { writer.append(" private final RequestContextResolver resolver;").eol(); } + if (reader.html()) { + writer.append(" private final TemplateRender renderer;").eol(); + } for (final UType type : jsonTypes.values()) { if (!isInputStream(type.full())) { @@ -146,6 +157,9 @@ private void writeClassStart() { if (useJsonB) { writer.append(", Jsonb jsonb"); } + if (reader.html()) { + writer.append(", TemplateRender renderer"); + } if (instrumentContext) { writer.append(", RequestContextResolver resolver"); } @@ -155,6 +169,9 @@ private void writeClassStart() { if (reader.isIncludeValidator()) { writer.append(" this.validator = validator;").eol(); } + if (reader.html()) { + writer.append(" this.renderer = renderer;").eol(); + } if (instrumentContext) { writer.append(" this.resolver = resolver;").eol(); } @@ -176,6 +193,6 @@ private void writeClassStart() { } private boolean isInputStream(String type) { - return isAssignable2Interface(type.toString(), "java.io.InputStream"); + return isAssignable2Interface(type, "java.io.InputStream"); } } diff --git a/pom.xml b/pom.xml index 34d114bc1..4bfa390f0 100644 --- a/pom.xml +++ b/pom.xml @@ -35,6 +35,7 @@ + htmx-api http-api http-api-javalin http-client @@ -63,9 +64,20 @@ [21,22] + htmx-nima + htmx-nima-jstache http-generator-helidon + + test21 + + htmx-nima + htmx-nima-jstache + http-generator-helidon + tests + + module-info.shade diff --git a/tests/pom.xml b/tests/pom.xml index c4173ff3a..449c3b843 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -38,6 +38,7 @@ test-nima test-nima-jsonb + test-nima-htmx diff --git a/tests/test-nima-htmx/pom.xml b/tests/test-nima-htmx/pom.xml new file mode 100644 index 000000000..2316c1bb5 --- /dev/null +++ b/tests/test-nima-htmx/pom.xml @@ -0,0 +1,100 @@ + + + 4.0.0 + + io.avaje + tests + 2.7 + + + test-nima-htmx + + + 21 + UTF-8 + false + 1.3.5 + + + + + io.avaje + avaje-inject + ${avaje-inject.version} + + + io.avaje + avaje-htmx-nima-jstache + ${project.version} + + + io.jstach + jstachio + ${io.jstach.version} + + + io.avaje + avaje-htmx-api + ${project.version} + + + io.avaje + avaje-htmx-nima + ${project.version} + + + io.avaje + avaje-nima + 1.0 + + + + + io.avaje + avaje-nima-test + 1.0 + test + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.11.0 + + 21 + + + io.avaje + avaje-http-helidon-generator + ${project.version} + + + io.avaje + avaje-inject-generator + ${avaje-inject.version} + + + io.avaje + avaje-jsonb-generator + 1.11 + + + io.jstach + jstachio-apt + ${io.jstach.version} + + + + + + + + + + diff --git a/tests/test-nima-htmx/src/main/java/org/example/htmx/Main.java b/tests/test-nima-htmx/src/main/java/org/example/htmx/Main.java new file mode 100644 index 000000000..1b6d205ad --- /dev/null +++ b/tests/test-nima-htmx/src/main/java/org/example/htmx/Main.java @@ -0,0 +1,15 @@ +package org.example.htmx; + +import io.avaje.inject.InjectModule; +import io.avaje.nima.Nima; + +@InjectModule(name = "hxTest") +public class Main { + + public static void main(String[] args) { + Nima.builder() + .port(8090) + .build() + .start(); + } +} diff --git a/tests/test-nima-htmx/src/main/java/org/example/htmx/UIController.java b/tests/test-nima-htmx/src/main/java/org/example/htmx/UIController.java new file mode 100644 index 000000000..05c59ded0 --- /dev/null +++ b/tests/test-nima-htmx/src/main/java/org/example/htmx/UIController.java @@ -0,0 +1,29 @@ +package org.example.htmx; + +import io.avaje.htmx.api.Html; +import io.avaje.htmx.api.HxRequest; +import io.avaje.http.api.Controller; +import io.avaje.http.api.Get; +import io.avaje.http.api.Path; + +import java.time.Instant; +import java.util.List; + +@Html +@Controller +@Path("/") +public class UIController { + + @Get + ViewHome index() { + return new ViewHome("Robin3"); + } + + @HxRequest(target = "name") + @Get("name") + ViewName name() { + var mlist = List.of("one","two","three", "four"); + return new ViewName("JimBolin", Instant.now(), "MoreMeMore", mlist); + } + +} diff --git a/tests/test-nima-htmx/src/main/java/org/example/htmx/ViewHome.java b/tests/test-nima-htmx/src/main/java/org/example/htmx/ViewHome.java new file mode 100644 index 000000000..607dc690b --- /dev/null +++ b/tests/test-nima-htmx/src/main/java/org/example/htmx/ViewHome.java @@ -0,0 +1,7 @@ +package org.example.htmx; + +import io.jstach.jstache.JStache; + +@JStache(path = "home") +public record ViewHome(String name) { +} diff --git a/tests/test-nima-htmx/src/main/java/org/example/htmx/ViewName.java b/tests/test-nima-htmx/src/main/java/org/example/htmx/ViewName.java new file mode 100644 index 000000000..2cda3b0cf --- /dev/null +++ b/tests/test-nima-htmx/src/main/java/org/example/htmx/ViewName.java @@ -0,0 +1,13 @@ +package org.example.htmx; + +import io.jstach.jstache.JStache; + +import java.time.Instant; +import java.util.List; + +@JStache(path = "name") +public record ViewName(String name, Instant foo, String more, List mlist) { + public String when() { + return foo.toString(); + } +} diff --git a/tests/test-nima-htmx/src/main/java/org/example/htmx/package-info.java b/tests/test-nima-htmx/src/main/java/org/example/htmx/package-info.java new file mode 100644 index 000000000..a0e8d10d8 --- /dev/null +++ b/tests/test-nima-htmx/src/main/java/org/example/htmx/package-info.java @@ -0,0 +1,4 @@ +@JStachePath(prefix = "ui/", suffix = ".mustache") +package org.example.htmx; + +import io.jstach.jstache.JStachePath; diff --git a/tests/test-nima-htmx/src/main/java/org/example/htmx/template/JstacheTemplateRender.java b/tests/test-nima-htmx/src/main/java/org/example/htmx/template/JstacheTemplateRender.java new file mode 100644 index 000000000..4acb8ed00 --- /dev/null +++ b/tests/test-nima-htmx/src/main/java/org/example/htmx/template/JstacheTemplateRender.java @@ -0,0 +1,17 @@ +package org.example.htmx.template; + +import io.avaje.htmx.nima.TemplateRender; +import io.avaje.inject.Component; +import io.helidon.webserver.http.ServerRequest; +import io.helidon.webserver.http.ServerResponse; +import io.jstach.jstachio.JStachio; + +@Component +public class JstacheTemplateRender implements TemplateRender { + + @Override + public void render(Object viewModel, ServerRequest req, ServerResponse res) { + String content = JStachio.render(viewModel); + res.send(content); + } +} diff --git a/tests/test-nima-htmx/src/main/resources/ui/fragments/layout.mustache b/tests/test-nima-htmx/src/main/resources/ui/fragments/layout.mustache new file mode 100644 index 000000000..26a8c9e85 --- /dev/null +++ b/tests/test-nima-htmx/src/main/resources/ui/fragments/layout.mustache @@ -0,0 +1,11 @@ + + + + Hi + + + +

    Heading

    +{{$body}}Empty body{{/body}} + + diff --git a/tests/test-nima-htmx/src/main/resources/ui/home.mustache b/tests/test-nima-htmx/src/main/resources/ui/home.mustache new file mode 100644 index 000000000..af4686584 --- /dev/null +++ b/tests/test-nima-htmx/src/main/resources/ui/home.mustache @@ -0,0 +1,8 @@ +{{ + Hi there {{ name }} + + +{{/body}} +{{/fragments/layout}} diff --git a/tests/test-nima-htmx/src/main/resources/ui/name.mustache b/tests/test-nima-htmx/src/main/resources/ui/name.mustache new file mode 100644 index 000000000..4c2f0f851 --- /dev/null +++ b/tests/test-nima-htmx/src/main/resources/ui/name.mustache @@ -0,0 +1,6 @@ +
    +Yond {{ name }} its {{ when }} !! and {{ more }} sad + {{#mlist}} + in {{.}} ot + {{/mlist}} +
    diff --git a/tests/test-nima-jsonb/src/main/java/org/example/path/nest/PathNestController.java b/tests/test-nima-jsonb/src/main/java/org/example/htmx/PathNestController.java similarity index 92% rename from tests/test-nima-jsonb/src/main/java/org/example/path/nest/PathNestController.java rename to tests/test-nima-jsonb/src/main/java/org/example/htmx/PathNestController.java index 47fb7479c..dcc7aa3ec 100644 --- a/tests/test-nima-jsonb/src/main/java/org/example/path/nest/PathNestController.java +++ b/tests/test-nima-jsonb/src/main/java/org/example/htmx/PathNestController.java @@ -1,4 +1,4 @@ -package org.example.path.nest; +package org.example.htmx; import io.avaje.http.api.Controller; import io.avaje.http.api.Get; diff --git a/tests/test-nima-jsonb/src/main/java/org/example/path/nest/package-info.java b/tests/test-nima-jsonb/src/main/java/org/example/htmx/package-info.java similarity index 61% rename from tests/test-nima-jsonb/src/main/java/org/example/path/nest/package-info.java rename to tests/test-nima-jsonb/src/main/java/org/example/htmx/package-info.java index 73f306ff6..d9695fcaa 100644 --- a/tests/test-nima-jsonb/src/main/java/org/example/path/nest/package-info.java +++ b/tests/test-nima-jsonb/src/main/java/org/example/htmx/package-info.java @@ -1,5 +1,5 @@ @Path("nested") -package org.example.path.nest; +package org.example.htmx; import io.avaje.http.api.Path; diff --git a/tests/test-nima-jsonb/src/main/java/org/example/path/PathTestController.java b/tests/test-nima-jsonb/src/main/java/org/example/path/PathTestController.java index 5d1a3f970..2421bd26e 100644 --- a/tests/test-nima-jsonb/src/main/java/org/example/path/PathTestController.java +++ b/tests/test-nima-jsonb/src/main/java/org/example/path/PathTestController.java @@ -1,6 +1,6 @@ package org.example.path; -import org.example.path.nest.PathNestController.NestedTypeResponse; +import org.example.htmx.PathNestController.NestedTypeResponse; import io.avaje.http.api.Controller; import io.avaje.http.api.Get; From 62e717e285c5fdf22c036e9c5b050735c3ca77e4 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 13 Aug 2024 23:36:26 +1200 Subject: [PATCH 1136/1323] Disable EA stable build (as download broken) --- .github/workflows/jdk-ea-stable.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/jdk-ea-stable.yml b/.github/workflows/jdk-ea-stable.yml index a6c44f00f..6f2383e62 100644 --- a/.github/workflows/jdk-ea-stable.yml +++ b/.github/workflows/jdk-ea-stable.yml @@ -2,11 +2,11 @@ name: JDK EA Stable on: - push: - pull_request: workflow_dispatch: - schedule: - - cron: '39 1 * * 1,3,5' +# push: +# pull_request: +# schedule: +# - cron: '39 1 * * 1,3,5' jobs: build: From 8a57e69d14810436e0339add68e28af11985f529 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 13 Aug 2024 23:37:51 +1200 Subject: [PATCH 1137/1323] Version 2.8-RC1 --- htmx-api/pom.xml | 2 +- htmx-nima-jstache/pom.xml | 2 +- htmx-nima/pom.xml | 4 ++-- http-api-javalin/pom.xml | 2 +- http-api/pom.xml | 2 +- http-client-gson-adapter/pom.xml | 4 ++-- http-client-moshi-adapter/pom.xml | 4 ++-- http-client/pom.xml | 4 ++-- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 2 +- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-inject-plugin/pom.xml | 2 +- pom.xml | 2 +- tests/pom.xml | 2 +- tests/test-client-generation/pom.xml | 2 +- tests/test-client/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-htmx/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- 24 files changed, 28 insertions(+), 28 deletions(-) diff --git a/htmx-api/pom.xml b/htmx-api/pom.xml index ad4b7e30c..9f086a835 100644 --- a/htmx-api/pom.xml +++ b/htmx-api/pom.xml @@ -6,7 +6,7 @@ io.avaje avaje-http-parent - 2.7 + 2.8-RC1 avaje-htmx-api diff --git a/htmx-nima-jstache/pom.xml b/htmx-nima-jstache/pom.xml index 3305f71c0..80c3976f0 100644 --- a/htmx-nima-jstache/pom.xml +++ b/htmx-nima-jstache/pom.xml @@ -6,7 +6,7 @@ io.avaje avaje-http-parent - 2.7 + 2.8-RC1 avaje-htmx-nima-jstache diff --git a/htmx-nima/pom.xml b/htmx-nima/pom.xml index bc405cfec..89c2870f3 100644 --- a/htmx-nima/pom.xml +++ b/htmx-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje avaje-http-parent - 2.7 + 2.8-RC1 avaje-htmx-nima @@ -21,7 +21,7 @@ io.avaje avaje-htmx-api - 2.7 + 2.8-RC1 io.helidon.webserver diff --git a/http-api-javalin/pom.xml b/http-api-javalin/pom.xml index ac78d243d..9f3b18bd3 100644 --- a/http-api-javalin/pom.xml +++ b/http-api-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.7 + 2.8-RC1 .. diff --git a/http-api/pom.xml b/http-api/pom.xml index 4c5548bdf..b8a425108 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.7 + 2.8-RC1 .. diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index 87d5d4fd0..099a2b053 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.7 + 2.8-RC1 avaje-http-client-gson @@ -20,7 +20,7 @@ io.avaje avaje-http-client - 2.7 + 2.8-RC1 provided diff --git a/http-client-moshi-adapter/pom.xml b/http-client-moshi-adapter/pom.xml index e0e01a110..f5cd2899c 100644 --- a/http-client-moshi-adapter/pom.xml +++ b/http-client-moshi-adapter/pom.xml @@ -3,7 +3,7 @@ io.avaje avaje-http-parent - 2.7 + 2.8-RC1 avaje-http-client-moshi @@ -19,7 +19,7 @@ io.avaje avaje-http-client - 2.7 + 2.8-RC1 provided diff --git a/http-client/pom.xml b/http-client/pom.xml index b0a81dd9a..d05286f04 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.7 + 2.8-RC1 avaje-http-client @@ -66,7 +66,7 @@ io.avaje avaje-http-api - 2.7 + 2.8-RC1 test diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index 85186fad1..a662b44a7 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.7 + 2.8-RC1 avaje-http-client-generator diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 2f386802c..0b730af17 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.7 + 2.8-RC1 avaje-http-generator-core diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index 3d5349a21..8fb09b39f 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.7 + 2.8-RC1 avaje-http-helidon-generator diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index 396494614..1985a057c 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.7 + 2.8-RC1 avaje-http-javalin-generator diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index ebd49a795..f77bac53a 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.7 + 2.8-RC1 avaje-http-jex-generator diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index 732c22b5a..d13cf8290 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.7 + 2.8-RC1 .. diff --git a/pom.xml b/pom.xml index 4bfa390f0..05a50c367 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-parent - 2.7 + 2.8-RC1 pom diff --git a/tests/pom.xml b/tests/pom.xml index 449c3b843..7082e7330 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.7 + 2.8-RC1 tests diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index ee5c1e62c..a1d6ba4da 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.7 + 2.8-RC1 test-client-generation diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index f0750b0fb..70285d69d 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.7 + 2.8-RC1 test-client diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index e628758ab..d130f7a8e 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 2.7 + 2.8-RC1 test-javalin-jsonb diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index d2e89b31e..ee0919f27 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.7 + 2.8-RC1 test-javalin diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index e93722d1b..7625ec2e8 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.7 + 2.8-RC1 test-jex diff --git a/tests/test-nima-htmx/pom.xml b/tests/test-nima-htmx/pom.xml index 2316c1bb5..65bbc43ce 100644 --- a/tests/test-nima-htmx/pom.xml +++ b/tests/test-nima-htmx/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.7 + 2.8-RC1 test-nima-htmx diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 9c54fb44b..5d0fe3206 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.7 + 2.8-RC1 test-nima-jsonb diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index a27501e10..ba385f431 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.7 + 2.8-RC1 test-nima From 5d50ef56b5f98c4597fd8f8c64fc1c92bb5ffba8 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Mon, 19 Aug 2024 08:37:31 +1200 Subject: [PATCH 1138/1323] Add htmx content cache feature (#484) --- .../java/io/avaje/htmx/api/ContentCache.java | 16 ++++ .../nima/jstache/DefaultTemplateProvider.java | 4 +- .../nima/jstache/JStacheTemplateRender.java | 7 +- .../htmx/nima/jstache/SimpleContentCache.java | 31 +++++++ .../avaje/htmx/nima/TemplateContentCache.java | 30 ++++++ .../io/avaje/htmx/nima/TemplateRender.java | 6 +- .../http/generator/core/ControllerReader.java | 20 +++- .../http/generator/core/MethodReader.java | 13 ++- .../generator/core/openapi/MediaType.java | 1 + .../http/generator/core/package-info.java | 1 + .../helidon/nima/ControllerMethodWriter.java | 92 +++++++++++++++---- .../helidon/nima/ControllerWriter.java | 15 +++ .../java/org/example/htmx/UIController.java | 3 + .../htmx/template/JstacheTemplateRender.java | 7 +- .../htmx/template/SimpleContentCache.java | 33 +++++++ 15 files changed, 240 insertions(+), 39 deletions(-) create mode 100644 htmx-api/src/main/java/io/avaje/htmx/api/ContentCache.java create mode 100644 htmx-nima-jstache/src/main/java/io/avaje/htmx/nima/jstache/SimpleContentCache.java create mode 100644 htmx-nima/src/main/java/io/avaje/htmx/nima/TemplateContentCache.java create mode 100644 tests/test-nima-htmx/src/main/java/org/example/htmx/template/SimpleContentCache.java diff --git a/htmx-api/src/main/java/io/avaje/htmx/api/ContentCache.java b/htmx-api/src/main/java/io/avaje/htmx/api/ContentCache.java new file mode 100644 index 000000000..56a8b2106 --- /dev/null +++ b/htmx-api/src/main/java/io/avaje/htmx/api/ContentCache.java @@ -0,0 +1,16 @@ +package io.avaje.htmx.api; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +/** + * Mark a controller method as using a content cache. + */ +@Target(METHOD) +@Retention(RUNTIME) +public @interface ContentCache { + +} diff --git a/htmx-nima-jstache/src/main/java/io/avaje/htmx/nima/jstache/DefaultTemplateProvider.java b/htmx-nima-jstache/src/main/java/io/avaje/htmx/nima/jstache/DefaultTemplateProvider.java index 342e2bd45..41fc8161e 100644 --- a/htmx-nima-jstache/src/main/java/io/avaje/htmx/nima/jstache/DefaultTemplateProvider.java +++ b/htmx-nima-jstache/src/main/java/io/avaje/htmx/nima/jstache/DefaultTemplateProvider.java @@ -1,5 +1,6 @@ package io.avaje.htmx.nima.jstache; +import io.avaje.htmx.nima.TemplateContentCache; import io.avaje.htmx.nima.TemplateRender; import io.avaje.inject.BeanScopeBuilder; import io.avaje.inject.spi.Plugin; @@ -11,11 +12,12 @@ public final class DefaultTemplateProvider implements Plugin { @Override public Class[] provides() { - return new Class[]{TemplateRender.class}; + return new Class[]{TemplateRender.class, TemplateContentCache.class}; } @Override public void apply(BeanScopeBuilder builder) { builder.provideDefault(null, TemplateRender.class, JStacheTemplateRender::new); + builder.provideDefault(null, TemplateContentCache.class, SimpleContentCache::new); } } diff --git a/htmx-nima-jstache/src/main/java/io/avaje/htmx/nima/jstache/JStacheTemplateRender.java b/htmx-nima-jstache/src/main/java/io/avaje/htmx/nima/jstache/JStacheTemplateRender.java index beb4bff60..7b5b70294 100644 --- a/htmx-nima-jstache/src/main/java/io/avaje/htmx/nima/jstache/JStacheTemplateRender.java +++ b/htmx-nima-jstache/src/main/java/io/avaje/htmx/nima/jstache/JStacheTemplateRender.java @@ -1,15 +1,12 @@ package io.avaje.htmx.nima.jstache; import io.avaje.htmx.nima.TemplateRender; -import io.helidon.webserver.http.ServerRequest; -import io.helidon.webserver.http.ServerResponse; import io.jstach.jstachio.JStachio; public final class JStacheTemplateRender implements TemplateRender { @Override - public void render(Object viewModel, ServerRequest req, ServerResponse res) { - var content = JStachio.render(viewModel); - res.send(content); + public String render(Object viewModel) { + return JStachio.render(viewModel); } } diff --git a/htmx-nima-jstache/src/main/java/io/avaje/htmx/nima/jstache/SimpleContentCache.java b/htmx-nima-jstache/src/main/java/io/avaje/htmx/nima/jstache/SimpleContentCache.java new file mode 100644 index 000000000..aaa64b6a5 --- /dev/null +++ b/htmx-nima-jstache/src/main/java/io/avaje/htmx/nima/jstache/SimpleContentCache.java @@ -0,0 +1,31 @@ +package io.avaje.htmx.nima.jstache; + +import io.avaje.htmx.nima.TemplateContentCache; +import io.helidon.webserver.http.ServerRequest; + +import java.util.concurrent.ConcurrentHashMap; + +public class SimpleContentCache implements TemplateContentCache { + + private final ConcurrentHashMap localCache = new ConcurrentHashMap<>(); + + @Override + public String key(ServerRequest req) { + return req.requestedUri().path().rawPath(); + } + + @Override + public String key(ServerRequest req, Object formParams) { + return req.requestedUri().path().rawPath() + formParams; + } + + @Override + public String content(String key) { + return localCache.get(key); + } + + @Override + public void contentPut(String key, String content) { + localCache.put(key, content); + } +} diff --git a/htmx-nima/src/main/java/io/avaje/htmx/nima/TemplateContentCache.java b/htmx-nima/src/main/java/io/avaje/htmx/nima/TemplateContentCache.java new file mode 100644 index 000000000..83a8a60e7 --- /dev/null +++ b/htmx-nima/src/main/java/io/avaje/htmx/nima/TemplateContentCache.java @@ -0,0 +1,30 @@ +package io.avaje.htmx.nima; + +import io.helidon.webserver.http.ServerRequest; + +/** + * Defines caching of template content. + */ +public interface TemplateContentCache { + + /** + * Return the key given the request. + */ + String key(ServerRequest req); + + /** + * Return the key given the request with form parameters. + */ + String key(ServerRequest req, Object formParams); + + /** + * Return the content given the key. + */ + String content(String key); + + /** + * Put the content into the cache. + */ + void contentPut(String key, String content); + +} diff --git a/htmx-nima/src/main/java/io/avaje/htmx/nima/TemplateRender.java b/htmx-nima/src/main/java/io/avaje/htmx/nima/TemplateRender.java index 4cc1a62fa..fa69f00f6 100644 --- a/htmx-nima/src/main/java/io/avaje/htmx/nima/TemplateRender.java +++ b/htmx-nima/src/main/java/io/avaje/htmx/nima/TemplateRender.java @@ -1,9 +1,5 @@ package io.avaje.htmx.nima; - -import io.helidon.webserver.http.ServerRequest; -import io.helidon.webserver.http.ServerResponse; - /** * Template render API for Helidon. */ @@ -12,5 +8,5 @@ public interface TemplateRender { /** * Render the given template view model to the server response. */ - void render(Object viewModel, ServerRequest req, ServerResponse res); + String render(Object viewModel); } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java index 12e89fdd6..2e5cd9dcd 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java @@ -49,6 +49,8 @@ public final class ControllerReader { private final boolean hasValid; /** Set true via {@code @Html} to indicate use of Templating */ private final boolean html; + /** Set true via {@code @ContentCache} to indicate use of Templating content cache */ + private boolean hasContentCache; private boolean methodHasValid; /** @@ -200,6 +202,10 @@ public boolean html() { return html; } + public boolean hasContentCache() { + return hasContentCache; + } + public TypeElement beanType() { return beanType; } @@ -247,10 +253,11 @@ public void read(boolean withSingleton) { } private void deriveIncludeValidation() { - methodHasValid = methodHasValid(); + methodHasValid = anyMethodHasValid(); + hasContentCache = anyMethodHasContentCache(); } - private boolean methodHasValid() { + private boolean anyMethodHasValid() { for (final MethodReader method : methods) { if (method.hasValid()) { return true; @@ -259,6 +266,15 @@ private boolean methodHasValid() { return false; } + private boolean anyMethodHasContentCache() { + for (final MethodReader method : methods) { + if (method.hasContentCache()) { + return true; + } + } + return false; + } + private void readField(Element element) { if (!requestScope) { final String rawType = element.asType().toString(); diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java index e679f267e..d427b57b9 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java @@ -41,6 +41,7 @@ public class MethodReader { private final List actualParams; private final PathSegments pathSegments; private final boolean hasValid; + private final Optional contentCache; private final List superMethods; private final Optional timeout; private final HxRequestPrism hxRequest; @@ -87,10 +88,12 @@ public class MethodReader { }); if (isWebMethod()) { this.hasValid = initValid(); + this.contentCache = initContentCache(); this.instrumentContext = initResolver(); this.pathSegments = PathSegments.parse(Util.combinePath(bean.path(), webMethodPath)); } else { this.hasValid = false; + this.contentCache = Optional.empty(); this.pathSegments = null; this.instrumentContext = false; } @@ -124,7 +127,11 @@ private boolean initValid() { private boolean superMethodHasValid() { return superMethods.stream() - .anyMatch(e -> findAnnotation(ValidPrism::getOptionalOn).isPresent()); + .anyMatch(e -> findAnnotation(ValidPrism::getOptionalOn).isPresent()); + } + + private Optional initContentCache() { + return findAnnotation(ContentCachePrism::getOptionalOn); } @Override @@ -413,6 +420,10 @@ boolean hasValid() { return hasValid; } + public boolean hasContentCache() { + return contentCache.isPresent(); + } + public String simpleName() { return element.getSimpleName().toString(); } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/MediaType.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/MediaType.java index 331488cfa..e4af9c899 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/MediaType.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/MediaType.java @@ -4,6 +4,7 @@ public enum MediaType { APPLICATION_JSON("application/json"), TEXT_PLAIN("text/plain"), TEXT_HTML("text/html"), + HTML_UTF8("text/html;charset=UTF8"), UNKNOWN(""); private final String value; diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/package-info.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/package-info.java index efdbc2609..5300dda1b 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/package-info.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/package-info.java @@ -36,6 +36,7 @@ @GeneratePrism(value = io.avaje.http.api.RequestTimeout.class, publicAccess = true) @GeneratePrism(value = io.avaje.htmx.api.HxRequest.class, publicAccess = true) @GeneratePrism(value = io.avaje.htmx.api.Html.class, publicAccess = true) +@GeneratePrism(value = io.avaje.htmx.api.ContentCache.class, publicAccess = true) package io.avaje.http.generator.core; import io.avaje.prism.GeneratePrism; diff --git a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java index ee7bf699b..5afa98747 100644 --- a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java +++ b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java @@ -131,7 +131,7 @@ void writeHandler(boolean requestScoped) { writer.append(" res.status(%s);", lookupStatusCode(statusCode)).eol(); } } - + boolean withFormParams = false; final var bodyType = method.bodyType(); if (bodyType != null && !method.isErrorMethod() && !isFilter) { if ("InputStream".equals(bodyType)) { @@ -144,26 +144,41 @@ void writeHandler(boolean requestScoped) { } else { defaultHelidonBodyContent(); } - } else if (usesFormParams()) { - writer.append(" var formParams = req.content().as(Parameters.class);").eol(); + } else { + withFormParams = usesFormParams(); + if (withFormParams) { + writer.append(" var formParams = req.content().as(Parameters.class);").eol(); + } + } + final ResponseMode responseMode = responseMode(); + final boolean withContentCache = responseMode == ResponseMode.Templating && useContentCache(); + if (withContentCache) { + writer.append(" var key = contentCache.key(req"); + if (withFormParams) { + writer.append(", formParams"); + } + writer.append(");").eol(); + writer.append(" var cacheContent = contentCache.content(key);").eol(); + writer.append(" if (cacheContent != null) {").eol(); + writeContextReturn(" "); + writer.append(" res.send(cacheContent);").eol(); + writer.append(" return;").eol(); + writer.append(" }").eol(); } final var segments = method.pathSegments(); if (segments.fullPath().contains("{")) { writer.append(" var pathParams = req.path().pathParameters();").eol(); } - for (final PathSegments.Segment matrixSegment : segments.matrixSegments()) { matrixSegment.writeCreateSegment(writer, platform()); } - final var params = method.params(); for (final MethodParam param : params) { if (!isExceptionOrFilterChain(param)) { param.writeCtxGet(writer, segments); } } - if (method.includeValidate()) { for (final MethodParam param : params) { param.writeValidate(writer); @@ -205,7 +220,7 @@ void writeHandler(boolean requestScoped) { } writer.append(");").eol(); - if (!method.isVoid() && !isFilter) { + if (responseMode != ResponseMode.Void) { TypeMirror typeMirror = method.returnType(); boolean includeNoContent = !typeMirror.getKind().isPrimitive(); if (includeNoContent) { @@ -214,21 +229,29 @@ void writeHandler(boolean requestScoped) { writer.append(" } else {").eol(); } String indent = includeNoContent ? " " : " "; - writeContextReturn(indent); - if (isInputStream(method.returnType())) { - final var uType = UType.parse(method.returnType()); - writer.append(indent).append("result.transferTo(res.outputStream());", uType.shortName()).eol(); - } else if (producesJson()) { - if (returnTypeString()) { - writer.append(indent).append("res.send(result); // send raw JSON").eol(); - } else { - final var uType = UType.parse(method.returnType()); - writer.append(indent).append("%sJsonType.toJson(result, JsonOutput.of(res));", uType.shortName()).eol(); + if (responseMode == ResponseMode.Templating) { + writer.append(indent).append("var content = renderer.render(result);").eol(); + if (withContentCache) { + writer.append(indent).append("contentCache.contentPut(key, content);").eol(); } - } else if (useTemplating()) { - writer.append(indent).append("renderer.render(result, req, res);").eol(); + writeContextReturn(indent); + writer.append(indent).append("res.send(content);").eol(); + } else { - writer.append(indent).append("res.send(result);").eol(); + writeContextReturn(indent); + if (responseMode == ResponseMode.InputStream) { + final var uType = UType.parse(method.returnType()); + writer.append(indent).append("result.transferTo(res.outputStream());", uType.shortName()).eol(); + } else if (responseMode == ResponseMode.Json) { + if (returnTypeString()) { + writer.append(indent).append("res.send(result); // send raw JSON").eol(); + } else { + final var uType = UType.parse(method.returnType()); + writer.append(indent).append("%sJsonType.toJson(result, JsonOutput.of(res));", uType.shortName()).eol(); + } + } else { + writer.append(indent).append("res.send(result);").eol(); + } } if (includeNoContent) { writer.append(" }").eol(); @@ -237,6 +260,34 @@ void writeHandler(boolean requestScoped) { writer.append(" }").eol().eol(); } + enum ResponseMode { + Void, + Json, + Templating, + InputStream, + Other + } + + ResponseMode responseMode() { + if (method.isVoid() || isFilter) { + return ResponseMode.Void; + } + if (isInputStream(method.returnType())) { + return ResponseMode.InputStream; + } + if (producesJson()) { + return ResponseMode.Json; + } + if (useTemplating()) { + return ResponseMode.Templating; + } + return ResponseMode.Other; + } + + private boolean useContentCache() { + return method.hasContentCache(); + } + private boolean useTemplating() { return reader.html() && !"byte[]".equals(method.returnType().toString()) @@ -308,6 +359,7 @@ private void writeContextReturn(String indent) { final var contentTypeString = "res.headers().contentType(MediaTypes."; writer.append(indent); switch (produces) { + case HTML_UTF8 -> writer.append("res.headers().contentType(HTML_UTF8);").eol(); case APPLICATION_JSON -> writer.append(contentTypeString).append("APPLICATION_JSON);").eol(); case TEXT_HTML -> writer.append(contentTypeString).append("TEXT_HTML);").eol(); case TEXT_PLAIN -> writer.append(contentTypeString).append("TEXT_PLAIN);").eol(); diff --git a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java index e3254ba39..c2a39d2e8 100644 --- a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java +++ b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java @@ -67,6 +67,9 @@ class ControllerWriter extends BaseControllerWriter { } if (reader.html()) { reader.addImportType("io.avaje.htmx.nima.TemplateRender"); + if (reader.hasContentCache()) { + reader.addImportType("io.avaje.htmx.nima.TemplateContentCache"); + } } } @@ -129,6 +132,9 @@ private void writeClassStart() { if (reader.isIncludeValidator()) { writer.append(" private static final HeaderName HEADER_ACCEPT_LANGUAGE = HeaderNames.create(\"Accept-Language\");").eol(); } + if (reader.html()) { + writer.append(" private static final io.helidon.common.media.type.MediaType HTML_UTF8 = MediaTypes.create(\"text/html;charset=UTF8\");").eol(); + } writer.append(" private final %s %s;", controllerType, controllerName).eol(); @@ -140,6 +146,9 @@ private void writeClassStart() { } if (reader.html()) { writer.append(" private final TemplateRender renderer;").eol(); + if (reader.hasContentCache()) { + writer.append(" private final TemplateContentCache contentCache;").eol(); + } } for (final UType type : jsonTypes.values()) { @@ -159,6 +168,9 @@ private void writeClassStart() { } if (reader.html()) { writer.append(", TemplateRender renderer"); + if (reader.hasContentCache()) { + writer.append(", TemplateContentCache contentCache"); + } } if (instrumentContext) { writer.append(", RequestContextResolver resolver"); @@ -171,6 +183,9 @@ private void writeClassStart() { } if (reader.html()) { writer.append(" this.renderer = renderer;").eol(); + if (reader.hasContentCache()) { + writer.append(" this.contentCache = contentCache;").eol(); + } } if (instrumentContext) { writer.append(" this.resolver = resolver;").eol(); diff --git a/tests/test-nima-htmx/src/main/java/org/example/htmx/UIController.java b/tests/test-nima-htmx/src/main/java/org/example/htmx/UIController.java index 05c59ded0..482ffe033 100644 --- a/tests/test-nima-htmx/src/main/java/org/example/htmx/UIController.java +++ b/tests/test-nima-htmx/src/main/java/org/example/htmx/UIController.java @@ -1,6 +1,7 @@ package org.example.htmx; import io.avaje.htmx.api.Html; +import io.avaje.htmx.api.ContentCache; import io.avaje.htmx.api.HxRequest; import io.avaje.http.api.Controller; import io.avaje.http.api.Get; @@ -14,11 +15,13 @@ @Path("/") public class UIController { + @ContentCache @Get ViewHome index() { return new ViewHome("Robin3"); } + @ContentCache @HxRequest(target = "name") @Get("name") ViewName name() { diff --git a/tests/test-nima-htmx/src/main/java/org/example/htmx/template/JstacheTemplateRender.java b/tests/test-nima-htmx/src/main/java/org/example/htmx/template/JstacheTemplateRender.java index 4acb8ed00..ec94bf95e 100644 --- a/tests/test-nima-htmx/src/main/java/org/example/htmx/template/JstacheTemplateRender.java +++ b/tests/test-nima-htmx/src/main/java/org/example/htmx/template/JstacheTemplateRender.java @@ -2,16 +2,13 @@ import io.avaje.htmx.nima.TemplateRender; import io.avaje.inject.Component; -import io.helidon.webserver.http.ServerRequest; -import io.helidon.webserver.http.ServerResponse; import io.jstach.jstachio.JStachio; @Component public class JstacheTemplateRender implements TemplateRender { @Override - public void render(Object viewModel, ServerRequest req, ServerResponse res) { - String content = JStachio.render(viewModel); - res.send(content); + public String render(Object viewModel) { + return JStachio.render(viewModel); } } diff --git a/tests/test-nima-htmx/src/main/java/org/example/htmx/template/SimpleContentCache.java b/tests/test-nima-htmx/src/main/java/org/example/htmx/template/SimpleContentCache.java new file mode 100644 index 000000000..bf1757496 --- /dev/null +++ b/tests/test-nima-htmx/src/main/java/org/example/htmx/template/SimpleContentCache.java @@ -0,0 +1,33 @@ +package org.example.htmx.template; + +import io.avaje.inject.Component; +import io.avaje.htmx.nima.TemplateContentCache; +import io.helidon.webserver.http.ServerRequest; + +import java.util.concurrent.ConcurrentHashMap; + +@Component +public class SimpleContentCache implements TemplateContentCache { + + private final ConcurrentHashMap localCache = new ConcurrentHashMap<>(); + + @Override + public String key(ServerRequest req) { + return req.requestedUri().path().rawPath(); + } + + @Override + public String key(ServerRequest req, Object formParams) { + return req.requestedUri().path().rawPath() + formParams; + } + + @Override + public String content(String key) { + return localCache.get(key); + } + + @Override + public void contentPut(String key, String content) { + localCache.put(key, content); + } +} From 3e7e192a72bbaf0df95c80970b7361c139c4919d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Aug 2024 19:40:55 +0000 Subject: [PATCH 1139/1323] Bump io.jstach.version from 1.3.5 to 1.3.6 Bumps `io.jstach.version` from 1.3.5 to 1.3.6. Updates `io.jstach:jstachio` from 1.3.5 to 1.3.6 Updates `io.jstach:jstachio-apt` from 1.3.5 to 1.3.6 --- updated-dependencies: - dependency-name: io.jstach:jstachio dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: io.jstach:jstachio-apt dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- htmx-nima-jstache/pom.xml | 2 +- tests/test-nima-htmx/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/htmx-nima-jstache/pom.xml b/htmx-nima-jstache/pom.xml index 80c3976f0..86faa8892 100644 --- a/htmx-nima-jstache/pom.xml +++ b/htmx-nima-jstache/pom.xml @@ -17,7 +17,7 @@ 21 UTF-8 false - 1.3.5 + 1.3.6 diff --git a/tests/test-nima-htmx/pom.xml b/tests/test-nima-htmx/pom.xml index 65bbc43ce..13bb9c183 100644 --- a/tests/test-nima-htmx/pom.xml +++ b/tests/test-nima-htmx/pom.xml @@ -15,7 +15,7 @@ 21 UTF-8 false - 1.3.5 + 1.3.6 From d6ff4598eab5ddff0a808c538ca963bb9671cd48 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Aug 2024 19:42:56 +0000 Subject: [PATCH 1140/1323] Bump org.apache.maven.plugins:maven-compiler-plugin Bumps [org.apache.maven.plugins:maven-compiler-plugin](https://github.com/apache/maven-compiler-plugin) from 3.11.0 to 3.13.0. - [Release notes](https://github.com/apache/maven-compiler-plugin/releases) - [Commits](https://github.com/apache/maven-compiler-plugin/compare/maven-compiler-plugin-3.11.0...maven-compiler-plugin-3.13.0) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-compiler-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- tests/test-nima-htmx/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test-nima-htmx/pom.xml b/tests/test-nima-htmx/pom.xml index 13bb9c183..61e6903f6 100644 --- a/tests/test-nima-htmx/pom.xml +++ b/tests/test-nima-htmx/pom.xml @@ -65,7 +65,7 @@ org.apache.maven.plugins maven-compiler-plugin - 3.11.0 + 3.13.0 21 From 7bf886d4ea1b863074ca133b5024fdcd728122e0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Aug 2024 19:44:55 +0000 Subject: [PATCH 1141/1323] Bump io.avaje:avaje-jsonb-generator from 1.11 to 2.1 Bumps io.avaje:avaje-jsonb-generator from 1.11 to 2.1. --- updated-dependencies: - dependency-name: io.avaje:avaje-jsonb-generator dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- tests/test-nima-htmx/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test-nima-htmx/pom.xml b/tests/test-nima-htmx/pom.xml index 61e6903f6..30dc21e50 100644 --- a/tests/test-nima-htmx/pom.xml +++ b/tests/test-nima-htmx/pom.xml @@ -82,7 +82,7 @@ io.avaje avaje-jsonb-generator - 1.11 + 2.1 io.jstach From 440c3c0875421bcbdda452c3ec6ba7eea7585acc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Aug 2024 19:46:58 +0000 Subject: [PATCH 1142/1323] Bump io.avaje:avaje-lang from 1.0 to 1.1 Bumps [io.avaje:avaje-lang](https://github.com/avaje/avaje-lang) from 1.0 to 1.1. - [Commits](https://github.com/avaje/avaje-lang/commits) --- updated-dependencies: - dependency-name: io.avaje:avaje-lang dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- htmx-api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htmx-api/pom.xml b/htmx-api/pom.xml index 9f086a835..8bdc810c5 100644 --- a/htmx-api/pom.xml +++ b/htmx-api/pom.xml @@ -18,7 +18,7 @@ io.avaje avaje-lang - 1.0 + 1.1 From dae77f899e79b75d3e96105d83c189e46ae40947 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Aug 2024 19:49:02 +0000 Subject: [PATCH 1143/1323] Bump nima.version from 4.0.7 to 4.1.0 Bumps `nima.version` from 4.0.7 to 4.1.0. Updates `io.helidon.webserver:helidon-webserver` from 4.0.7 to 4.1.0 Updates `io.helidon.http.media:helidon-http-media-jsonb` from 4.0.11 to 4.1.0 --- updated-dependencies: - dependency-name: io.helidon.webserver:helidon-webserver dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: io.helidon.http.media:helidon-http-media-jsonb dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- htmx-nima/pom.xml | 2 +- tests/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/htmx-nima/pom.xml b/htmx-nima/pom.xml index 89c2870f3..0598cec23 100644 --- a/htmx-nima/pom.xml +++ b/htmx-nima/pom.xml @@ -26,7 +26,7 @@ io.helidon.webserver helidon-webserver - 4.0.7 + 4.1.0 diff --git a/tests/pom.xml b/tests/pom.xml index 7082e7330..d1ab571ab 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -17,7 +17,7 @@ 2.17.2 2.5 10.3 - 4.0.11 + 4.1.0 6.2.0 From 03340f051cb281c9d0646af3afb90a15c678f6fb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Aug 2024 19:51:04 +0000 Subject: [PATCH 1144/1323] Bump junit.version from 5.10.3 to 5.11.0 Bumps `junit.version` from 5.10.3 to 5.11.0. Updates `org.junit.jupiter:junit-jupiter-api` from 5.10.3 to 5.11.0 - [Release notes](https://github.com/junit-team/junit5/releases) - [Commits](https://github.com/junit-team/junit5/compare/r5.10.3...r5.11.0) Updates `org.junit.jupiter:junit-jupiter-engine` from 5.10.3 to 5.11.0 - [Release notes](https://github.com/junit-team/junit5/releases) - [Commits](https://github.com/junit-team/junit5/compare/r5.10.3...r5.11.0) --- updated-dependencies: - dependency-name: org.junit.jupiter:junit-jupiter-api dependency-type: direct:development update-type: version-update:semver-minor - dependency-name: org.junit.jupiter:junit-jupiter-engine dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- tests/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/pom.xml b/tests/pom.xml index d1ab571ab..a7c1889be 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -12,7 +12,7 @@ true - 5.10.3 + 5.11.0 3.26.3 2.17.2 2.5 From d6c442ed440d4a9524a2b0b3287042590738d1b7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 Aug 2024 19:12:10 +0000 Subject: [PATCH 1145/1323] Bump io.javalin:javalin from 6.2.0 to 6.3.0 Bumps [io.javalin:javalin](https://github.com/javalin/javalin) from 6.2.0 to 6.3.0. - [Release notes](https://github.com/javalin/javalin/releases) - [Commits](https://github.com/javalin/javalin/compare/javalin-parent-6.2.0...javalin-parent-6.3.0) --- updated-dependencies: - dependency-name: io.javalin:javalin dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- http-api/pom.xml | 2 +- http-client/pom.xml | 2 +- tests/pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/http-api/pom.xml b/http-api/pom.xml index b8a425108..80efe5d32 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -24,7 +24,7 @@ io.javalin javalin - 6.2.0 + 6.3.0 provided true diff --git a/http-client/pom.xml b/http-client/pom.xml index d05286f04..c7562cc9c 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -59,7 +59,7 @@ io.javalin javalin - 6.2.0 + 6.3.0 test diff --git a/tests/pom.xml b/tests/pom.xml index a7c1889be..e5b424de8 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -18,7 +18,7 @@ 2.5 10.3 4.1.0 - 6.2.0 + 6.3.0 From ea4d1e8d3f0fb252bde704b36ccbef2558386fb8 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Mon, 26 Aug 2024 16:35:41 -0400 Subject: [PATCH 1146/1323] Use Non-Deprecated Inject Plugin (#491) * Use non-deprecated Inject Plugin * fix module * restore EA * Update jdk-ea-stable.yml * Revert "Disable EA stable build (as download broken)" This reverts commit 62e717e285c5fdf22c036e9c5b050735c3ca77e4. * Update DefaultResolverProvider.java * correctly register the spis * Update module-info.java --- .github/workflows/jdk-ea-stable.yml | 8 ++++---- htmx-nima-jstache/pom.xml | 7 +++++++ .../avaje/htmx/nima/jstache/DefaultTemplateProvider.java | 6 ++++-- htmx-nima-jstache/src/main/java/module-info.java | 5 +++-- .../META-INF/services/io.avaje.inject.spi.Plugin | 1 - http-inject-plugin/pom.xml | 9 ++++++++- .../io/avaje/http/inject/DefaultResolverProvider.java | 6 ++++-- http-inject-plugin/src/main/java/module-info.java | 8 ++++---- .../META-INF/services/io.avaje.inject.spi.Plugin | 1 - pom.xml | 2 +- tests/pom.xml | 2 +- 11 files changed, 36 insertions(+), 19 deletions(-) delete mode 100644 htmx-nima-jstache/src/main/resources/META-INF/services/io.avaje.inject.spi.Plugin delete mode 100644 http-inject-plugin/src/main/resources/META-INF/services/io.avaje.inject.spi.Plugin diff --git a/.github/workflows/jdk-ea-stable.yml b/.github/workflows/jdk-ea-stable.yml index 6f2383e62..a6c44f00f 100644 --- a/.github/workflows/jdk-ea-stable.yml +++ b/.github/workflows/jdk-ea-stable.yml @@ -2,11 +2,11 @@ name: JDK EA Stable on: + push: + pull_request: workflow_dispatch: -# push: -# pull_request: -# schedule: -# - cron: '39 1 * * 1,3,5' + schedule: + - cron: '39 1 * * 1,3,5' jobs: build: diff --git a/htmx-nima-jstache/pom.xml b/htmx-nima-jstache/pom.xml index 86faa8892..522c21397 100644 --- a/htmx-nima-jstache/pom.xml +++ b/htmx-nima-jstache/pom.xml @@ -43,5 +43,12 @@ provided true + + io.avaje + avaje-spi-service + 2.5 + provided + true +
    diff --git a/htmx-nima-jstache/src/main/java/io/avaje/htmx/nima/jstache/DefaultTemplateProvider.java b/htmx-nima-jstache/src/main/java/io/avaje/htmx/nima/jstache/DefaultTemplateProvider.java index 41fc8161e..c74e0f617 100644 --- a/htmx-nima-jstache/src/main/java/io/avaje/htmx/nima/jstache/DefaultTemplateProvider.java +++ b/htmx-nima-jstache/src/main/java/io/avaje/htmx/nima/jstache/DefaultTemplateProvider.java @@ -3,12 +3,14 @@ import io.avaje.htmx.nima.TemplateContentCache; import io.avaje.htmx.nima.TemplateRender; import io.avaje.inject.BeanScopeBuilder; -import io.avaje.inject.spi.Plugin; +import io.avaje.inject.spi.InjectPlugin; +import io.avaje.spi.ServiceProvider; /** * Plugin for avaje inject that provides a default TemplateRender instance. */ -public final class DefaultTemplateProvider implements Plugin { +@ServiceProvider +public final class DefaultTemplateProvider implements InjectPlugin { @Override public Class[] provides() { diff --git a/htmx-nima-jstache/src/main/java/module-info.java b/htmx-nima-jstache/src/main/java/module-info.java index 2da4668b1..88d587079 100644 --- a/htmx-nima-jstache/src/main/java/module-info.java +++ b/htmx-nima-jstache/src/main/java/module-info.java @@ -5,7 +5,8 @@ requires transitive io.avaje.htmx.nima; requires transitive io.helidon.webserver; requires transitive io.jstach.jstachio; - requires io.avaje.inject; + requires transitive io.avaje.inject; + requires static io.avaje.spi; - provides io.avaje.inject.spi.Plugin with io.avaje.htmx.nima.jstache.DefaultTemplateProvider; + provides io.avaje.inject.spi.InjectExtension with io.avaje.htmx.nima.jstache.DefaultTemplateProvider; } diff --git a/htmx-nima-jstache/src/main/resources/META-INF/services/io.avaje.inject.spi.Plugin b/htmx-nima-jstache/src/main/resources/META-INF/services/io.avaje.inject.spi.Plugin deleted file mode 100644 index 456aa71f2..000000000 --- a/htmx-nima-jstache/src/main/resources/META-INF/services/io.avaje.inject.spi.Plugin +++ /dev/null @@ -1 +0,0 @@ -io.avaje.htmx.nima.jstache.DefaultTemplateProvider diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index d13cf8290..a21ecbe9f 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -26,10 +26,17 @@ io.avaje avaje-http-api - 1.37 + 2.7 true provided + + io.avaje + avaje-spi-service + 2.5 + provided + true + diff --git a/http-inject-plugin/src/main/java/io/avaje/http/inject/DefaultResolverProvider.java b/http-inject-plugin/src/main/java/io/avaje/http/inject/DefaultResolverProvider.java index 56b5ad2f2..b22eb7714 100644 --- a/http-inject-plugin/src/main/java/io/avaje/http/inject/DefaultResolverProvider.java +++ b/http-inject-plugin/src/main/java/io/avaje/http/inject/DefaultResolverProvider.java @@ -3,10 +3,12 @@ import io.avaje.http.api.context.RequestContextResolver; import io.avaje.http.api.context.ThreadLocalRequestContextResolver; import io.avaje.inject.BeanScopeBuilder; -import io.avaje.inject.spi.Plugin; +import io.avaje.inject.spi.InjectPlugin; +import io.avaje.spi.ServiceProvider; /** Plugin for avaje inject that provides a default RequestContextResolver instance. */ -public final class DefaultResolverProvider implements Plugin { +@ServiceProvider +public final class DefaultResolverProvider implements InjectPlugin { @Override public Class[] provides() { diff --git a/http-inject-plugin/src/main/java/module-info.java b/http-inject-plugin/src/main/java/module-info.java index c8149f2fe..e13c5e735 100644 --- a/http-inject-plugin/src/main/java/module-info.java +++ b/http-inject-plugin/src/main/java/module-info.java @@ -1,8 +1,8 @@ module io.avaje.http.plugin { - requires io.avaje.http.api; - requires io.avaje.inject; - - provides io.avaje.inject.spi.Plugin with io.avaje.http.inject.DefaultResolverProvider; + requires io.avaje.http.api; + requires io.avaje.inject; + requires static io.avaje.spi; + provides io.avaje.inject.spi.InjectExtension with io.avaje.http.inject.DefaultResolverProvider; } diff --git a/http-inject-plugin/src/main/resources/META-INF/services/io.avaje.inject.spi.Plugin b/http-inject-plugin/src/main/resources/META-INF/services/io.avaje.inject.spi.Plugin deleted file mode 100644 index d996e4e0c..000000000 --- a/http-inject-plugin/src/main/resources/META-INF/services/io.avaje.inject.spi.Plugin +++ /dev/null @@ -1 +0,0 @@ -io.avaje.http.inject.DefaultResolverProvider diff --git a/pom.xml b/pom.xml index 05a50c367..7a9ea7749 100644 --- a/pom.xml +++ b/pom.xml @@ -61,7 +61,7 @@ jdk21plus - [21,22] + [21,) htmx-nima diff --git a/tests/pom.xml b/tests/pom.xml index e5b424de8..cdec44f34 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -33,7 +33,7 @@ jdk21plus - [21,22] + [21,) test-nima From ff89af5f07eb01dffcba5fd392b2af82f56480a4 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Tue, 27 Aug 2024 01:46:42 -0400 Subject: [PATCH 1147/1323] Update Dependabot Grouping (#493) Now dependabot should create a single PR for all the dependencies. [Example PR](https://github.com/SentryMan/avaje-javalin-api-example/pull/50) --- .github/dependabot.yml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index de2383d88..8178f9917 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -3,13 +3,16 @@ updates: - package-ecosystem: "maven" directory: "/" schedule: - interval: "weekly" + interval: weekly open-pull-requests-limit: 10 + groups: + dependencies: + patterns: + - "*" labels: - "dependencies" target-branch: "master" - - package-ecosystem: "github-actions" directory: "/" schedule: From da2b3f10b16b4de1907a5b0e907ad8fa8aa8ff73 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 27 Aug 2024 05:47:38 +0000 Subject: [PATCH 1148/1323] Bump io.avaje:avaje-spi-service in the dependencies group Bumps the dependencies group with 1 update: io.avaje:avaje-spi-service. Updates `io.avaje:avaje-spi-service` from 2.5 to 2.6 --- updated-dependencies: - dependency-name: io.avaje:avaje-spi-service dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies ... Signed-off-by: dependabot[bot] --- htmx-nima-jstache/pom.xml | 2 +- http-inject-plugin/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/htmx-nima-jstache/pom.xml b/htmx-nima-jstache/pom.xml index 522c21397..fa0592ddd 100644 --- a/htmx-nima-jstache/pom.xml +++ b/htmx-nima-jstache/pom.xml @@ -46,7 +46,7 @@ io.avaje avaje-spi-service - 2.5 + 2.6 provided true diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index a21ecbe9f..91e9da057 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -33,7 +33,7 @@ io.avaje avaje-spi-service - 2.5 + 2.6 provided true From e2b71773ec16c51d0a89fb3de82c7dacb67d4d5e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Sep 2024 19:50:37 +0000 Subject: [PATCH 1149/1323] Bump the dependencies group with 3 updates Bumps the dependencies group with 3 updates: [org.avaje:java11-oss](https://github.com/avaje-pom/java11-oss), io.swagger.core.v3:swagger-annotations and io.swagger.core.v3:swagger-models. Updates `org.avaje:java11-oss` from 4.3 to 4.4 - [Release notes](https://github.com/avaje-pom/java11-oss/releases) - [Commits](https://github.com/avaje-pom/java11-oss/commits) Updates `io.swagger.core.v3:swagger-annotations` from 2.2.22 to 2.2.23 Updates `io.swagger.core.v3:swagger-models` from 2.2.22 to 2.2.23 Updates `io.swagger.core.v3:swagger-models` from 2.2.22 to 2.2.23 --- updated-dependencies: - dependency-name: org.avaje:java11-oss dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.swagger.core.v3:swagger-annotations dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: io.swagger.core.v3:swagger-models dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: io.swagger.core.v3:swagger-models dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies ... Signed-off-by: dependabot[bot] --- pom.xml | 4 ++-- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index 7a9ea7749..e569bebd2 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ org.avaje java11-oss - 4.3 + 4.4 io.avaje @@ -19,7 +19,7 @@ true - 2.2.22 + 2.2.23 2.14.2 1.31 ${project.build.directory}${file.separator}module-info.shade diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index d130f7a8e..d910cbb86 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -13,7 +13,7 @@ true org.example.myapp.Main - 2.2.22 + 2.2.23 1.3.71 diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index ee0919f27..925384baf 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -12,7 +12,7 @@ true org.example.myapp.Main - 2.2.22 + 2.2.23 1.3.71 diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 7625ec2e8..dc6834c5f 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -13,7 +13,7 @@ true org.example.myapp.Main 2.5 - 2.2.22 + 2.2.23 From 295a23e38ff1ef8d08abbf2a063f8c414d7e00f2 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sat, 7 Sep 2024 18:06:47 -0400 Subject: [PATCH 1150/1323] Add Sigma Lambda Generator (#498) * start * complete generator * rename routing * test * fix compilation * Update HealthController.java * Update pom.xml --- http-generator-sigma/pom.xml | 31 +++ .../src/etc/activate-shade-module | 1 + .../sigma/ControllerMethodWriter.java | 128 ++++++++++++ .../generator/sigma/ControllerWriter.java | 92 +++++++++ .../http/generator/sigma/SigmaAdapter.java | 141 +++++++++++++ .../http/generator/sigma/SigmaProcessor.java | 24 +++ .../http/generator/sigma/SigmaWebMethod.java | 21 ++ .../src/main/java/module-info.java | 12 ++ pom.xml | 1 + tests/pom.xml | 1 + tests/test-javalin-jsonb/avaje-processors.txt | 1 + .../io.avaje.jsonb.spi.JsonbExtension | 1 + tests/test-sigma/.gitignore | 5 + tests/test-sigma/README.md | 7 + tests/test-sigma/pom.xml | 133 ++++++++++++ .../org/example/myapp/service/BazRepo.java | 31 +++ .../example/myapp/service/MyDependency.java | 11 + .../org/example/myapp/service/MyService.java | 20 ++ .../main/java/org/example/myapp/web/Bar.java | 10 + .../org/example/myapp/web/BarController.java | 28 +++ .../org/example/myapp/web/BarInterface.java | 25 +++ .../org/example/myapp/web/BaseController.java | 31 +++ .../main/java/org/example/myapp/web/Baz.java | 15 ++ .../org/example/myapp/web/BazController.java | 43 ++++ .../org/example/myapp/web/GetBeanForm.java | 88 ++++++++ .../java/org/example/myapp/web/Hallo.java | 13 ++ .../example/myapp/web/HelloController.java | 190 ++++++++++++++++++ .../java/org/example/myapp/web/HelloDto.java | 56 ++++++ .../java/org/example/myapp/web/HelloForm.java | 83 ++++++++ .../org/example/myapp/web/Repository.java | 13 ++ .../example/myapp/web/SecurityController.java | 22 ++ .../org/example/myapp/web/ServerType.java | 7 + .../java/org/example/myapp/web/other/Foo.java | 7 + .../example/myapp/web/test/ErrorResponse.java | 7 + .../myapp/web/test/HealthController.java | 30 +++ .../myapp/web/test/HealthControllerImpl.java | 13 ++ .../org/example/myapp/web/test/MyForm.java | 8 + .../myapp/web/test/OpenAPIController.java | 102 ++++++++++ .../org/example/myapp/web/test/Person.java | 31 +++ .../myapp/web/test/TestController.java | 130 ++++++++++++ .../myapp/web/test/TestController2.java | 95 +++++++++ .../test-sigma/src/main/resources/logback.xml | 18 ++ .../http/generator/SigmaProcessorTest.java | 102 ++++++++++ .../src/test/resources/application-test.yaml | 6 + .../src/test/resources/logback-test.xml | 19 ++ 45 files changed, 1853 insertions(+) create mode 100644 http-generator-sigma/pom.xml create mode 100644 http-generator-sigma/src/etc/activate-shade-module create mode 100644 http-generator-sigma/src/main/java/io/avaje/http/generator/sigma/ControllerMethodWriter.java create mode 100644 http-generator-sigma/src/main/java/io/avaje/http/generator/sigma/ControllerWriter.java create mode 100644 http-generator-sigma/src/main/java/io/avaje/http/generator/sigma/SigmaAdapter.java create mode 100644 http-generator-sigma/src/main/java/io/avaje/http/generator/sigma/SigmaProcessor.java create mode 100644 http-generator-sigma/src/main/java/io/avaje/http/generator/sigma/SigmaWebMethod.java create mode 100644 http-generator-sigma/src/main/java/module-info.java create mode 100644 tests/test-javalin-jsonb/avaje-processors.txt create mode 100644 tests/test-javalin-jsonb/io.avaje.jsonb.spi.JsonbExtension create mode 100644 tests/test-sigma/.gitignore create mode 100644 tests/test-sigma/README.md create mode 100644 tests/test-sigma/pom.xml create mode 100644 tests/test-sigma/src/main/java/org/example/myapp/service/BazRepo.java create mode 100644 tests/test-sigma/src/main/java/org/example/myapp/service/MyDependency.java create mode 100644 tests/test-sigma/src/main/java/org/example/myapp/service/MyService.java create mode 100644 tests/test-sigma/src/main/java/org/example/myapp/web/Bar.java create mode 100644 tests/test-sigma/src/main/java/org/example/myapp/web/BarController.java create mode 100644 tests/test-sigma/src/main/java/org/example/myapp/web/BarInterface.java create mode 100644 tests/test-sigma/src/main/java/org/example/myapp/web/BaseController.java create mode 100644 tests/test-sigma/src/main/java/org/example/myapp/web/Baz.java create mode 100644 tests/test-sigma/src/main/java/org/example/myapp/web/BazController.java create mode 100644 tests/test-sigma/src/main/java/org/example/myapp/web/GetBeanForm.java create mode 100644 tests/test-sigma/src/main/java/org/example/myapp/web/Hallo.java create mode 100644 tests/test-sigma/src/main/java/org/example/myapp/web/HelloController.java create mode 100644 tests/test-sigma/src/main/java/org/example/myapp/web/HelloDto.java create mode 100644 tests/test-sigma/src/main/java/org/example/myapp/web/HelloForm.java create mode 100644 tests/test-sigma/src/main/java/org/example/myapp/web/Repository.java create mode 100644 tests/test-sigma/src/main/java/org/example/myapp/web/SecurityController.java create mode 100644 tests/test-sigma/src/main/java/org/example/myapp/web/ServerType.java create mode 100644 tests/test-sigma/src/main/java/org/example/myapp/web/other/Foo.java create mode 100644 tests/test-sigma/src/main/java/org/example/myapp/web/test/ErrorResponse.java create mode 100644 tests/test-sigma/src/main/java/org/example/myapp/web/test/HealthController.java create mode 100644 tests/test-sigma/src/main/java/org/example/myapp/web/test/HealthControllerImpl.java create mode 100644 tests/test-sigma/src/main/java/org/example/myapp/web/test/MyForm.java create mode 100644 tests/test-sigma/src/main/java/org/example/myapp/web/test/OpenAPIController.java create mode 100644 tests/test-sigma/src/main/java/org/example/myapp/web/test/Person.java create mode 100644 tests/test-sigma/src/main/java/org/example/myapp/web/test/TestController.java create mode 100644 tests/test-sigma/src/main/java/org/example/myapp/web/test/TestController2.java create mode 100644 tests/test-sigma/src/main/resources/logback.xml create mode 100644 tests/test-sigma/src/test/java/io/avaje/http/generator/SigmaProcessorTest.java create mode 100644 tests/test-sigma/src/test/resources/application-test.yaml create mode 100644 tests/test-sigma/src/test/resources/logback-test.xml diff --git a/http-generator-sigma/pom.xml b/http-generator-sigma/pom.xml new file mode 100644 index 000000000..77014be46 --- /dev/null +++ b/http-generator-sigma/pom.xml @@ -0,0 +1,31 @@ + + + 4.0.0 + + io.avaje + avaje-http-parent + 2.8-RC1 + + + avaje-http-sigma-generator + + + 17 + UTF-8 + + + + + io.avaje + avaje-http-generator-core + ${project.version} + + + + io.avaje + avaje-prisms + ${avaje.prisms.version} + provided + + + diff --git a/http-generator-sigma/src/etc/activate-shade-module b/http-generator-sigma/src/etc/activate-shade-module new file mode 100644 index 000000000..949f3d244 --- /dev/null +++ b/http-generator-sigma/src/etc/activate-shade-module @@ -0,0 +1 @@ +Remove from module-info all content after: // SHADED: diff --git a/http-generator-sigma/src/main/java/io/avaje/http/generator/sigma/ControllerMethodWriter.java b/http-generator-sigma/src/main/java/io/avaje/http/generator/sigma/ControllerMethodWriter.java new file mode 100644 index 000000000..787820979 --- /dev/null +++ b/http-generator-sigma/src/main/java/io/avaje/http/generator/sigma/ControllerMethodWriter.java @@ -0,0 +1,128 @@ +package io.avaje.http.generator.sigma; + +import static io.avaje.http.generator.core.ProcessingContext.*; + +import java.util.List; + +import io.avaje.http.generator.core.*; +import io.avaje.http.generator.core.openapi.MediaType; + +/** Write code to register Web route for a given controller method. */ +class ControllerMethodWriter { + + private final MethodReader method; + private final Append writer; + private final WebMethod webMethod; + private final boolean instrumentContext; + private final boolean customMethod; + + ControllerMethodWriter(MethodReader method, Append writer) { + this.method = method; + this.writer = writer; + final var webM = method.webMethod(); + this.webMethod = webM == CoreWebMethod.FILTER ? SigmaWebMethod.BEFORE : webM; + this.instrumentContext = method.instrumentContext(); + customMethod = !(webMethod instanceof CoreWebMethod); + } + + void write() { + final var segments = method.pathSegments(); + final var fullPath = segments.fullPath(); + + writeMethod(fullPath); + + final var params = writeParams(segments); + writer.append(" "); + if (!method.isVoid() && !customMethod) { + writer.append("var result = "); + } + + if (instrumentContext) { + method.writeContext(writer, "ctx", "ctx"); + } + + writer.append("controller."); + + writer.append(method.simpleName()).append("("); + for (var i = 0; i < params.size(); i++) { + if (i > 0) { + writer.append(", "); + } + final var param = params.get(i); + if (isAssignable2Interface(param.utype().mainType(), "java.lang.Exception")) { + writer.append("ex"); + } else { + param.buildParamName(writer); + } + } + + if (instrumentContext) { + writer.append(")"); + } + + writer.append(");").eol(); + if (!method.isVoid() && !customMethod) { + writeContextReturn(); + writer.eol(); + } + + writer.append(" }"); + writer.append(");").eol().eol(); + } + + private void writeMethod(final String fullPath) { + if (method.isErrorMethod()) { + writer + .append(" router.exception(%s.class, (ex, ctx) -> {", method.exceptionShortName()) + .eol(); + } else { + var methodName = webMethod.name().toLowerCase().replace("_m", "M"); + writer.append(" router.%s(\"%s\", ctx -> {", methodName, fullPath).eol(); + } + if (!customMethod) { + int statusCode = method.statusCode(); + if (statusCode > 0) { + writer.append(" ctx.status(%d);", statusCode).eol(); + } + } + } + + private List writeParams(final PathSegments segments) { + final var matrixSegments = segments.matrixSegments(); + for (final PathSegments.Segment matrixSegment : matrixSegments) { + matrixSegment.writeCreateSegment(writer, platform()); + } + + final var params = method.params(); + for (final MethodParam param : params) { + if (!isAssignable2Interface(param.utype().mainType(), "java.lang.Exception")) { + param.writeCtxGet(writer, segments); + } + } + if (method.includeValidate()) { + for (final MethodParam param : params) { + param.writeValidate(writer); + } + } + return params; + } + + private void writeContextReturn() { + var produces = method.produces(); + boolean applicationJson = + produces == null || MediaType.APPLICATION_JSON.getValue().equalsIgnoreCase(produces); + if (applicationJson || JsonBUtil.isJsonMimeType(produces)) { + if (applicationJson) { + writer.append(" ctx.json(result);"); + } else { + writer.append(" ctx.contentType(\"%s\").result(result);", produces); + } + } else if (MediaType.TEXT_HTML.getValue().equalsIgnoreCase(produces)) { + writer.append(" ctx.html(result);"); + } else if (MediaType.TEXT_PLAIN.getValue().equalsIgnoreCase(produces)) { + writer.append(" ctx.text(result);"); + } else { + writer.append(" ctx.contentType(\"%s\").result(%s);", produces); + } + } +} diff --git a/http-generator-sigma/src/main/java/io/avaje/http/generator/sigma/ControllerWriter.java b/http-generator-sigma/src/main/java/io/avaje/http/generator/sigma/ControllerWriter.java new file mode 100644 index 000000000..f0ec980df --- /dev/null +++ b/http-generator-sigma/src/main/java/io/avaje/http/generator/sigma/ControllerWriter.java @@ -0,0 +1,92 @@ +package io.avaje.http.generator.sigma; + +import static io.avaje.http.generator.core.ProcessingContext.diAnnotation; + +import java.io.IOException; + +import io.avaje.http.generator.core.BaseControllerWriter; +import io.avaje.http.generator.core.ControllerReader; +import io.avaje.http.generator.core.MethodReader; + +/** + * Write Sigma specific Controller WebRoute handling adapter. + */ +class ControllerWriter extends BaseControllerWriter { + + private static final String AT_GENERATED = "@Generated(\"avaje-sigma-generator\")"; + + ControllerWriter(ControllerReader reader) throws IOException { + super(reader); + reader.addImportType("io.avaje.sigma.HttpService"); + reader.addImportType("io.avaje.sigma.Router"); + } + + void write() { + writePackage(); + writeImports(); + writeClassStart(); + writeAddRoutes(); + writeClassEnd(); + } + + private void writeAddRoutes() { + writer.append(" @Override").eol(); + writer.append(" public void setup(Router router) {").eol().eol(); + + + for (final MethodReader method : reader.methods()) { + if (method.isWebMethod()) { + writeForMethod(method); + } + } + writer.append(" }").eol().eol(); + } + + private void writeForMethod(MethodReader method) { + new ControllerMethodWriter(method, writer).write(); + if (!reader.isDocHidden()) { + method.buildApiDocumentation(); + } + } + + private void writeClassStart() { + writer.append(AT_GENERATED).eol(); + writer.append(diAnnotation()).eol(); + writer + .append("public class ") + .append(shortName) + .append("$Route implements HttpService {") + .eol() + .eol(); + + var controllerName = "controller"; + var controllerType = shortName; + writer.append(" private final %s %s;", controllerType, controllerName).eol(); + + if (reader.isIncludeValidator()) { + writer.append(" private final Validator validator;").eol(); + } + + if (instrumentContext) { + writer.append(" private final RequestContextResolver resolver;").eol(); + } + writer.eol(); + + writer.append(" public %s$Route(%s %s", shortName, controllerType, controllerName); + if (reader.isIncludeValidator()) { + writer.append(", Validator validator"); + } + if (instrumentContext) { + writer.append(", RequestContextResolver resolver"); + } + writer.append(") {").eol(); + writer.append(" this.%s = %s;", controllerName, controllerName).eol(); + if (reader.isIncludeValidator()) { + writer.append(" this.validator = validator;").eol(); + } + if (instrumentContext) { + writer.append(" this.resolver = resolver;").eol(); + } + writer.append(" }").eol().eol(); + } +} diff --git a/http-generator-sigma/src/main/java/io/avaje/http/generator/sigma/SigmaAdapter.java b/http-generator-sigma/src/main/java/io/avaje/http/generator/sigma/SigmaAdapter.java new file mode 100644 index 000000000..4b45afc7e --- /dev/null +++ b/http-generator-sigma/src/main/java/io/avaje/http/generator/sigma/SigmaAdapter.java @@ -0,0 +1,141 @@ +package io.avaje.http.generator.sigma; + +import java.util.List; +import java.util.Optional; +import java.util.function.Function; + +import javax.lang.model.element.Element; + +import io.avaje.http.generator.core.Append; +import io.avaje.http.generator.core.Constants; +import io.avaje.http.generator.core.ControllerReader; +import io.avaje.http.generator.core.CustomWebMethod; +import io.avaje.http.generator.core.ParamType; +import io.avaje.http.generator.core.PlatformAdapter; +import io.avaje.http.generator.core.UType; + +class SigmaAdapter implements PlatformAdapter { + + static final String CONTEXT = "io.avaje.sigma.HttpContext"; + + @Override + public boolean isContextType(String rawType) { + return CONTEXT.equals(rawType); + } + + @Override + public String platformVariable(String rawType) { + return "ctx"; + } + + @Override + public boolean isBodyMethodParam() { + return false; + } + + @Override + public String bodyAsClass(UType type) { + if ("java.lang.String".equals(type.full())) { + return "ctx.body()"; + } else { + return "ctx.bodyAsClass(" + type.mainType() + ".class)"; + } + } + + @Override + public String indent() { + return " "; + } + + @Override + public void writeReadParameter(Append writer, ParamType paramType, String paramName) { + writer.append("ctx.%s(\"%s\")", paramType, paramName); + } + + @Override + public void writeReadParameter(Append writer, ParamType paramType, String paramName, String paramDefault) { + writer.append("withDefault(ctx.%s(\"%s\"), \"%s\")", paramType, paramName, paramDefault); + } + + @Override + public void writeReadMapParameter(Append writer, ParamType paramType) { + + switch (paramType) { + case QUERYPARAM: + writer.append("ctx.queryParamMap()"); + break; + case FORM: + case FORMPARAM: + writer.append("ctx.formParamMap()"); + break; + default: + throw new UnsupportedOperationException( + "Only Query/Form Params have Map> supported in Javalin"); + } + } + + @Override + public void writeReadCollectionParameter(Append writer, ParamType paramType, String paramName) { + switch (paramType) { + case QUERYPARAM: + writer.append("ctx.queryParams(\"%s\")", paramName); + break; + case HEADER: + writer.append("ctx.headers(\"%s\")", paramName); + break; + case FORMPARAM: + writer.append("ctx.formParams(\"%s\")", paramName); + break; + default: + throw new UnsupportedOperationException( + "Only MultiValue Form/Query Params are supported in Javalin"); + } + } + + @Override + public void writeReadCollectionParameter( + Append writer, ParamType paramType, String paramName, List paramDefault) { + + switch (paramType) { + case QUERYPARAM: + writer.append( + "withDefault(ctx.queryParams(\"%s\"), java.util.List.of(\"%s\"))", + paramName, String.join(",", paramDefault)); + break; + case HEADER: + writer.append( + "withDefault(ctx.headers(\"%s\"), java.util.List.of(\"%s\"))", + paramName, String.join(",", paramDefault)); + break; + case FORMPARAM: + writer.append( + "withDefault(ctx.formParams(\"%s\"), java.util.List.of(\"%s\"))", + paramName, String.join(",", paramDefault)); + break; + default: + throw new UnsupportedOperationException( + "Only MultiValue Form/Header/Query Params are supported in Javalin"); + } + } + + @Override + public void writeAcceptLanguage(Append writer) { + writer.append("ctx.header(\"%s\")", Constants.ACCEPT_LANGUAGE); + } + + @Override + public List>> customHandlers() { + + return List.of(); + } + + @Override + public void controllerRoles(List roles, ControllerReader controller) { + + } + + @Override + public void methodRoles(List roles, ControllerReader controller) { + + } +} diff --git a/http-generator-sigma/src/main/java/io/avaje/http/generator/sigma/SigmaProcessor.java b/http-generator-sigma/src/main/java/io/avaje/http/generator/sigma/SigmaProcessor.java new file mode 100644 index 000000000..9a79145b2 --- /dev/null +++ b/http-generator-sigma/src/main/java/io/avaje/http/generator/sigma/SigmaProcessor.java @@ -0,0 +1,24 @@ +package io.avaje.http.generator.sigma; + +import java.io.IOException; + +import javax.annotation.processing.Processor; + +import io.avaje.http.generator.core.BaseProcessor; +import io.avaje.http.generator.core.ControllerReader; +import io.avaje.http.generator.core.PlatformAdapter; +import io.avaje.spi.ServiceProvider; + +@ServiceProvider(Processor.class) +public class SigmaProcessor extends BaseProcessor { + + @Override + protected PlatformAdapter providePlatformAdapter() { + return new SigmaAdapter(); + } + + @Override + public void writeControllerAdapter(ControllerReader reader) throws IOException { + new ControllerWriter(reader).write(); + } +} diff --git a/http-generator-sigma/src/main/java/io/avaje/http/generator/sigma/SigmaWebMethod.java b/http-generator-sigma/src/main/java/io/avaje/http/generator/sigma/SigmaWebMethod.java new file mode 100644 index 000000000..471b00da4 --- /dev/null +++ b/http-generator-sigma/src/main/java/io/avaje/http/generator/sigma/SigmaWebMethod.java @@ -0,0 +1,21 @@ +package io.avaje.http.generator.sigma; + +import io.avaje.http.generator.core.WebMethod; + +public enum SigmaWebMethod implements WebMethod { + BEFORE(0), + BEFORE_MATCHED(0), + AFTER(0), + AFTER_MATCHED(0); + + private final int statusCode; + + SigmaWebMethod(int statusCode) { + this.statusCode = statusCode; + } + + @Override + public int statusCode(boolean isVoid) { + return statusCode; + } +} diff --git a/http-generator-sigma/src/main/java/module-info.java b/http-generator-sigma/src/main/java/module-info.java new file mode 100644 index 000000000..37c1b3fbb --- /dev/null +++ b/http-generator-sigma/src/main/java/module-info.java @@ -0,0 +1,12 @@ +module io.avaje.http.sigma.generator { + + provides javax.annotation.processing.Processor with io.avaje.http.generator.sigma.SigmaProcessor; + + requires java.compiler; + requires java.sql; + + // SHADED: All content after this line will be removed at package time + requires io.avaje.http.generator.core; + requires static io.avaje.prism; + requires static io.avaje.spi; +} diff --git a/pom.xml b/pom.xml index e569bebd2..a2333d507 100644 --- a/pom.xml +++ b/pom.xml @@ -45,6 +45,7 @@ http-generator-core http-generator-javalin http-generator-jex + http-generator-sigma http-generator-client diff --git a/tests/pom.xml b/tests/pom.xml index cdec44f34..0f7523f12 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -27,6 +27,7 @@ test-jex test-client test-client-generation + test-sigma diff --git a/tests/test-javalin-jsonb/avaje-processors.txt b/tests/test-javalin-jsonb/avaje-processors.txt new file mode 100644 index 000000000..6ee501129 --- /dev/null +++ b/tests/test-javalin-jsonb/avaje-processors.txt @@ -0,0 +1 @@ +avaje-jsonb-generator \ No newline at end of file diff --git a/tests/test-javalin-jsonb/io.avaje.jsonb.spi.JsonbExtension b/tests/test-javalin-jsonb/io.avaje.jsonb.spi.JsonbExtension new file mode 100644 index 000000000..05a41ae93 --- /dev/null +++ b/tests/test-javalin-jsonb/io.avaje.jsonb.spi.JsonbExtension @@ -0,0 +1 @@ +org.example.myapp.web.jsonb.GeneratedJsonComponent \ No newline at end of file diff --git a/tests/test-sigma/.gitignore b/tests/test-sigma/.gitignore new file mode 100644 index 000000000..0c9d542d8 --- /dev/null +++ b/tests/test-sigma/.gitignore @@ -0,0 +1,5 @@ +target/ +build/ +.idea/ +*.iml +.gradle diff --git a/tests/test-sigma/README.md b/tests/test-sigma/README.md new file mode 100644 index 000000000..7463daa77 --- /dev/null +++ b/tests/test-sigma/README.md @@ -0,0 +1,7 @@ +# example-javalin-java-jsonb + +Very simple Java Maven Javalin example with Avaje JsonB instead of Jackson. + +- Run the main method - org.example.myapp.Main + +- `curl http://localhost:7000/hello/42/Roberto?otherParam=banana` diff --git a/tests/test-sigma/pom.xml b/tests/test-sigma/pom.xml new file mode 100644 index 000000000..78e59fa6c --- /dev/null +++ b/tests/test-sigma/pom.xml @@ -0,0 +1,133 @@ + + + 4.0.0 + + io.avaje + tests + 2.8-RC1 + + + test-sigma + + + 17 + true + 2.2.23 + 1.3.71 + + + + + + org.avaje + logback + 1.0 + + + + io.avaje + avaje-sigma + 0.2 + + + + io.avaje + avaje-inject + ${avaje-inject.version} + + + + io.avaje + avaje-http-api + ${project.version} + + + + io.avaje + avaje-http-hibernate-validator + 3.5-RC3 + + + + io.swagger.core.v3 + swagger-annotations + ${swagger.version} + + + + + io.avaje + avaje-inject-generator + ${avaje-inject.version} + provided + + + + io.avaje + avaje-http-sigma-generator + ${project.version} + provided + + + + io.avaje + avaje-jsonb + 2.1 + + + io.avaje + avaje-jsonb-generator + 2.1 + provided + + + + + io.avaje + junit + 1.5 + test + + + + + app + + + + io.avaje + openapi-maven-plugin + 1.0 + + + main + process-classes + + openapi + + + + + + + io.repaint.maven + tiles-maven-plugin + 2.40 + true + + + org.avaje.tile:lib-classpath:1.1 + + + + + + + + + + HEAD + scm:git:git@github.com:avaje/avaje-http.git + + diff --git a/tests/test-sigma/src/main/java/org/example/myapp/service/BazRepo.java b/tests/test-sigma/src/main/java/org/example/myapp/service/BazRepo.java new file mode 100644 index 000000000..226df54b9 --- /dev/null +++ b/tests/test-sigma/src/main/java/org/example/myapp/service/BazRepo.java @@ -0,0 +1,31 @@ +package org.example.myapp.service; + +import org.example.myapp.web.Baz; +import org.example.myapp.web.Repository; + +import jakarta.inject.Singleton; +import java.util.ArrayList; +import java.util.List; + +@Singleton +public class BazRepo implements Repository { + + @Override + public Baz findById(Long id) { + Baz baz = new Baz(); + baz.id = id; + baz.name = "Baz" + id; + //baz.startDate = LocalDate.of(2020, 1, 1); + return baz; + } + + @Override + public List findAll() { + return new ArrayList<>(); + } + + @Override + public Long save(Baz bean) { + return 42L; + } +} diff --git a/tests/test-sigma/src/main/java/org/example/myapp/service/MyDependency.java b/tests/test-sigma/src/main/java/org/example/myapp/service/MyDependency.java new file mode 100644 index 000000000..394f48d76 --- /dev/null +++ b/tests/test-sigma/src/main/java/org/example/myapp/service/MyDependency.java @@ -0,0 +1,11 @@ +package org.example.myapp.service; + +import jakarta.inject.Singleton; + +@Singleton +public class MyDependency { + + public String hello() { + return "my dependency"; + } +} diff --git a/tests/test-sigma/src/main/java/org/example/myapp/service/MyService.java b/tests/test-sigma/src/main/java/org/example/myapp/service/MyService.java new file mode 100644 index 000000000..e21da48fa --- /dev/null +++ b/tests/test-sigma/src/main/java/org/example/myapp/service/MyService.java @@ -0,0 +1,20 @@ +package org.example.myapp.service; + +import org.example.myapp.web.HelloDto; + +import jakarta.inject.Singleton; +import java.util.ArrayList; +import java.util.List; + +@Singleton +public class MyService { + + public List findAll() { + + List list = new ArrayList<>(); + list.add(new HelloDto(12, "Jim", "asd")); + list.add(new HelloDto(13, "Spock", "456456")); + + return list; + } +} diff --git a/tests/test-sigma/src/main/java/org/example/myapp/web/Bar.java b/tests/test-sigma/src/main/java/org/example/myapp/web/Bar.java new file mode 100644 index 000000000..5d044cbf6 --- /dev/null +++ b/tests/test-sigma/src/main/java/org/example/myapp/web/Bar.java @@ -0,0 +1,10 @@ +package org.example.myapp.web; + +import io.avaje.jsonb.Json; + +@Json +public class Bar { + + public long id; + public String name; +} diff --git a/tests/test-sigma/src/main/java/org/example/myapp/web/BarController.java b/tests/test-sigma/src/main/java/org/example/myapp/web/BarController.java new file mode 100644 index 000000000..2c6e281e4 --- /dev/null +++ b/tests/test-sigma/src/main/java/org/example/myapp/web/BarController.java @@ -0,0 +1,28 @@ +package org.example.myapp.web; + +import io.avaje.http.api.Controller; + +import java.util.ArrayList; +import java.util.List; + +@Controller +public class BarController implements BarInterface { + + @Override + public Bar getById(long id) { + Bar bar = new Bar(); + bar.id = id; + bar.name = "Rob" + id; + return bar; + } + + @Override + public List findByCode(String code) { + return new ArrayList<>(); + } + + @Override + public String barMessage() { + return "Hello"; + } +} diff --git a/tests/test-sigma/src/main/java/org/example/myapp/web/BarInterface.java b/tests/test-sigma/src/main/java/org/example/myapp/web/BarInterface.java new file mode 100644 index 000000000..4572236ae --- /dev/null +++ b/tests/test-sigma/src/main/java/org/example/myapp/web/BarInterface.java @@ -0,0 +1,25 @@ +package org.example.myapp.web; + +import io.avaje.http.api.Get; +import io.avaje.http.api.MediaType; +import io.avaje.http.api.Path; +import io.avaje.http.api.Produces; +import io.swagger.v3.oas.annotations.links.Link; +import io.swagger.v3.oas.annotations.responses.ApiResponse; + +import java.util.List; + +@Path("/bars") +public interface BarInterface { + + @Get(":id") + @ApiResponse(links = @Link(name="find", ref ="/find/:code", description="find by code")) + Bar getById(long id); + + @Get("/find/:code") + List findByCode(String code); + + @Produces(MediaType.TEXT_PLAIN) + @Get + String barMessage(); +} diff --git a/tests/test-sigma/src/main/java/org/example/myapp/web/BaseController.java b/tests/test-sigma/src/main/java/org/example/myapp/web/BaseController.java new file mode 100644 index 000000000..d342015b6 --- /dev/null +++ b/tests/test-sigma/src/main/java/org/example/myapp/web/BaseController.java @@ -0,0 +1,31 @@ +package org.example.myapp.web; + +import io.avaje.http.api.Get; +import io.avaje.http.api.Post; + +import java.util.List; + +abstract class BaseController { + + protected final Repository repository; + + BaseController(Repository repository) { + this.repository = repository; + } + + @Get(":id") + T getById(I id) { + return repository.findById(id); + } + + @Get + List findAll() { + return repository.findAll(); + } + + @Post + I save(T bean) { + return repository.save(bean); + } + +} diff --git a/tests/test-sigma/src/main/java/org/example/myapp/web/Baz.java b/tests/test-sigma/src/main/java/org/example/myapp/web/Baz.java new file mode 100644 index 000000000..7fbf3d1fc --- /dev/null +++ b/tests/test-sigma/src/main/java/org/example/myapp/web/Baz.java @@ -0,0 +1,15 @@ +package org.example.myapp.web; + +import java.time.LocalDate; + +import io.avaje.jsonb.Json; +@Json +public class Baz { + + public Long id; + + public String name; + + public LocalDate startDate; + +} diff --git a/tests/test-sigma/src/main/java/org/example/myapp/web/BazController.java b/tests/test-sigma/src/main/java/org/example/myapp/web/BazController.java new file mode 100644 index 000000000..96923c60f --- /dev/null +++ b/tests/test-sigma/src/main/java/org/example/myapp/web/BazController.java @@ -0,0 +1,43 @@ +package org.example.myapp.web; + +import io.avaje.http.api.Controller; +import io.avaje.http.api.Get; +import io.avaje.http.api.Path; + +import java.util.Arrays; +import java.util.List; + +@Controller +@Path("/baz") +class BazController extends BaseController { + + BazController(Repository repository) { + super(repository); + } + + /** + * Find the baz by name. + *

    + * This is some more comments about this method. + * + * @return The list of baz + */ + @Get("findbyname/{name}") + List searchByName(String name) { + + Baz b1 = new Baz(); + b1.id = 1L; + b1.name = "baz1-" + name; + + Baz b2 = new Baz(); + b2.id = 2L; + b2.name = "baz2"; + + return Arrays.asList(b1, b2); + } + + @Get("checkparams/{id}") + String checkParams(int id, String p1, Double p2, Integer p3, Float p4, String body) { + return "dummy-response"; + } +} diff --git a/tests/test-sigma/src/main/java/org/example/myapp/web/GetBeanForm.java b/tests/test-sigma/src/main/java/org/example/myapp/web/GetBeanForm.java new file mode 100644 index 000000000..70818500d --- /dev/null +++ b/tests/test-sigma/src/main/java/org/example/myapp/web/GetBeanForm.java @@ -0,0 +1,88 @@ +package org.example.myapp.web; + +import java.util.List; +import java.util.Set; + +import io.avaje.http.api.Header; +import io.avaje.http.api.Ignore; +import io.avaje.http.api.QueryParam; +import io.avaje.jsonb.Json; +import jakarta.validation.Valid; +import jakarta.validation.constraints.Email; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; + +@Json +@Valid +public class GetBeanForm { + + @NotNull + @Size(min = 2, max = 150) + private String name; + + @Email + @Size(max = 100) + private String email; + + private List addresses; + + @Header private String head; + + @QueryParam private Set type; + + @Json.Ignore @Ignore private String ignored; + + public String getIgnored() { + return ignored; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public GetBeanForm(String name, String email) { + this.name = name; + this.email = email; + } + + @Override + public String toString() { + return "HelloForm{" + "name='" + name + '\'' + ", email='" + email + '\'' + '}'; + } + + public List getAddresses() { + return addresses; + } + + public void setAddresses(List addresses) { + this.addresses = addresses; + } + + public String getHead() { + return head; + } + + public void setHead(String head) { + this.head = head; + } + + public Set getType() { + return type; + } + + public void setType(Set type) { + this.type = type; + } +} diff --git a/tests/test-sigma/src/main/java/org/example/myapp/web/Hallo.java b/tests/test-sigma/src/main/java/org/example/myapp/web/Hallo.java new file mode 100644 index 000000000..441676e7b --- /dev/null +++ b/tests/test-sigma/src/main/java/org/example/myapp/web/Hallo.java @@ -0,0 +1,13 @@ +package org.example.myapp.web; + +import io.avaje.http.api.Controller; +import io.avaje.http.api.Path; + +@Controller +@Path("hallo") +public class Hallo { + + public String getStuff() { + return "Hallo"; + } +} diff --git a/tests/test-sigma/src/main/java/org/example/myapp/web/HelloController.java b/tests/test-sigma/src/main/java/org/example/myapp/web/HelloController.java new file mode 100644 index 000000000..6beaa9b3d --- /dev/null +++ b/tests/test-sigma/src/main/java/org/example/myapp/web/HelloController.java @@ -0,0 +1,190 @@ +package org.example.myapp.web; + +import static java.util.Objects.requireNonNull; + +import java.time.LocalDate; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.Executors; + +import org.example.myapp.service.MyService; +import org.example.myapp.web.other.Foo; + +import io.avaje.http.api.BeanParam; +import io.avaje.http.api.Controller; +import io.avaje.http.api.Default; +import io.avaje.http.api.Delete; +import io.avaje.http.api.Form; +import io.avaje.http.api.Get; +import io.avaje.http.api.MediaType; +import io.avaje.http.api.Path; +import io.avaje.http.api.Post; +import io.avaje.http.api.Produces; +import io.avaje.http.api.QueryParam; +import io.avaje.http.api.Valid; +import io.avaje.sigma.HttpContext; +import io.swagger.v3.oas.annotations.Hidden; +import jakarta.inject.Inject; + +/** + * Hello resource manager. + *

    + * Simple API for Hello resources. + */ +//@Hidden +@Valid +@Controller +@Path("/hello") +class HelloController { + + private final MyService myService; + + @Inject + HelloController(MyService myService) { + this.myService = myService; + } + + @Produces(MediaType.TEXT_PLAIN) + @Get("message") + String getPlainMessage() { + return "hello world"; + } + + /** + * Return the Hello DTO. + * + * @param id The hello Id. + * @param date The name of the hello + * @param otherParam Optional other parameter + * @return The Hello DTO given the id and name. + * @deprecated Please migrate away + */ + @Deprecated + @Get("/:id/:date") + HelloDto hello(int id, LocalDate date, String otherParam) { + return new HelloDto(id, date.toString(), otherParam); + } + + /** + * Find Hellos by name. + * + * @param name The name to search for + * @param myParam My option parameter + * @return The Hellos that we found. + */ + @Get("/findbyname/{name}") + List findByName(String name, @QueryParam("my-param") @Default("one") String myParam) { + return new ArrayList<>(); + } + + /** + * Simple example post with JSON body response. + */ + @Produces(MediaType.APPLICATION_JSON_PATCH_JSON) + @Post + HelloDto post(HelloDto dto) { + dto.name = "posted"; + return dto; + } + + /** + * Save the hello using json body. + * + * @param foo The hello doo id + * @param dto The hello body as json + */ + @Post("/savebean/:foo") + void saveBean(String foo, HelloDto dto, HttpContext HttpContext) { + // save hello data ... + System.out.println("save " + foo + " dto:" + dto); + requireNonNull(foo); + requireNonNull(dto); + requireNonNull(HttpContext); + } + + /** + * Create the new Hello using a form. + */ + @Post("saveform") + @Form + void saveForm(HelloForm helloForm) { + System.out.println("saving " + helloForm); + } + + @Form @Post("mySave") + void saveForm324(@Default("junk") String name, String email, String url) { + System.out.println("name " + name + " email:" + email + " url:" + url); + } + + + @Post("saveform2") + @Form + void saveForm2(String name, String email, String url) { + System.out.println("name " + name + " email:" + email + " url:" + url); + } + + @Post("saveform3") + @Form + HelloDto saveForm3(HelloForm helloForm) { + return new HelloDto(52, helloForm.name, helloForm.email); + } + + @Produces("text/plain") + @Get("withValidBean") + String getGetBeanForm(@BeanParam GetBeanForm bean) { + return "ok name:" + bean.getName(); + } + + @Hidden + @Get + List getAll() { + return myService.findAll(); + } + + @Get("/async") + CompletableFuture> getAllAsync() { + return CompletableFuture.supplyAsync(() -> { + // Simulate a delay as if an actual IO operation is being executed. + // This also helps ensure that we aren't just getting lucky with timings. + try { + Thread.sleep(10L); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + + return myService.findAll(); + }, Executors.newSingleThreadExecutor()); // Example of how to use a custom executor. + } + + // @Hidden + @Delete(":id") + void deleteById(int id) { + System.out.println("deleting " + id); + } + + @Produces("text/plain") + @Get("/withMatrix/:year;author;country/:other") + String getWithMatrixParam(int year, String author, String country, String other, String extra) { + return "yr:" + year + " au:" + author + " co:" + country + " other:" + other + " extra:" + extra; + } + + @Produces("text/plain") + @Get("slash/{name}//other/") + String slashAccepting(String name, String nam0, String nam1) { + return "got name:" + name + " splat0:" + nam0 + " splat1:" + nam1; + } + + @Produces(value = "text/plain") + @Get("controlStatusCode") + String controlStatusCode(HttpContext ctx) { + ctx.status(201); + return "controlStatusCode"; + } + + @Produces(value = "text/plain") + @Get("takesNestedEnum") + String takesNestedEnum(Foo.NestedEnum myEnum) { + return "takesNestedEnum-" + myEnum; + } +} diff --git a/tests/test-sigma/src/main/java/org/example/myapp/web/HelloDto.java b/tests/test-sigma/src/main/java/org/example/myapp/web/HelloDto.java new file mode 100644 index 000000000..ac3762420 --- /dev/null +++ b/tests/test-sigma/src/main/java/org/example/myapp/web/HelloDto.java @@ -0,0 +1,56 @@ +package org.example.myapp.web; + +import java.time.Instant; +import java.util.UUID; + +import io.avaje.jsonb.Json; +@Json +public class HelloDto { + + public int id; + /** + * This is a comment. + */ + public String name; + /** + * This is a comment + */ + public String otherParam; + private UUID gid; + + private Instant whenAction; + + public HelloDto(int id, String name, String otherParam) { + this.id = id; + this.name = name; + this.otherParam = otherParam; + } + + /** + * Jackson constructor. + */ + public HelloDto() { + } + + public UUID getGid() { + return gid; + } + + public void setGid(UUID gid) { + this.gid = gid; + } + + public Instant getWhenAction() { + return whenAction; + } + + public void setWhenAction(Instant whenAction) { + this.whenAction = whenAction; + } + + @Override + public String toString() { + return "id:" + id + " name:" + name + " other:" + otherParam; + } + +} diff --git a/tests/test-sigma/src/main/java/org/example/myapp/web/HelloForm.java b/tests/test-sigma/src/main/java/org/example/myapp/web/HelloForm.java new file mode 100644 index 000000000..51dcfb085 --- /dev/null +++ b/tests/test-sigma/src/main/java/org/example/myapp/web/HelloForm.java @@ -0,0 +1,83 @@ +package org.example.myapp.web; + +import java.time.LocalDate; + +import org.hibernate.validator.constraints.URL; + +import io.avaje.jsonb.Json; +import jakarta.validation.Valid; +import jakarta.validation.constraints.Email; +import jakarta.validation.constraints.Future; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; + +@Json +@Valid +public class HelloForm { + + @NotNull + @Size(min = 2, max = 150) + String name; + + @Email + @Size(max = 100) + String email; +@URL + private String url; +@Future + public LocalDate startDate; + + public HelloForm(String name, String email) { + this.name = name; + this.email = email; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public LocalDate getStartDate() { + return startDate; + } + + public void setStartDate(LocalDate startDate) { + this.startDate = startDate; + } + + @Override + public String toString() { + return "HelloForm{" + + "name='" + + name + + '\'' + + ", email='" + + email + + '\'' + + ", url='" + + url + + '\'' + + ", startDate=" + + startDate + + '}'; + } +} diff --git a/tests/test-sigma/src/main/java/org/example/myapp/web/Repository.java b/tests/test-sigma/src/main/java/org/example/myapp/web/Repository.java new file mode 100644 index 000000000..de24d26ca --- /dev/null +++ b/tests/test-sigma/src/main/java/org/example/myapp/web/Repository.java @@ -0,0 +1,13 @@ +package org.example.myapp.web; + +import java.util.List; + +public interface Repository { + + T findById(I id); + + List findAll(); + + I save(T bean); +} + diff --git a/tests/test-sigma/src/main/java/org/example/myapp/web/SecurityController.java b/tests/test-sigma/src/main/java/org/example/myapp/web/SecurityController.java new file mode 100644 index 000000000..4668a9b91 --- /dev/null +++ b/tests/test-sigma/src/main/java/org/example/myapp/web/SecurityController.java @@ -0,0 +1,22 @@ +package org.example.myapp.web; + +import io.avaje.http.api.Controller; +import io.avaje.http.api.Get; +import io.avaje.http.api.Path; +import io.swagger.v3.oas.annotations.security.SecurityRequirement; + +@Controller +@Path("/security") +class SecurityController { + + @Get("/first") + @SecurityRequirement(name = "JWT") + String first() { + return "simple"; + } + + @Get("/second") + String second() { + return "simple"; + } +} diff --git a/tests/test-sigma/src/main/java/org/example/myapp/web/ServerType.java b/tests/test-sigma/src/main/java/org/example/myapp/web/ServerType.java new file mode 100644 index 000000000..244f00545 --- /dev/null +++ b/tests/test-sigma/src/main/java/org/example/myapp/web/ServerType.java @@ -0,0 +1,7 @@ +package org.example.myapp.web; + +public enum ServerType { + PROXY, + HIDE_N_SEEK, + FFA +} diff --git a/tests/test-sigma/src/main/java/org/example/myapp/web/other/Foo.java b/tests/test-sigma/src/main/java/org/example/myapp/web/other/Foo.java new file mode 100644 index 000000000..f3ed0507a --- /dev/null +++ b/tests/test-sigma/src/main/java/org/example/myapp/web/other/Foo.java @@ -0,0 +1,7 @@ +package org.example.myapp.web.other; + +public class Foo { + public enum NestedEnum { + A, B, C + } +} diff --git a/tests/test-sigma/src/main/java/org/example/myapp/web/test/ErrorResponse.java b/tests/test-sigma/src/main/java/org/example/myapp/web/test/ErrorResponse.java new file mode 100644 index 000000000..4611cc712 --- /dev/null +++ b/tests/test-sigma/src/main/java/org/example/myapp/web/test/ErrorResponse.java @@ -0,0 +1,7 @@ +package org.example.myapp.web.test; + +public class ErrorResponse { + + public String id; + public String text; +} diff --git a/tests/test-sigma/src/main/java/org/example/myapp/web/test/HealthController.java b/tests/test-sigma/src/main/java/org/example/myapp/web/test/HealthController.java new file mode 100644 index 000000000..8cdbea60a --- /dev/null +++ b/tests/test-sigma/src/main/java/org/example/myapp/web/test/HealthController.java @@ -0,0 +1,30 @@ +package org.example.myapp.web.test; + +import io.avaje.http.api.Get; +import io.avaje.http.api.MediaType; +import io.avaje.http.api.OpenAPIResponse; +import io.avaje.http.api.Path; +import io.avaje.http.api.Produces; +import io.swagger.v3.oas.annotations.OpenAPIDefinition; +import io.swagger.v3.oas.annotations.info.Info; +import io.swagger.v3.oas.annotations.tags.Tag; + +@Path("javalin") +@OpenAPIDefinition( + info = + @Info( + title = "Example service showing off the Path extension method of controller", + description = "")) +@OpenAPIResponse(responseCode = 403, description = "Not Authorized") +public interface HealthController { + /** + * Standard Get + * + * @return a health check + */ + @Get("/health") + @Produces(MediaType.TEXT_PLAIN) + @Tag(name = "tag1", description = "it's somethin") + @OpenAPIResponse(responseCode = 500, type = ErrorResponse.class) + String health(); +} diff --git a/tests/test-sigma/src/main/java/org/example/myapp/web/test/HealthControllerImpl.java b/tests/test-sigma/src/main/java/org/example/myapp/web/test/HealthControllerImpl.java new file mode 100644 index 000000000..e89195d97 --- /dev/null +++ b/tests/test-sigma/src/main/java/org/example/myapp/web/test/HealthControllerImpl.java @@ -0,0 +1,13 @@ +package org.example.myapp.web.test; + +import io.avaje.http.api.Controller; + +@Controller +public class HealthControllerImpl implements HealthController { + + @Override + public String health() { + + return "this feels like a picnic *chew*"; + } +} diff --git a/tests/test-sigma/src/main/java/org/example/myapp/web/test/MyForm.java b/tests/test-sigma/src/main/java/org/example/myapp/web/test/MyForm.java new file mode 100644 index 000000000..8b7207843 --- /dev/null +++ b/tests/test-sigma/src/main/java/org/example/myapp/web/test/MyForm.java @@ -0,0 +1,8 @@ +package org.example.myapp.web.test; + +public class MyForm { + + public String name; + public String email; + public String url; +} diff --git a/tests/test-sigma/src/main/java/org/example/myapp/web/test/OpenAPIController.java b/tests/test-sigma/src/main/java/org/example/myapp/web/test/OpenAPIController.java new file mode 100644 index 000000000..39764584b --- /dev/null +++ b/tests/test-sigma/src/main/java/org/example/myapp/web/test/OpenAPIController.java @@ -0,0 +1,102 @@ +package org.example.myapp.web.test; + +import java.util.List; + +import io.avaje.http.api.Controller; +import io.avaje.http.api.Get; +import io.avaje.http.api.MediaType; +import io.avaje.http.api.OpenAPIResponse; +import io.avaje.http.api.OpenAPIResponses; +import io.avaje.http.api.Path; +import io.avaje.http.api.Post; +import io.avaje.http.api.Produces; +import io.avaje.http.api.Put; +import io.avaje.sigma.HttpContext; +import io.swagger.v3.oas.annotations.OpenAPIDefinition; +import io.swagger.v3.oas.annotations.enums.SecuritySchemeIn; +import io.swagger.v3.oas.annotations.enums.SecuritySchemeType; +import io.swagger.v3.oas.annotations.info.Info; +import io.swagger.v3.oas.annotations.security.SecurityScheme; +import io.swagger.v3.oas.annotations.tags.Tag; + +@OpenAPIDefinition( + info = + @Info( + title = "Example service", + description = "Example Javalin controllers with Java and Maven")) +@Controller +@Path("openapi/") +@SecurityScheme( + type = SecuritySchemeType.APIKEY, + in = SecuritySchemeIn.QUERY, + name = "JWT", + paramName = "access_token", + description = + "JSON Web Tokens are an open, industry standard RFC 7519 method for representing claims securely between two parties.") +public class OpenAPIController { + + /** + * Example of Open API Get (up to the first period is the summary). When using Javalin HttpContext + * only
    + * This Javadoc description is added to the generated openapi.json + * + * @return funny phrase (this part of the javadoc is added to the response desc) + */ + @Get("/get") + @Produces(MediaType.TEXT_PLAIN) + @OpenAPIResponse(responseCode = 200, type = String.class) + void ctxEndpoint(HttpContext ctx) { + ctx.contentType(MediaType.TEXT_PLAIN).result("healthlmao"); + } + + /** + * Standard Post. uses tag annotation to add tags to openapi json + * + * @param b the body (this is used for generated request body desc) + * @return the response body (from javadoc) + */ + @Post("/post") + @Tag(name = "tag1", description = "this is added to openapi tags") + @OpenAPIResponse(responseCode = 200, description = "overrides @return javadoc description") + @OpenAPIResponse(responseCode = 201) + @OpenAPIResponse( + responseCode = 400, + description = "User not found (Will not have an associated response schema)") + @OpenAPIResponse( + responseCode = 500, + description = "Some other Error (Will have this error class as the response class)", + type = ErrorResponse.class) + Person testPost(Person b) { + return new Person(0, "baby"); + } + + /** + * Standard Post. The Deprecated annotation adds "deprecacted:true" to the generated json + * + * @param m the body + * @return the response body (from javadoc) + */ + @Deprecated + @Post("/post1") + @OpenAPIResponses({ + @OpenAPIResponse(responseCode = 400, description = "User not found"), + @OpenAPIResponse( + responseCode = 500, + description = "Some other Error", + type = ErrorResponse.class) + }) + Person testPostList(List m) { + return new Person(0, "baby"); + } + + @Put("/put") + @Produces(value = MediaType.TEXT_PLAIN, statusCode = 203) + @OpenAPIResponse(responseCode = 204, type = String.class) + String testDefaultStatus(HttpContext ctx) { + if (ctx.contentType().equals(MediaType.APPLICATION_PDF)) { + ctx.status(204); + return ""; + } + return "only partial info"; + } +} diff --git a/tests/test-sigma/src/main/java/org/example/myapp/web/test/Person.java b/tests/test-sigma/src/main/java/org/example/myapp/web/test/Person.java new file mode 100644 index 000000000..434251ba0 --- /dev/null +++ b/tests/test-sigma/src/main/java/org/example/myapp/web/test/Person.java @@ -0,0 +1,31 @@ +package org.example.myapp.web.test; + +import io.avaje.jsonb.Json; + +@Json +public class Person { + + long id; + String name; + + public Person(long id, String name) { + this.id = id; + this.name = name; + } + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/tests/test-sigma/src/main/java/org/example/myapp/web/test/TestController.java b/tests/test-sigma/src/main/java/org/example/myapp/web/test/TestController.java new file mode 100644 index 000000000..036777241 --- /dev/null +++ b/tests/test-sigma/src/main/java/org/example/myapp/web/test/TestController.java @@ -0,0 +1,130 @@ +package org.example.myapp.web.test; + +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.CompletableFuture; + +import org.example.myapp.web.HelloDto; +import org.example.myapp.web.ServerType; + +import io.avaje.http.api.Controller; +import io.avaje.http.api.Default; +import io.avaje.http.api.Form; +import io.avaje.http.api.Get; +import io.avaje.http.api.Header; +import io.avaje.http.api.MatrixParam; +import io.avaje.http.api.MediaType; +import io.avaje.http.api.Path; +import io.avaje.http.api.Post; +import io.avaje.http.api.Produces; +import io.avaje.http.api.Put; +import io.avaje.http.api.QueryParam; +import io.avaje.sigma.HttpContext; + +@Controller +@Path("test/") +public class TestController { + + @Get + @Produces(MediaType.TEXT_PLAIN) + String basic() { + return "Hello world - index"; + } + + @Get("hey") + @Produces(MediaType.TEXT_PLAIN) + String helloWorld() { + return "Hello world"; + } + + @Get("/ctx") + void testVoid(HttpContext ctx) { + ctx.result("success path:" + ctx.path()); + } + + @Get("/header") + String testHeader(@Header String head) { + return head; + } + + @Get("person/{name}") + Person testParamAndBody(String name) { + return new Person(42, name + " hello"); + } + + @Post("/person") + Person testPostPerson(Person body) { + return new Person(42, "Returning " + body.getName()); + } + + @Get("person/{sortBy}/list") + List testPersonList(String sortBy) { + return List.of(new Person(42, "fooList"), new Person(43, "barList")); + } + + // curl -v localhost:8081/person/foo/set + @Get("person/{sortBy}/set") + Set testPersonSet(String sortBy) { + return Set.of(new Person(42, "fooSet"), new Person(43, "barSet")); + } + + @Get("person/{sortBy}/map") + Map testPersonMap(String sortBy) { + return Map.of("one", new Person(42, "fooMap"), "two", new Person(43, "barMap")); + } + + @Put("person/update") + String testPersonListBody(List newGuys) { + return "New Guys Added"; + } + + @Put("int") + int testIntReturn() { + return 422; + } + + @Put("long") + long testLongReturn() { + return 69; + } + + // curl -X POST http://localhost:8081/form + // -H "Content-Type: application/x-www-form-urlencoded" + // -d "name=Jimmy&email=jim@foo&url=notaurl" + @Form + @Post("form") + String testForm(String name, String email, String url) { + return name + "-" + email + "-" + url; + } + + // curl -X POST http://localhost:8081/formBean + // -H "Content-Type:application/x-www-form-urlencoded" + // -d "name=FormBeanJimmy&email=jim@foo&url=notaurl" + @Form + @Post("formBean") + String testFormBean(MyForm form) { + return form.name + "|" + form.email + "|" + form.url; + } + + @Get("/withMatrixParam/{type-1;category;vendor-34}/{range;style}") + void neo( + @MatrixParam("type-1") String type, + String category, + @MatrixParam("vendor-34") String vendor, + String range, + String style) { + + System.out.println("Ever have that feeling where you're not sure if you're awake or dreaming?"); + } + + @Get("/async") + CompletableFuture getAllAsync() { + return CompletableFuture.supplyAsync(() -> new HelloDto(12, "Jim", "asd")); + } + + @Get("/enumQuery2") + String enumMultiQuery(@QueryParam @Default({"FFA", "PROXY"}) Set type) { + return type.toString(); + } +} diff --git a/tests/test-sigma/src/main/java/org/example/myapp/web/test/TestController2.java b/tests/test-sigma/src/main/java/org/example/myapp/web/test/TestController2.java new file mode 100644 index 000000000..b4b20804b --- /dev/null +++ b/tests/test-sigma/src/main/java/org/example/myapp/web/test/TestController2.java @@ -0,0 +1,95 @@ +package org.example.myapp.web.test; + +import java.util.Set; + +import org.example.myapp.web.ServerType; + +import io.avaje.http.api.BodyString; +import io.avaje.http.api.Controller; +import io.avaje.http.api.Default; +import io.avaje.http.api.ExceptionHandler; +import io.avaje.http.api.Filter; +import io.avaje.http.api.Form; +import io.avaje.http.api.FormParam; +import io.avaje.http.api.Get; +import io.avaje.http.api.InstrumentServerContext; +import io.avaje.http.api.Path; +import io.avaje.http.api.Post; +import io.avaje.http.api.QueryParam; +import io.avaje.sigma.HttpContext; + +@Path("test/") +@Controller +public class TestController2 { + + @Form + @Get("/enumForm") + @InstrumentServerContext + void enumForm(String s, ServerType type, HttpContext ctx) { + ctx.result(s); + } + + @Get("/enumFormParam") + @InstrumentServerContext + String enumFormParam(@FormParam String s, @FormParam ServerType type) throws Exception { + return type.name(); + } + + @Get("/enumQuery") + String enumQuery(@QueryParam @Default("FFA") ServerType type) { + return type.name(); + } + + @Post("/enumQueryImplied") + String enumQueryImplied(String s, @QueryParam ServerType type) { + return type.name(); + } + + @Post("/enumPath/{type}") + String enumPath(ServerType type) { + return type.name(); + } + + @Post("/strBody") + @InstrumentServerContext + String strBody(@BodyString String body) { + return body; + } + + @ExceptionHandler + String exception(Exception ex) { + + return ""; + } + + @ExceptionHandler + String exceptionCtx(Exception ex, HttpContext ctx) { + + return ""; + } + + @ExceptionHandler(RuntimeException.class) + void exceptionVoid(HttpContext ctx) { + System.err.println("do nothing lmao"); + } + + // @After + void after(String s, ServerType type, HttpContext ctx) { + ctx.result(s); + } + + // @Before + void before(String s, ServerType type, HttpContext ctx) { + ctx.result(s); + } + + @Filter + void filter(HttpContext ctx) { + } + + @Form + @Get("/formMulti") + String formMulti(Set strings) { + return strings.toString(); + } +} diff --git a/tests/test-sigma/src/main/resources/logback.xml b/tests/test-sigma/src/main/resources/logback.xml new file mode 100644 index 000000000..1119a0c85 --- /dev/null +++ b/tests/test-sigma/src/main/resources/logback.xml @@ -0,0 +1,18 @@ + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + + + + + + + diff --git a/tests/test-sigma/src/test/java/io/avaje/http/generator/SigmaProcessorTest.java b/tests/test-sigma/src/test/java/io/avaje/http/generator/SigmaProcessorTest.java new file mode 100644 index 000000000..dda2e39b7 --- /dev/null +++ b/tests/test-sigma/src/test/java/io/avaje/http/generator/SigmaProcessorTest.java @@ -0,0 +1,102 @@ +package io.avaje.http.generator; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.io.File; +import java.io.IOException; +import java.io.PrintWriter; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +import java.util.Set; + +import javax.tools.JavaFileObject; +import javax.tools.JavaFileObject.Kind; +import javax.tools.StandardLocation; +import javax.tools.ToolProvider; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; + +import io.avaje.http.generator.sigma.SigmaProcessor; +import io.avaje.jsonb.generator.JsonbProcessor; + +class SigmaProcessorTest { + + @AfterEach + void deleteGeneratedFiles() throws IOException { + + Paths.get("openapi.json").toAbsolutePath().toFile().delete(); + + Files.walk(Paths.get("org").toAbsolutePath()) + .sorted(Comparator.reverseOrder()) + .map(Path::toFile) + .forEach(File::delete); + } + + @Test + public void runAnnotationProcessor() throws Exception { + final var source = Paths.get("src").toAbsolutePath().toString(); + + final var files = getSourceFiles(source); + + final var compiler = ToolProvider.getSystemJavaCompiler(); + + final var task = + compiler.getTask( + new PrintWriter(System.out), + null, + null, + List.of("--release=11", "-AdisableDirectWrites=true"), + null, + files); + task.setProcessors(List.of(new SigmaProcessor())); + + assertThat(task.call()).isTrue(); + assert Files.readString( + Paths.get("org/example/myapp/web/BarController$Route.java").toAbsolutePath()) + .contains("io.avaje.inject.Component"); + } + + @Test + void runAnnotationProcessorJakarta() throws Exception { + final var source = Paths.get("src").toAbsolutePath().toString(); + + final var files = getSourceFiles(source); + + final var compiler = ToolProvider.getSystemJavaCompiler(); + + final var task = + compiler.getTask( + new PrintWriter(System.out), + null, + null, + List.of( + "--release=11", + "-AuseJavax=false", + "-AuseSingleton=true", + "-AdisableDirectWrites=true"), + null, + files); + task.setProcessors(List.of(new SigmaProcessor(), new JsonbProcessor())); + + assertThat(task.call()).isTrue(); + + assert Files.readString( + Paths.get("org/example/myapp/web/BarController$Route.java").toAbsolutePath()) + .contains("jakarta.inject.Singleton"); + } + + private Iterable getSourceFiles(String source) throws Exception { + final var compiler = ToolProvider.getSystemJavaCompiler(); + final var files = compiler.getStandardFileManager(null, null, null); + + files.setLocation(StandardLocation.SOURCE_PATH, List.of(new File(source))); + + final Set fileKinds = Collections.singleton(Kind.SOURCE); + return files.list(StandardLocation.SOURCE_PATH, "", fileKinds, true); + } +} diff --git a/tests/test-sigma/src/test/resources/application-test.yaml b/tests/test-sigma/src/test/resources/application-test.yaml new file mode 100644 index 000000000..ae43f3a1f --- /dev/null +++ b/tests/test-sigma/src/test/resources/application-test.yaml @@ -0,0 +1,6 @@ +ebean: + test: +# shutdown: remove # stop | remove + platform: h2 # h2, postgres, mysql, mariadb, sqlserver, oracle, hana, clickhouse, sqlite + ddlMode: dropCreate # none | dropCreate | create | migration | createOnly | migrationDropCreate + dbName: my_app diff --git a/tests/test-sigma/src/test/resources/logback-test.xml b/tests/test-sigma/src/test/resources/logback-test.xml new file mode 100644 index 000000000..8467abcc9 --- /dev/null +++ b/tests/test-sigma/src/test/resources/logback-test.xml @@ -0,0 +1,19 @@ + + + + TRACE + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + + + + + From 0108280c607adc7ffa582364db963cc0ad089299 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Sun, 8 Sep 2024 10:21:43 +1200 Subject: [PATCH 1151/1323] Version 2.8-RC3 --- htmx-api/pom.xml | 2 +- htmx-nima-jstache/pom.xml | 2 +- htmx-nima/pom.xml | 4 ++-- http-api-javalin/pom.xml | 2 +- http-api/pom.xml | 2 +- http-client-gson-adapter/pom.xml | 4 ++-- http-client-moshi-adapter/pom.xml | 4 ++-- http-client/pom.xml | 4 ++-- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 2 +- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-generator-sigma/pom.xml | 2 +- http-inject-plugin/pom.xml | 2 +- pom.xml | 4 ++-- tests/pom.xml | 2 +- tests/test-client-generation/pom.xml | 2 +- tests/test-client/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-htmx/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- tests/test-sigma/pom.xml | 2 +- 26 files changed, 31 insertions(+), 31 deletions(-) diff --git a/htmx-api/pom.xml b/htmx-api/pom.xml index 8bdc810c5..010acb986 100644 --- a/htmx-api/pom.xml +++ b/htmx-api/pom.xml @@ -6,7 +6,7 @@ io.avaje avaje-http-parent - 2.8-RC1 + 2.8-RC3 avaje-htmx-api diff --git a/htmx-nima-jstache/pom.xml b/htmx-nima-jstache/pom.xml index fa0592ddd..1dfa1a80b 100644 --- a/htmx-nima-jstache/pom.xml +++ b/htmx-nima-jstache/pom.xml @@ -6,7 +6,7 @@ io.avaje avaje-http-parent - 2.8-RC1 + 2.8-RC3 avaje-htmx-nima-jstache diff --git a/htmx-nima/pom.xml b/htmx-nima/pom.xml index 0598cec23..b884f993e 100644 --- a/htmx-nima/pom.xml +++ b/htmx-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje avaje-http-parent - 2.8-RC1 + 2.8-RC3 avaje-htmx-nima @@ -21,7 +21,7 @@ io.avaje avaje-htmx-api - 2.8-RC1 + 2.8-RC3 io.helidon.webserver diff --git a/http-api-javalin/pom.xml b/http-api-javalin/pom.xml index 9f3b18bd3..d46c51782 100644 --- a/http-api-javalin/pom.xml +++ b/http-api-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.8-RC1 + 2.8-RC3 .. diff --git a/http-api/pom.xml b/http-api/pom.xml index 80efe5d32..b9f88901f 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.8-RC1 + 2.8-RC3 .. diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index 099a2b053..2e81c4660 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.8-RC1 + 2.8-RC3 avaje-http-client-gson @@ -20,7 +20,7 @@ io.avaje avaje-http-client - 2.8-RC1 + 2.8-RC3 provided diff --git a/http-client-moshi-adapter/pom.xml b/http-client-moshi-adapter/pom.xml index f5cd2899c..405d92b2e 100644 --- a/http-client-moshi-adapter/pom.xml +++ b/http-client-moshi-adapter/pom.xml @@ -3,7 +3,7 @@ io.avaje avaje-http-parent - 2.8-RC1 + 2.8-RC3 avaje-http-client-moshi @@ -19,7 +19,7 @@ io.avaje avaje-http-client - 2.8-RC1 + 2.8-RC3 provided diff --git a/http-client/pom.xml b/http-client/pom.xml index c7562cc9c..c2bebc7bc 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.8-RC1 + 2.8-RC3 avaje-http-client @@ -66,7 +66,7 @@ io.avaje avaje-http-api - 2.8-RC1 + 2.8-RC3 test diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index a662b44a7..7683c4a38 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.8-RC1 + 2.8-RC3 avaje-http-client-generator diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 0b730af17..e3ec8a5c6 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.8-RC1 + 2.8-RC3 avaje-http-generator-core diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index 8fb09b39f..4d6e9a15e 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.8-RC1 + 2.8-RC3 avaje-http-helidon-generator diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index 1985a057c..ab0617d41 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.8-RC1 + 2.8-RC3 avaje-http-javalin-generator diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index f77bac53a..ad9e48d24 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.8-RC1 + 2.8-RC3 avaje-http-jex-generator diff --git a/http-generator-sigma/pom.xml b/http-generator-sigma/pom.xml index 77014be46..6acafc844 100644 --- a/http-generator-sigma/pom.xml +++ b/http-generator-sigma/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.8-RC1 + 2.8-RC3 avaje-http-sigma-generator diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index 91e9da057..1954133c7 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.8-RC1 + 2.8-RC3 .. diff --git a/pom.xml b/pom.xml index a2333d507..5e228d5de 100644 --- a/pom.xml +++ b/pom.xml @@ -4,12 +4,12 @@ org.avaje java11-oss - 4.4 + 4.5 io.avaje avaje-http-parent - 2.8-RC1 + 2.8-RC3 pom diff --git a/tests/pom.xml b/tests/pom.xml index 0f7523f12..8c928d044 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.8-RC1 + 2.8-RC3 tests diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index a1d6ba4da..1e60293c2 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.8-RC1 + 2.8-RC3 test-client-generation diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index 70285d69d..87ac90f7b 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.8-RC1 + 2.8-RC3 test-client diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index d910cbb86..e64da19fe 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 2.8-RC1 + 2.8-RC3 test-javalin-jsonb diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 925384baf..fa0ca5f64 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.8-RC1 + 2.8-RC3 test-javalin diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index dc6834c5f..0d380e41d 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.8-RC1 + 2.8-RC3 test-jex diff --git a/tests/test-nima-htmx/pom.xml b/tests/test-nima-htmx/pom.xml index 30dc21e50..b632f7d6d 100644 --- a/tests/test-nima-htmx/pom.xml +++ b/tests/test-nima-htmx/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.8-RC1 + 2.8-RC3 test-nima-htmx diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 5d0fe3206..54655f0c2 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.8-RC1 + 2.8-RC3 test-nima-jsonb diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index ba385f431..bfb9f65fe 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.8-RC1 + 2.8-RC3 test-nima diff --git a/tests/test-sigma/pom.xml b/tests/test-sigma/pom.xml index 78e59fa6c..e1e81eb35 100644 --- a/tests/test-sigma/pom.xml +++ b/tests/test-sigma/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 2.8-RC1 + 2.8-RC3 test-sigma From 50723c661327207fac1d1b218bd18f8f42607088 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Sep 2024 19:15:04 +0000 Subject: [PATCH 1152/1323] Bump the dependencies group with 2 updates Bumps the dependencies group with 2 updates: io.helidon.webserver:helidon-webserver and io.helidon.http.media:helidon-http-media-jsonb. Updates `io.helidon.webserver:helidon-webserver` from 4.1.0 to 4.1.1 Updates `io.helidon.http.media:helidon-http-media-jsonb` from 4.1.0 to 4.1.1 Updates `io.helidon.http.media:helidon-http-media-jsonb` from 4.1.0 to 4.1.1 --- updated-dependencies: - dependency-name: io.helidon.webserver:helidon-webserver dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: io.helidon.http.media:helidon-http-media-jsonb dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: io.helidon.http.media:helidon-http-media-jsonb dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies ... Signed-off-by: dependabot[bot] --- htmx-nima/pom.xml | 2 +- tests/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/htmx-nima/pom.xml b/htmx-nima/pom.xml index b884f993e..fa731ed37 100644 --- a/htmx-nima/pom.xml +++ b/htmx-nima/pom.xml @@ -26,7 +26,7 @@ io.helidon.webserver helidon-webserver - 4.1.0 + 4.1.1 diff --git a/tests/pom.xml b/tests/pom.xml index 8c928d044..7c9af0e81 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -17,7 +17,7 @@ 2.17.2 2.5 10.3 - 4.1.0 + 4.1.1 6.3.0 From ca5c034ee101202a39b4f43273643abb1834bfc4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Sep 2024 19:04:36 +0000 Subject: [PATCH 1153/1323] Bump the dependencies group with 3 updates Bumps the dependencies group with 3 updates: [io.avaje:avaje-inject](https://github.com/avaje/avaje-inject), io.avaje:avaje-inject-generator and io.avaje:avaje-inject-maven-plugin. Updates `io.avaje:avaje-inject` from 10.3 to 10.4 - [Release notes](https://github.com/avaje/avaje-inject/releases) - [Commits](https://github.com/avaje/avaje-inject/compare/10.3...10.4) Updates `io.avaje:avaje-inject-generator` from 10.3 to 10.4 Updates `io.avaje:avaje-inject-generator` from 10.3 to 10.4 Updates `io.avaje:avaje-inject-maven-plugin` from 10.3 to 10.4 --- updated-dependencies: - dependency-name: io.avaje:avaje-inject dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.avaje:avaje-inject-generator dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.avaje:avaje-inject-generator dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.avaje:avaje-inject-maven-plugin dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies ... Signed-off-by: dependabot[bot] --- htmx-nima-jstache/pom.xml | 2 +- http-client/pom.xml | 4 ++-- http-inject-plugin/pom.xml | 2 +- tests/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/htmx-nima-jstache/pom.xml b/htmx-nima-jstache/pom.xml index 1dfa1a80b..84ebf9f8c 100644 --- a/htmx-nima-jstache/pom.xml +++ b/htmx-nima-jstache/pom.xml @@ -39,7 +39,7 @@ io.avaje avaje-inject - 10.3 + 10.4 provided true diff --git a/http-client/pom.xml b/http-client/pom.xml index c2bebc7bc..ee23fa52c 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -43,7 +43,7 @@ io.avaje avaje-inject - 10.3 + 10.4 true @@ -99,7 +99,7 @@ io.avaje avaje-inject-generator - 10.3 + 10.4 diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index 1954133c7..b20c28426 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -19,7 +19,7 @@ io.avaje avaje-inject - 10.3 + 10.4 provided true diff --git a/tests/pom.xml b/tests/pom.xml index 7c9af0e81..bcf90cb54 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -16,7 +16,7 @@ 3.26.3 2.17.2 2.5 - 10.3 + 10.4 4.1.1 6.3.0 diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 54655f0c2..b8d4c4c2f 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -109,7 +109,7 @@ io.avaje avaje-inject-maven-plugin - 10.3 + 10.4 process-sources From 6408abf473062ba86e9215d7358cd11678ca06b4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 23 Sep 2024 19:12:58 +0000 Subject: [PATCH 1154/1323] Bump the dependencies group with 5 updates Bumps the dependencies group with 5 updates: | Package | From | To | | --- | --- | --- | | [io.avaje:avaje-jsonb](https://github.com/avaje/avaje-jsonb) | `2.1` | `2.2` | | [io.avaje:avaje-prisms](https://github.com/avaje/avaje-prisms) | `1.31` | `1.32` | | io.swagger.core.v3:swagger-annotations | `2.2.23` | `2.2.24` | | io.swagger.core.v3:swagger-models | `2.2.23` | `2.2.24` | | io.avaje:avaje-jsonb-generator | `2.1` | `2.2` | Updates `io.avaje:avaje-jsonb` from 2.1 to 2.2 - [Release notes](https://github.com/avaje/avaje-jsonb/releases) - [Commits](https://github.com/avaje/avaje-jsonb/compare/2.1...2.2) Updates `io.avaje:avaje-prisms` from 1.31 to 1.32 - [Release notes](https://github.com/avaje/avaje-prisms/releases) - [Commits](https://github.com/avaje/avaje-prisms/compare/1.31...1.32) Updates `io.swagger.core.v3:swagger-annotations` from 2.2.23 to 2.2.24 Updates `io.swagger.core.v3:swagger-models` from 2.2.23 to 2.2.24 Updates `io.swagger.core.v3:swagger-models` from 2.2.23 to 2.2.24 Updates `io.avaje:avaje-jsonb-generator` from 2.1 to 2.2 --- updated-dependencies: - dependency-name: io.avaje:avaje-jsonb dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.avaje:avaje-prisms dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.swagger.core.v3:swagger-annotations dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: io.swagger.core.v3:swagger-models dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: io.swagger.core.v3:swagger-models dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: io.avaje:avaje-jsonb-generator dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies ... Signed-off-by: dependabot[bot] --- http-client/pom.xml | 2 +- pom.xml | 4 ++-- tests/test-javalin-jsonb/pom.xml | 6 +++--- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-htmx/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 4 ++-- tests/test-sigma/pom.xml | 6 +++--- 8 files changed, 14 insertions(+), 14 deletions(-) diff --git a/http-client/pom.xml b/http-client/pom.xml index ee23fa52c..7631b2a5f 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -36,7 +36,7 @@ io.avaje avaje-jsonb - 2.1 + 2.2 true diff --git a/pom.xml b/pom.xml index 5e228d5de..eec04c814 100644 --- a/pom.xml +++ b/pom.xml @@ -19,9 +19,9 @@ true - 2.2.23 + 2.2.24 2.14.2 - 1.31 + 1.32 ${project.build.directory}${file.separator}module-info.shade diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index e64da19fe..1809b8896 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -13,7 +13,7 @@ true org.example.myapp.Main - 2.2.23 + 2.2.24 1.3.71 @@ -80,13 +80,13 @@ io.avaje avaje-jsonb - 2.1 + 2.2 io.avaje avaje-jsonb-generator - 2.1 + 2.2 provided diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index fa0ca5f64..21473a52d 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -12,7 +12,7 @@ true org.example.myapp.Main - 2.2.23 + 2.2.24 1.3.71 diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 0d380e41d..541960dd3 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -13,7 +13,7 @@ true org.example.myapp.Main 2.5 - 2.2.23 + 2.2.24 diff --git a/tests/test-nima-htmx/pom.xml b/tests/test-nima-htmx/pom.xml index b632f7d6d..a7f609ce0 100644 --- a/tests/test-nima-htmx/pom.xml +++ b/tests/test-nima-htmx/pom.xml @@ -82,7 +82,7 @@ io.avaje avaje-jsonb-generator - 2.1 + 2.2 io.jstach diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index b8d4c4c2f..a743861d3 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -31,7 +31,7 @@ io.avaje avaje-jsonb - 2.1 + 2.2 io.avaje @@ -90,7 +90,7 @@ io.avaje avaje-jsonb-generator - 2.1 + 2.2 diff --git a/tests/test-sigma/pom.xml b/tests/test-sigma/pom.xml index e1e81eb35..e641f13c3 100644 --- a/tests/test-sigma/pom.xml +++ b/tests/test-sigma/pom.xml @@ -13,7 +13,7 @@ 17 true - 2.2.23 + 2.2.24 1.3.71 @@ -73,12 +73,12 @@ io.avaje avaje-jsonb - 2.1 + 2.2 io.avaje avaje-jsonb-generator - 2.1 + 2.2 provided From 6810fe29d3d7ccb0bd6fff26940d7c7062c73cc5 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Mon, 23 Sep 2024 18:47:51 -0400 Subject: [PATCH 1155/1323] fix serializer --- .../avaje/http/generator/core/openapi/OpenAPISerializer.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/OpenAPISerializer.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/OpenAPISerializer.java index 7f57bc00a..9b24d6037 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/OpenAPISerializer.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/OpenAPISerializer.java @@ -65,7 +65,8 @@ static String serialize(Object obj) throws IllegalAccessException { for (final Field field : fields) { // skip JsonIgnored fields - if ("BIND_TYPE_AND_TYPES".equals(field.getName()) + if ("SCHEMA_RESOLUTION_PROPERTY".equals(field.getName()) + || "BIND_TYPE_AND_TYPES".equals(field.getName()) || "BINARY_STRING_CONVERSION_PROPERTY".equals(field.getName()) || "COMPONENTS_SCHEMAS_REF".equals(field.getName()) || "exampleSetFlag".equals(field.getName()) From 848f597ecd41070efe6df46a1b28c32ab6de7296 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 30 Sep 2024 19:13:25 +0000 Subject: [PATCH 1156/1323] Bump the dependencies group with 3 updates Bumps the dependencies group with 3 updates: [com.fasterxml.jackson.core:jackson-databind](https://github.com/FasterXML/jackson), [org.junit.jupiter:junit-jupiter-api](https://github.com/junit-team/junit5) and [org.junit.jupiter:junit-jupiter-engine](https://github.com/junit-team/junit5). Updates `com.fasterxml.jackson.core:jackson-databind` from 2.17.2 to 2.18.0 - [Commits](https://github.com/FasterXML/jackson/commits) Updates `org.junit.jupiter:junit-jupiter-api` from 5.11.0 to 5.11.1 - [Release notes](https://github.com/junit-team/junit5/releases) - [Commits](https://github.com/junit-team/junit5/compare/r5.11.0...r5.11.1) Updates `org.junit.jupiter:junit-jupiter-engine` from 5.11.0 to 5.11.1 - [Release notes](https://github.com/junit-team/junit5/releases) - [Commits](https://github.com/junit-team/junit5/compare/r5.11.0...r5.11.1) Updates `org.junit.jupiter:junit-jupiter-engine` from 5.11.0 to 5.11.1 - [Release notes](https://github.com/junit-team/junit5/releases) - [Commits](https://github.com/junit-team/junit5/compare/r5.11.0...r5.11.1) --- updated-dependencies: - dependency-name: com.fasterxml.jackson.core:jackson-databind dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: org.junit.jupiter:junit-jupiter-api dependency-type: direct:development update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: org.junit.jupiter:junit-jupiter-engine dependency-type: direct:development update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: org.junit.jupiter:junit-jupiter-engine dependency-type: direct:development update-type: version-update:semver-patch dependency-group: dependencies ... Signed-off-by: dependabot[bot] --- http-client/pom.xml | 2 +- tests/pom.xml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/http-client/pom.xml b/http-client/pom.xml index 7631b2a5f..c3c5c5d39 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -29,7 +29,7 @@ com.fasterxml.jackson.core jackson-databind - 2.17.2 + 2.18.0 true diff --git a/tests/pom.xml b/tests/pom.xml index bcf90cb54..7ffbb2c11 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -12,9 +12,9 @@ true - 5.11.0 + 5.11.1 3.26.3 - 2.17.2 + 2.18.0 2.5 10.4 4.1.1 From 0e478d9fa1c3b8309761bd5dca4c63f05887f827 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 7 Oct 2024 19:51:56 +0000 Subject: [PATCH 1157/1323] Bump the dependencies group with 6 updates Bumps the dependencies group with 6 updates: | Package | From | To | | --- | --- | --- | | io.swagger.core.v3:swagger-annotations | `2.2.24` | `2.2.25` | | io.swagger.core.v3:swagger-models | `2.2.24` | `2.2.25` | | [org.junit.jupiter:junit-jupiter-api](https://github.com/junit-team/junit5) | `5.11.1` | `5.11.2` | | [org.junit.jupiter:junit-jupiter-engine](https://github.com/junit-team/junit5) | `5.11.1` | `5.11.2` | | io.helidon.webserver:helidon-webserver | `4.1.1` | `4.1.2` | | io.helidon.http.media:helidon-http-media-jsonb | `4.1.1` | `4.1.2` | Updates `io.swagger.core.v3:swagger-annotations` from 2.2.24 to 2.2.25 Updates `io.swagger.core.v3:swagger-models` from 2.2.24 to 2.2.25 Updates `io.swagger.core.v3:swagger-models` from 2.2.24 to 2.2.25 Updates `org.junit.jupiter:junit-jupiter-api` from 5.11.1 to 5.11.2 - [Release notes](https://github.com/junit-team/junit5/releases) - [Commits](https://github.com/junit-team/junit5/compare/r5.11.1...r5.11.2) Updates `org.junit.jupiter:junit-jupiter-engine` from 5.11.1 to 5.11.2 - [Release notes](https://github.com/junit-team/junit5/releases) - [Commits](https://github.com/junit-team/junit5/compare/r5.11.1...r5.11.2) Updates `org.junit.jupiter:junit-jupiter-engine` from 5.11.1 to 5.11.2 - [Release notes](https://github.com/junit-team/junit5/releases) - [Commits](https://github.com/junit-team/junit5/compare/r5.11.1...r5.11.2) Updates `io.helidon.webserver:helidon-webserver` from 4.1.1 to 4.1.2 Updates `io.helidon.http.media:helidon-http-media-jsonb` from 4.1.1 to 4.1.2 Updates `io.helidon.http.media:helidon-http-media-jsonb` from 4.1.1 to 4.1.2 --- updated-dependencies: - dependency-name: io.swagger.core.v3:swagger-annotations dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: io.swagger.core.v3:swagger-models dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: io.swagger.core.v3:swagger-models dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: org.junit.jupiter:junit-jupiter-api dependency-type: direct:development update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: org.junit.jupiter:junit-jupiter-engine dependency-type: direct:development update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: org.junit.jupiter:junit-jupiter-engine dependency-type: direct:development update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: io.helidon.webserver:helidon-webserver dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: io.helidon.http.media:helidon-http-media-jsonb dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: io.helidon.http.media:helidon-http-media-jsonb dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies ... Signed-off-by: dependabot[bot] --- htmx-nima/pom.xml | 2 +- pom.xml | 2 +- tests/pom.xml | 4 ++-- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-sigma/pom.xml | 2 +- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/htmx-nima/pom.xml b/htmx-nima/pom.xml index fa731ed37..3c460dcbe 100644 --- a/htmx-nima/pom.xml +++ b/htmx-nima/pom.xml @@ -26,7 +26,7 @@ io.helidon.webserver helidon-webserver - 4.1.1 + 4.1.2 diff --git a/pom.xml b/pom.xml index eec04c814..ccd4c9245 100644 --- a/pom.xml +++ b/pom.xml @@ -19,7 +19,7 @@ true - 2.2.24 + 2.2.25 2.14.2 1.32 ${project.build.directory}${file.separator}module-info.shade diff --git a/tests/pom.xml b/tests/pom.xml index 7ffbb2c11..570c3c2cf 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -12,12 +12,12 @@ true - 5.11.1 + 5.11.2 3.26.3 2.18.0 2.5 10.4 - 4.1.1 + 4.1.2 6.3.0 diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 1809b8896..4c9fc376f 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -13,7 +13,7 @@ true org.example.myapp.Main - 2.2.24 + 2.2.25 1.3.71 diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 21473a52d..5d2a15c98 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -12,7 +12,7 @@ true org.example.myapp.Main - 2.2.24 + 2.2.25 1.3.71 diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 541960dd3..e2284c89d 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -13,7 +13,7 @@ true org.example.myapp.Main 2.5 - 2.2.24 + 2.2.25 diff --git a/tests/test-sigma/pom.xml b/tests/test-sigma/pom.xml index e641f13c3..44948df0e 100644 --- a/tests/test-sigma/pom.xml +++ b/tests/test-sigma/pom.xml @@ -13,7 +13,7 @@ 17 true - 2.2.24 + 2.2.25 1.3.71 From 1c27559faee0fdd91071d95f6024e55ce62231a8 Mon Sep 17 00:00:00 2001 From: Harry Chan <38070640+re-thc@users.noreply.github.com> Date: Wed, 9 Oct 2024 11:19:41 +1100 Subject: [PATCH 1158/1323] Optimize helidon optionals - io.helidon.common.mapper.OptionalValue (#505) * Optimize helidon optionals Helidon docs says that `Optional` is expensive and don't use it unless you need to. In the generator, optionals are more of an implementation detail and null or the default value is returned. For better performance, this PR replaces optionals with contains / get as Helidon suggests. * fix build --------- Co-authored-by: Josiah Noel <32279667+SentryMan@users.noreply.github.com> --- .../generator/helidon/nima/ControllerWriter.java | 6 +++++- .../helidon/nima/NimaPlatformAdapter.java | 16 ++++++++-------- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java index c2a39d2e8..78f90f972 100644 --- a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java +++ b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java @@ -202,7 +202,11 @@ private void writeClassStart() { if (reader.isIncludeValidator()) { writer.append(" private String language(ServerRequest req) {").eol(); - writer.append(" return req.headers().first(HEADER_ACCEPT_LANGUAGE).orElse(null);").eol(); + writer.append(" var headers = req.headers();").eol(); + writer.append(" if (headers.contains(HEADER_ACCEPT_LANGUAGE)) {").eol(); + writer.append(" return headers.get(HEADER_ACCEPT_LANGUAGE).get();").eol(); + writer.append(" }").eol(); + writer.append(" return null;").eol(); writer.append(" }").eol().eol(); } } diff --git a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/NimaPlatformAdapter.java b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/NimaPlatformAdapter.java index 83790aefc..03d211896 100644 --- a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/NimaPlatformAdapter.java +++ b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/NimaPlatformAdapter.java @@ -67,16 +67,16 @@ private void addRoleImports(List roles, ControllerReader controller) { @Override public void writeReadParameter(Append writer, ParamType paramType, String paramName) { switch (paramType) { - case PATHPARAM -> writer.append("pathParams.first(\"%s\").get()", paramName); + case PATHPARAM -> writer.append("pathParams.contains(\"%s\") ? pathParams.get(\"%s\") : null", paramName, paramName); - case QUERYPARAM -> writer.append("req.query().first(\"%s\").orElse(null)", paramName); + case QUERYPARAM -> writer.append("req.query().contains(\"%s\") ? req.query().get(\"%s\") : null", paramName, paramName); - case FORMPARAM -> writer.append("formParams.first(\"%s\").orElse(null)", paramName); + case FORMPARAM -> writer.append("formParams.contains(\"%s\") ? formParams.get(\"%s\") : null", paramName, paramName); case HEADER -> writer.append( "req.headers().value(HeaderNames.create(\"%s\")).orElse(null)", paramName); - case COOKIE -> writer.append("req.headers().cookies().first(\"%s\").orElse(null)", paramName); + case COOKIE -> writer.append("req.headers().cookies().contains(\"%s\") ? req.headers().cookies().get(\"%s\") : null", paramName, paramName); default -> writer.append("null // TODO req.%s().param(\"%s\")", paramType.type(), paramName); } @@ -86,19 +86,19 @@ public void writeReadParameter(Append writer, ParamType paramType, String paramN public void writeReadParameter(Append writer, ParamType paramType, String paramName, String paramDefault) { switch (paramType) { case PATHPARAM -> writer.append( - "pathParams.first(\"%s\").orElse(\"%s\")", paramName, paramDefault); + "pathParams.contains(\"%s\") ? pathParams.get(\"%s\") : \"%s\"", paramName, paramName, paramDefault); case QUERYPARAM -> writer.append( - "req.query().first(\"%s\").orElse(\"%s\")", paramName, paramDefault); + "req.query().contains(\"%s\") ? req.query().get(\"%s\") : \"%s\"", paramName, paramName, paramDefault); case FORMPARAM -> writer.append( - "formParams.first(\"%s\").orElse(\"%s\")", paramName, paramDefault); + "formParams.contains(\"%s\") ? formParams.get(\"%s\") : \"%s\"", paramName, paramName, paramDefault); case HEADER -> writer.append( "req.headers().value(Http.Header.create(\"%s\").orElse(\"%s\")", paramName, paramDefault); case COOKIE -> writer.append( - "req.headers().cookies().first(\"%s\").orElse(\"%s\")", paramName, paramDefault); + "req.headers().cookies().contains(\"%s\") ? req.headers().cookies().get(\"%s\") : \"%s\"", paramName, paramName, paramDefault); default -> writer.append("null // TODO req.%s().param(\"%s\")", paramType.type(), paramName); } From 42e546888b61d299d598b2d2c548a53589aea32f Mon Sep 17 00:00:00 2001 From: Harry Chan <38070640+re-thc@users.noreply.github.com> Date: Fri, 11 Oct 2024 08:49:58 +1100 Subject: [PATCH 1159/1323] Add roles support for Helidon (#506) Helidon has security providers e.g. OIDC. These integrate with WebServer Security as `SecurityHandler`s with the shorthand `SecurityFeature.rolesAllowed()` and the authorization provider will then validate the role before delegating to the actual handler. This PR takes Avaje's `@Roles` and populates them and the rest is up to Helidon. --- README.md | 4 ++-- .../helidon/nima/ControllerMethodWriter.java | 9 ++++++++ .../helidon/nima/ControllerWriter.java | 3 +++ .../helidon/nima/NimaPlatformAdapter.java | 4 +++- tests/test-nima/pom.xml | 5 +++++ .../src/main/java/org/example/AppRoles.java | 5 +++++ .../java/org/example/HelloController.java | 8 +++++++ .../src/main/java/org/example/Roles.java | 21 +++++++++++++++++++ 8 files changed, 56 insertions(+), 3 deletions(-) create mode 100644 tests/test-nima/src/main/java/org/example/AppRoles.java create mode 100644 tests/test-nima/src/main/java/org/example/Roles.java diff --git a/README.md b/README.md index a47585153..f0660e3dc 100644 --- a/README.md +++ b/README.md @@ -184,7 +184,7 @@ public class WidgetController$Route implements HttpFeature { private void _getById(ServerRequest req, ServerResponse res) throws Exception { res.status(OK_200); var pathParams = req.path().pathParameters(); - var id = asInt(pathParams.first("id").get()); + var id = asInt(pathParams.contains("id") ? pathParams.get("id") : null); var result = controller.getById(id); res.send(result); } @@ -263,7 +263,7 @@ public class WidgetController$Route implements HttpFeature { private void _getById(ServerRequest req, ServerResponse res) throws Exception { res.status(OK_200); var pathParams = req.path().pathParameters(); - var id = asInt(pathParams.first("id").get()); + var id = asInt(pathParams.contains("id") ? pathParams.get("id") : null); var result = controller.getById(id); res.headers().contentType(MediaTypes.APPLICATION_JSON); //jsonb has a special accommodation for helidon to improve performance diff --git a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java index 5afa98747..993ea6c64 100644 --- a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java +++ b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java @@ -88,6 +88,15 @@ void writeRule() { writer.append(" routing.addFilter(this::_%s);", method.simpleName()).eol(); } else { writer.append(" routing.%s(\"%s\", ", webMethod.name().toLowerCase(), method.fullPath().replace("\\", "\\\\")); + var roles = method.roles(); + if (!roles.isEmpty()) { + writer.append("SecurityFeature.rolesAllowed("); + writer.append("\"%s\"", Util.shortName(roles.getFirst(), true)); + for (var i = 1; i < roles.size(); i++) { + writer.append(", \"%s\"", Util.shortName(roles.get(i), true)); + } + writer.append("), "); + } var hxRequest = method.hxRequest(); if (hxRequest != null) { writer.append("HxHandler.builder(this::_%s)", method.simpleName()); diff --git a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java index 78f90f972..1e3d75d5f 100644 --- a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java +++ b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java @@ -50,6 +50,9 @@ class ControllerWriter extends BaseControllerWriter { reader.addImportType("io.helidon.webserver.http.ServerResponse"); reader.addImportType("io.helidon.webserver.http.HttpFeature"); reader.addImportType("io.helidon.http.HeaderNames"); + if (!reader.roles().isEmpty() || reader.methods().stream().anyMatch(m -> !m.roles().isEmpty())) { + reader.addImportType("io.helidon.webserver.security.SecurityFeature"); + } if (reader.isIncludeValidator()) { reader.addImportType("io.helidon.http.HeaderName"); } diff --git a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/NimaPlatformAdapter.java b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/NimaPlatformAdapter.java index 03d211896..8f73b0bde 100644 --- a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/NimaPlatformAdapter.java +++ b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/NimaPlatformAdapter.java @@ -61,7 +61,9 @@ public void methodRoles(List roles, ControllerReader controller) { } private void addRoleImports(List roles, ControllerReader controller) { - // nothing here yet + for (final String role : roles) { + controller.addStaticImportType(role); + } } @Override diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index bfb9f65fe..c2d0daaf3 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -33,6 +33,11 @@ helidon-webserver ${nima.version} + + io.helidon.webserver + helidon-webserver-security + ${nima.version} + io.helidon.http.media helidon-http-media-jsonb diff --git a/tests/test-nima/src/main/java/org/example/AppRoles.java b/tests/test-nima/src/main/java/org/example/AppRoles.java new file mode 100644 index 000000000..7e361aa10 --- /dev/null +++ b/tests/test-nima/src/main/java/org/example/AppRoles.java @@ -0,0 +1,5 @@ +package org.example; + +public enum AppRoles { + ANYONE, ADMIN, BASIC_USER +} diff --git a/tests/test-nima/src/main/java/org/example/HelloController.java b/tests/test-nima/src/main/java/org/example/HelloController.java index fbff3ec17..88df46723 100644 --- a/tests/test-nima/src/main/java/org/example/HelloController.java +++ b/tests/test-nima/src/main/java/org/example/HelloController.java @@ -2,6 +2,7 @@ import io.avaje.http.api.Controller; import io.avaje.http.api.Get; +import io.avaje.http.api.Produces; @Controller public class HelloController { @@ -18,4 +19,11 @@ Person person(String name, String sortBy) { p.setName(name + " hello" + " sortBy:" + sortBy); return p; } + + @Roles({AppRoles.ADMIN, AppRoles.BASIC_USER}) + @Produces("text/plain") + @Get("other/{name}") + String name(String name) { + return "hi " + name; + } } diff --git a/tests/test-nima/src/main/java/org/example/Roles.java b/tests/test-nima/src/main/java/org/example/Roles.java new file mode 100644 index 000000000..7e17989e4 --- /dev/null +++ b/tests/test-nima/src/main/java/org/example/Roles.java @@ -0,0 +1,21 @@ +package org.example; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +/** + * Specify permitted roles. + */ +@Target(value={METHOD, TYPE}) +@Retention(value=RUNTIME) +public @interface Roles { + + /** + * Specify the permitted roles. + */ + AppRoles[] value() default {}; +} From 0f9d6653dab05fca0f94b4eaa3b34d0980cd4111 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Thu, 17 Oct 2024 01:55:30 -0400 Subject: [PATCH 1160/1323] Fix Maven Badge (#507) link is dead --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f0660e3dc..5ed45b37e 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # [Avaje-HTTP](https://avaje.io/http/) [![Discord](https://img.shields.io/discord/1074074312421683250?color=%237289da&label=discord)](https://discord.gg/Qcqf9R27BR) [![Build](https://github.com/avaje/avaje-http/actions/workflows/build.yml/badge.svg)](https://github.com/avaje/avaje-http/actions/workflows/build.yml) -[![Maven Central : avaje-inject](https://img.shields.io/maven-central/v/io.avaje/avaje-http-api.svg?label=Maven%20Central)](https://maven-badges.herokuapp.com/maven-central/io.avaje/avaje-http-api) +[![Maven Central](https://img.shields.io/maven-central/v/io.avaje/avaje-http-api.svg?label=Maven%20Central)](https://mvnrepository.com/artifact/io.avaje/avaje-http-api) [![javadoc](https://javadoc.io/badge2/io.avaje/avaje-http-api/http_api_javadoc.svg?&color=purple)](https://javadoc.io/doc/io.avaje/avaje-http-api) [![javadoc](https://javadoc.io/badge2/io.avaje/avaje-http-client/http_client_javadoc.svg?&color=purple)](https://javadoc.io/doc/io.avaje/avaje-http-client) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://github.com/avaje/avaje-inject/blob/master/LICENSE) From b0285a24d12a46a51dbe67e83d0cc208a209dd57 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Thu, 17 Oct 2024 19:09:24 +1300 Subject: [PATCH 1161/1323] Version 2.8-RC4 --- htmx-api/pom.xml | 2 +- htmx-nima-jstache/pom.xml | 2 +- htmx-nima/pom.xml | 4 ++-- http-api-javalin/pom.xml | 2 +- http-api/pom.xml | 2 +- http-client-gson-adapter/pom.xml | 4 ++-- http-client-moshi-adapter/pom.xml | 4 ++-- http-client/pom.xml | 4 ++-- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 2 +- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-generator-sigma/pom.xml | 2 +- http-inject-plugin/pom.xml | 2 +- pom.xml | 2 +- tests/pom.xml | 2 +- tests/test-client-generation/pom.xml | 2 +- tests/test-client/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-htmx/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- tests/test-sigma/pom.xml | 2 +- 26 files changed, 30 insertions(+), 30 deletions(-) diff --git a/htmx-api/pom.xml b/htmx-api/pom.xml index 010acb986..5993dc8dc 100644 --- a/htmx-api/pom.xml +++ b/htmx-api/pom.xml @@ -6,7 +6,7 @@ io.avaje avaje-http-parent - 2.8-RC3 + 2.8-RC4 avaje-htmx-api diff --git a/htmx-nima-jstache/pom.xml b/htmx-nima-jstache/pom.xml index 84ebf9f8c..36ab96cdb 100644 --- a/htmx-nima-jstache/pom.xml +++ b/htmx-nima-jstache/pom.xml @@ -6,7 +6,7 @@ io.avaje avaje-http-parent - 2.8-RC3 + 2.8-RC4 avaje-htmx-nima-jstache diff --git a/htmx-nima/pom.xml b/htmx-nima/pom.xml index 3c460dcbe..c73d802ce 100644 --- a/htmx-nima/pom.xml +++ b/htmx-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje avaje-http-parent - 2.8-RC3 + 2.8-RC4 avaje-htmx-nima @@ -21,7 +21,7 @@ io.avaje avaje-htmx-api - 2.8-RC3 + 2.8-RC4 io.helidon.webserver diff --git a/http-api-javalin/pom.xml b/http-api-javalin/pom.xml index d46c51782..b8bb5f7d7 100644 --- a/http-api-javalin/pom.xml +++ b/http-api-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.8-RC3 + 2.8-RC4 .. diff --git a/http-api/pom.xml b/http-api/pom.xml index b9f88901f..51c354b05 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.8-RC3 + 2.8-RC4 .. diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index 2e81c4660..fd764969f 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.8-RC3 + 2.8-RC4 avaje-http-client-gson @@ -20,7 +20,7 @@ io.avaje avaje-http-client - 2.8-RC3 + 2.8-RC4 provided diff --git a/http-client-moshi-adapter/pom.xml b/http-client-moshi-adapter/pom.xml index 405d92b2e..a45880454 100644 --- a/http-client-moshi-adapter/pom.xml +++ b/http-client-moshi-adapter/pom.xml @@ -3,7 +3,7 @@ io.avaje avaje-http-parent - 2.8-RC3 + 2.8-RC4 avaje-http-client-moshi @@ -19,7 +19,7 @@ io.avaje avaje-http-client - 2.8-RC3 + 2.8-RC4 provided diff --git a/http-client/pom.xml b/http-client/pom.xml index c3c5c5d39..f5bbae84a 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.8-RC3 + 2.8-RC4 avaje-http-client @@ -66,7 +66,7 @@ io.avaje avaje-http-api - 2.8-RC3 + 2.8-RC4 test diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index 7683c4a38..f2ddbf6d8 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.8-RC3 + 2.8-RC4 avaje-http-client-generator diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index e3ec8a5c6..1d2bc2958 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.8-RC3 + 2.8-RC4 avaje-http-generator-core diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index 4d6e9a15e..4f2ea0637 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.8-RC3 + 2.8-RC4 avaje-http-helidon-generator diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index ab0617d41..77a70d038 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.8-RC3 + 2.8-RC4 avaje-http-javalin-generator diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index ad9e48d24..b2aee6bb9 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.8-RC3 + 2.8-RC4 avaje-http-jex-generator diff --git a/http-generator-sigma/pom.xml b/http-generator-sigma/pom.xml index 6acafc844..c1537219f 100644 --- a/http-generator-sigma/pom.xml +++ b/http-generator-sigma/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.8-RC3 + 2.8-RC4 avaje-http-sigma-generator diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index b20c28426..0bb0604de 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.8-RC3 + 2.8-RC4 .. diff --git a/pom.xml b/pom.xml index ccd4c9245..6796947b6 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-parent - 2.8-RC3 + 2.8-RC4 pom diff --git a/tests/pom.xml b/tests/pom.xml index 570c3c2cf..657626258 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.8-RC3 + 2.8-RC4 tests diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index 1e60293c2..619548afa 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.8-RC3 + 2.8-RC4 test-client-generation diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index 87ac90f7b..7c0705799 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.8-RC3 + 2.8-RC4 test-client diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 4c9fc376f..e90b53129 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 2.8-RC3 + 2.8-RC4 test-javalin-jsonb diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 5d2a15c98..95dea8d81 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.8-RC3 + 2.8-RC4 test-javalin diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index e2284c89d..3a2debf1a 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.8-RC3 + 2.8-RC4 test-jex diff --git a/tests/test-nima-htmx/pom.xml b/tests/test-nima-htmx/pom.xml index a7f609ce0..a1197fd61 100644 --- a/tests/test-nima-htmx/pom.xml +++ b/tests/test-nima-htmx/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.8-RC3 + 2.8-RC4 test-nima-htmx diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index a743861d3..a1ea7ee71 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.8-RC3 + 2.8-RC4 test-nima-jsonb diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index c2d0daaf3..894bd43a9 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.8-RC3 + 2.8-RC4 test-nima diff --git a/tests/test-sigma/pom.xml b/tests/test-sigma/pom.xml index 44948df0e..4bcc3d598 100644 --- a/tests/test-sigma/pom.xml +++ b/tests/test-sigma/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 2.8-RC3 + 2.8-RC4 test-sigma From e2b8aab2e298531332424bba823aae6ebc989df5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 21 Oct 2024 19:11:38 +0000 Subject: [PATCH 1162/1323] Bump the dependencies group with 5 updates Bumps the dependencies group with 5 updates: | Package | From | To | | --- | --- | --- | | [io.avaje:avaje-jsonb](https://github.com/avaje/avaje-jsonb) | `2.2` | `2.3` | | io.avaje:avaje-spi-service | `2.6` | `2.7` | | io.avaje:avaje-jsonb-generator | `2.2` | `2.3` | | [org.junit.jupiter:junit-jupiter-api](https://github.com/junit-team/junit5) | `5.11.2` | `5.11.3` | | [org.junit.jupiter:junit-jupiter-engine](https://github.com/junit-team/junit5) | `5.11.2` | `5.11.3` | Updates `io.avaje:avaje-jsonb` from 2.2 to 2.3 - [Release notes](https://github.com/avaje/avaje-jsonb/releases) - [Commits](https://github.com/avaje/avaje-jsonb/compare/2.2...2.3) Updates `io.avaje:avaje-spi-service` from 2.6 to 2.7 Updates `io.avaje:avaje-jsonb-generator` from 2.2 to 2.3 Updates `org.junit.jupiter:junit-jupiter-api` from 5.11.2 to 5.11.3 - [Release notes](https://github.com/junit-team/junit5/releases) - [Commits](https://github.com/junit-team/junit5/compare/r5.11.2...r5.11.3) Updates `org.junit.jupiter:junit-jupiter-engine` from 5.11.2 to 5.11.3 - [Release notes](https://github.com/junit-team/junit5/releases) - [Commits](https://github.com/junit-team/junit5/compare/r5.11.2...r5.11.3) Updates `org.junit.jupiter:junit-jupiter-engine` from 5.11.2 to 5.11.3 - [Release notes](https://github.com/junit-team/junit5/releases) - [Commits](https://github.com/junit-team/junit5/compare/r5.11.2...r5.11.3) --- updated-dependencies: - dependency-name: io.avaje:avaje-jsonb dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.avaje:avaje-spi-service dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.avaje:avaje-jsonb-generator dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: org.junit.jupiter:junit-jupiter-api dependency-type: direct:development update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: org.junit.jupiter:junit-jupiter-engine dependency-type: direct:development update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: org.junit.jupiter:junit-jupiter-engine dependency-type: direct:development update-type: version-update:semver-patch dependency-group: dependencies ... Signed-off-by: dependabot[bot] --- htmx-nima-jstache/pom.xml | 2 +- http-client/pom.xml | 2 +- http-inject-plugin/pom.xml | 2 +- tests/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 4 ++-- tests/test-nima-htmx/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 4 ++-- tests/test-sigma/pom.xml | 4 ++-- 8 files changed, 11 insertions(+), 11 deletions(-) diff --git a/htmx-nima-jstache/pom.xml b/htmx-nima-jstache/pom.xml index 36ab96cdb..8884d2bbc 100644 --- a/htmx-nima-jstache/pom.xml +++ b/htmx-nima-jstache/pom.xml @@ -46,7 +46,7 @@ io.avaje avaje-spi-service - 2.6 + 2.7 provided true diff --git a/http-client/pom.xml b/http-client/pom.xml index f5bbae84a..cadff26ab 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -36,7 +36,7 @@ io.avaje avaje-jsonb - 2.2 + 2.3 true diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index 0bb0604de..0840b6a5d 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -33,7 +33,7 @@ io.avaje avaje-spi-service - 2.6 + 2.7 provided true diff --git a/tests/pom.xml b/tests/pom.xml index 657626258..7761db976 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -12,7 +12,7 @@ true - 5.11.2 + 5.11.3 3.26.3 2.18.0 2.5 diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index e90b53129..29e090e7c 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -80,13 +80,13 @@ io.avaje avaje-jsonb - 2.2 + 2.3 io.avaje avaje-jsonb-generator - 2.2 + 2.3 provided diff --git a/tests/test-nima-htmx/pom.xml b/tests/test-nima-htmx/pom.xml index a1197fd61..8e7dc3a0f 100644 --- a/tests/test-nima-htmx/pom.xml +++ b/tests/test-nima-htmx/pom.xml @@ -82,7 +82,7 @@ io.avaje avaje-jsonb-generator - 2.2 + 2.3 io.jstach diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index a1ea7ee71..05eef070d 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -31,7 +31,7 @@ io.avaje avaje-jsonb - 2.2 + 2.3 io.avaje @@ -90,7 +90,7 @@ io.avaje avaje-jsonb-generator - 2.2 + 2.3 diff --git a/tests/test-sigma/pom.xml b/tests/test-sigma/pom.xml index 4bcc3d598..95534c3e2 100644 --- a/tests/test-sigma/pom.xml +++ b/tests/test-sigma/pom.xml @@ -73,12 +73,12 @@ io.avaje avaje-jsonb - 2.2 + 2.3 io.avaje avaje-jsonb-generator - 2.2 + 2.3 provided From a2f08c2c47ebcb5f340c951a170cb3429cfad5fb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 28 Oct 2024 19:17:54 +0000 Subject: [PATCH 1163/1323] Bump the dependencies group with 4 updates Bumps the dependencies group with 4 updates: [io.avaje:avaje-prisms](https://github.com/avaje/avaje-prisms), io.helidon.webserver:helidon-webserver, io.helidon.webserver:helidon-webserver-security and io.helidon.http.media:helidon-http-media-jsonb. Updates `io.avaje:avaje-prisms` from 1.32 to 1.33 - [Release notes](https://github.com/avaje/avaje-prisms/releases) - [Commits](https://github.com/avaje/avaje-prisms/compare/1.32...1.33) Updates `io.helidon.webserver:helidon-webserver` from 4.1.2 to 4.1.3 Updates `io.helidon.webserver:helidon-webserver-security` from 4.1.2 to 4.1.3 Updates `io.helidon.http.media:helidon-http-media-jsonb` from 4.1.2 to 4.1.3 Updates `io.helidon.webserver:helidon-webserver-security` from 4.1.2 to 4.1.3 Updates `io.helidon.http.media:helidon-http-media-jsonb` from 4.1.2 to 4.1.3 --- updated-dependencies: - dependency-name: io.avaje:avaje-prisms dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.helidon.webserver:helidon-webserver dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: io.helidon.webserver:helidon-webserver-security dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: io.helidon.http.media:helidon-http-media-jsonb dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: io.helidon.webserver:helidon-webserver-security dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: io.helidon.http.media:helidon-http-media-jsonb dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies ... Signed-off-by: dependabot[bot] --- htmx-nima/pom.xml | 2 +- pom.xml | 2 +- tests/pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/htmx-nima/pom.xml b/htmx-nima/pom.xml index c73d802ce..8a2e888f0 100644 --- a/htmx-nima/pom.xml +++ b/htmx-nima/pom.xml @@ -26,7 +26,7 @@ io.helidon.webserver helidon-webserver - 4.1.2 + 4.1.3 diff --git a/pom.xml b/pom.xml index 6796947b6..2e791ce7f 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ true 2.2.25 2.14.2 - 1.32 + 1.33 ${project.build.directory}${file.separator}module-info.shade diff --git a/tests/pom.xml b/tests/pom.xml index 7761db976..5bb0389d4 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -17,7 +17,7 @@ 2.18.0 2.5 10.4 - 4.1.2 + 4.1.3 6.3.0 From e5781fccc969d8310fb35879aeac040ebacc5a33 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 Nov 2024 19:40:42 +0000 Subject: [PATCH 1164/1323] Bump the dependencies group with 2 updates Bumps the dependencies group with 2 updates: [com.fasterxml.jackson.core:jackson-databind](https://github.com/FasterXML/jackson) and [io.avaje:avaje-prisms](https://github.com/avaje/avaje-prisms). Updates `com.fasterxml.jackson.core:jackson-databind` from 2.18.0 to 2.18.1 - [Commits](https://github.com/FasterXML/jackson/commits) Updates `io.avaje:avaje-prisms` from 1.33 to 1.34 - [Release notes](https://github.com/avaje/avaje-prisms/releases) - [Commits](https://github.com/avaje/avaje-prisms/compare/1.33...1.34) --- updated-dependencies: - dependency-name: com.fasterxml.jackson.core:jackson-databind dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: io.avaje:avaje-prisms dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies ... Signed-off-by: dependabot[bot] --- http-client/pom.xml | 2 +- pom.xml | 2 +- tests/pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/http-client/pom.xml b/http-client/pom.xml index cadff26ab..d283296dc 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -29,7 +29,7 @@ com.fasterxml.jackson.core jackson-databind - 2.18.0 + 2.18.1 true diff --git a/pom.xml b/pom.xml index 2e791ce7f..93b2068b1 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ true 2.2.25 2.14.2 - 1.33 + 1.34 ${project.build.directory}${file.separator}module-info.shade diff --git a/tests/pom.xml b/tests/pom.xml index 5bb0389d4..66f3f5191 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -14,7 +14,7 @@ true 5.11.3 3.26.3 - 2.18.0 + 2.18.1 2.5 10.4 4.1.3 From a11506768475ecf17f65eae20cfc42c6dc89e8f5 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 5 Nov 2024 21:16:58 +1300 Subject: [PATCH 1165/1323] Version 2.8 --- htmx-api/pom.xml | 2 +- htmx-nima-jstache/pom.xml | 2 +- htmx-nima/pom.xml | 4 ++-- http-api-javalin/pom.xml | 2 +- http-api/pom.xml | 2 +- http-client-gson-adapter/pom.xml | 4 ++-- http-client-moshi-adapter/pom.xml | 4 ++-- http-client/pom.xml | 4 ++-- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 2 +- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-generator-sigma/pom.xml | 2 +- http-inject-plugin/pom.xml | 2 +- pom.xml | 2 +- tests/pom.xml | 2 +- tests/test-client-generation/pom.xml | 2 +- tests/test-client/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-htmx/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- tests/test-sigma/pom.xml | 2 +- 26 files changed, 30 insertions(+), 30 deletions(-) diff --git a/htmx-api/pom.xml b/htmx-api/pom.xml index 5993dc8dc..4da6dae00 100644 --- a/htmx-api/pom.xml +++ b/htmx-api/pom.xml @@ -6,7 +6,7 @@ io.avaje avaje-http-parent - 2.8-RC4 + 2.8 avaje-htmx-api diff --git a/htmx-nima-jstache/pom.xml b/htmx-nima-jstache/pom.xml index 8884d2bbc..f01df7f31 100644 --- a/htmx-nima-jstache/pom.xml +++ b/htmx-nima-jstache/pom.xml @@ -6,7 +6,7 @@ io.avaje avaje-http-parent - 2.8-RC4 + 2.8 avaje-htmx-nima-jstache diff --git a/htmx-nima/pom.xml b/htmx-nima/pom.xml index 8a2e888f0..08f0d9a6d 100644 --- a/htmx-nima/pom.xml +++ b/htmx-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje avaje-http-parent - 2.8-RC4 + 2.8 avaje-htmx-nima @@ -21,7 +21,7 @@ io.avaje avaje-htmx-api - 2.8-RC4 + 2.8 io.helidon.webserver diff --git a/http-api-javalin/pom.xml b/http-api-javalin/pom.xml index b8bb5f7d7..c63513caf 100644 --- a/http-api-javalin/pom.xml +++ b/http-api-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.8-RC4 + 2.8 .. diff --git a/http-api/pom.xml b/http-api/pom.xml index 51c354b05..13ac6c317 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.8-RC4 + 2.8 .. diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index fd764969f..c2126baff 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.8-RC4 + 2.8 avaje-http-client-gson @@ -20,7 +20,7 @@ io.avaje avaje-http-client - 2.8-RC4 + 2.8 provided diff --git a/http-client-moshi-adapter/pom.xml b/http-client-moshi-adapter/pom.xml index a45880454..8ad8ef8f6 100644 --- a/http-client-moshi-adapter/pom.xml +++ b/http-client-moshi-adapter/pom.xml @@ -3,7 +3,7 @@ io.avaje avaje-http-parent - 2.8-RC4 + 2.8 avaje-http-client-moshi @@ -19,7 +19,7 @@ io.avaje avaje-http-client - 2.8-RC4 + 2.8 provided diff --git a/http-client/pom.xml b/http-client/pom.xml index d283296dc..583c76986 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.8-RC4 + 2.8 avaje-http-client @@ -66,7 +66,7 @@ io.avaje avaje-http-api - 2.8-RC4 + 2.8 test diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index f2ddbf6d8..7c27a7a42 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.8-RC4 + 2.8 avaje-http-client-generator diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 1d2bc2958..9b4fabfe1 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.8-RC4 + 2.8 avaje-http-generator-core diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index 4f2ea0637..e8da0cb46 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.8-RC4 + 2.8 avaje-http-helidon-generator diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index 77a70d038..5faac53e4 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.8-RC4 + 2.8 avaje-http-javalin-generator diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index b2aee6bb9..1eae077ef 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.8-RC4 + 2.8 avaje-http-jex-generator diff --git a/http-generator-sigma/pom.xml b/http-generator-sigma/pom.xml index c1537219f..025a1ebf3 100644 --- a/http-generator-sigma/pom.xml +++ b/http-generator-sigma/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.8-RC4 + 2.8 avaje-http-sigma-generator diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index 0840b6a5d..d58c41a6a 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.8-RC4 + 2.8 .. diff --git a/pom.xml b/pom.xml index 93b2068b1..5e8784add 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-parent - 2.8-RC4 + 2.8 pom diff --git a/tests/pom.xml b/tests/pom.xml index 66f3f5191..9d691b6b5 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.8-RC4 + 2.8 tests diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index 619548afa..fe931240c 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.8-RC4 + 2.8 test-client-generation diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index 7c0705799..32c725753 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.8-RC4 + 2.8 test-client diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 29e090e7c..1ab23eee4 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 2.8-RC4 + 2.8 test-javalin-jsonb diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 95dea8d81..ef65d99db 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.8-RC4 + 2.8 test-javalin diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 3a2debf1a..878ed9b8d 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.8-RC4 + 2.8 test-jex diff --git a/tests/test-nima-htmx/pom.xml b/tests/test-nima-htmx/pom.xml index 8e7dc3a0f..dcb44334f 100644 --- a/tests/test-nima-htmx/pom.xml +++ b/tests/test-nima-htmx/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.8-RC4 + 2.8 test-nima-htmx diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 05eef070d..c066699ea 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.8-RC4 + 2.8 test-nima-jsonb diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index 894bd43a9..8f4d63cea 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.8-RC4 + 2.8 test-nima diff --git a/tests/test-sigma/pom.xml b/tests/test-sigma/pom.xml index 95534c3e2..00006f9a1 100644 --- a/tests/test-sigma/pom.xml +++ b/tests/test-sigma/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 2.8-RC4 + 2.8 test-sigma From faef1c7420111d7bbb16c258693ab5897df5f17c Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 5 Nov 2024 21:17:36 +1300 Subject: [PATCH 1166/1323] Bump to next snapshot --- htmx-api/pom.xml | 2 +- htmx-nima-jstache/pom.xml | 2 +- htmx-nima/pom.xml | 4 ++-- http-api-javalin/pom.xml | 2 +- http-api/pom.xml | 2 +- http-client-gson-adapter/pom.xml | 4 ++-- http-client-moshi-adapter/pom.xml | 4 ++-- http-client/pom.xml | 4 ++-- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 2 +- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-generator-sigma/pom.xml | 2 +- http-inject-plugin/pom.xml | 2 +- pom.xml | 2 +- tests/pom.xml | 2 +- tests/test-client-generation/pom.xml | 2 +- tests/test-client/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-htmx/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- tests/test-sigma/pom.xml | 2 +- 26 files changed, 30 insertions(+), 30 deletions(-) diff --git a/htmx-api/pom.xml b/htmx-api/pom.xml index 4da6dae00..e932c70eb 100644 --- a/htmx-api/pom.xml +++ b/htmx-api/pom.xml @@ -6,7 +6,7 @@ io.avaje avaje-http-parent - 2.8 + 2.9-SNAPSHOT avaje-htmx-api diff --git a/htmx-nima-jstache/pom.xml b/htmx-nima-jstache/pom.xml index f01df7f31..b394fc809 100644 --- a/htmx-nima-jstache/pom.xml +++ b/htmx-nima-jstache/pom.xml @@ -6,7 +6,7 @@ io.avaje avaje-http-parent - 2.8 + 2.9-SNAPSHOT avaje-htmx-nima-jstache diff --git a/htmx-nima/pom.xml b/htmx-nima/pom.xml index 08f0d9a6d..71e467ed8 100644 --- a/htmx-nima/pom.xml +++ b/htmx-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje avaje-http-parent - 2.8 + 2.9-SNAPSHOT avaje-htmx-nima @@ -21,7 +21,7 @@ io.avaje avaje-htmx-api - 2.8 + 2.9-SNAPSHOT io.helidon.webserver diff --git a/http-api-javalin/pom.xml b/http-api-javalin/pom.xml index c63513caf..a0310fba5 100644 --- a/http-api-javalin/pom.xml +++ b/http-api-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.8 + 2.9-SNAPSHOT .. diff --git a/http-api/pom.xml b/http-api/pom.xml index 13ac6c317..a3aa1476e 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.8 + 2.9-SNAPSHOT .. diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index c2126baff..c672484af 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.8 + 2.9-SNAPSHOT avaje-http-client-gson @@ -20,7 +20,7 @@ io.avaje avaje-http-client - 2.8 + 2.9-SNAPSHOT provided diff --git a/http-client-moshi-adapter/pom.xml b/http-client-moshi-adapter/pom.xml index 8ad8ef8f6..44ae0bf64 100644 --- a/http-client-moshi-adapter/pom.xml +++ b/http-client-moshi-adapter/pom.xml @@ -3,7 +3,7 @@ io.avaje avaje-http-parent - 2.8 + 2.9-SNAPSHOT avaje-http-client-moshi @@ -19,7 +19,7 @@ io.avaje avaje-http-client - 2.8 + 2.9-SNAPSHOT provided diff --git a/http-client/pom.xml b/http-client/pom.xml index 583c76986..8fc244ac0 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.8 + 2.9-SNAPSHOT avaje-http-client @@ -66,7 +66,7 @@ io.avaje avaje-http-api - 2.8 + 2.9-SNAPSHOT test diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index 7c27a7a42..5f60f7f29 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.8 + 2.9-SNAPSHOT avaje-http-client-generator diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 9b4fabfe1..f5cbba44c 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.8 + 2.9-SNAPSHOT avaje-http-generator-core diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index e8da0cb46..fa0717bf5 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.8 + 2.9-SNAPSHOT avaje-http-helidon-generator diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index 5faac53e4..aa91a16fb 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.8 + 2.9-SNAPSHOT avaje-http-javalin-generator diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index 1eae077ef..b48989ce7 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.8 + 2.9-SNAPSHOT avaje-http-jex-generator diff --git a/http-generator-sigma/pom.xml b/http-generator-sigma/pom.xml index 025a1ebf3..d73f8f708 100644 --- a/http-generator-sigma/pom.xml +++ b/http-generator-sigma/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.8 + 2.9-SNAPSHOT avaje-http-sigma-generator diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index d58c41a6a..0fa8baff2 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.8 + 2.9-SNAPSHOT .. diff --git a/pom.xml b/pom.xml index 5e8784add..39f9b3599 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-parent - 2.8 + 2.9-SNAPSHOT pom diff --git a/tests/pom.xml b/tests/pom.xml index 9d691b6b5..a18e6a3ca 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.8 + 2.9-SNAPSHOT tests diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index fe931240c..7ce89b71c 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.8 + 2.9-SNAPSHOT test-client-generation diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index 32c725753..56ee06c4c 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.8 + 2.9-SNAPSHOT test-client diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 1ab23eee4..028e40e02 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 2.8 + 2.9-SNAPSHOT test-javalin-jsonb diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index ef65d99db..070793d6c 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.8 + 2.9-SNAPSHOT test-javalin diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 878ed9b8d..44821ce3d 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.8 + 2.9-SNAPSHOT test-jex diff --git a/tests/test-nima-htmx/pom.xml b/tests/test-nima-htmx/pom.xml index dcb44334f..7f3aaee66 100644 --- a/tests/test-nima-htmx/pom.xml +++ b/tests/test-nima-htmx/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.8 + 2.9-SNAPSHOT test-nima-htmx diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index c066699ea..b37331ebd 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.8 + 2.9-SNAPSHOT test-nima-jsonb diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index 8f4d63cea..9fa8e803d 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.8 + 2.9-SNAPSHOT test-nima diff --git a/tests/test-sigma/pom.xml b/tests/test-sigma/pom.xml index 00006f9a1..a3ba24260 100644 --- a/tests/test-sigma/pom.xml +++ b/tests/test-sigma/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 2.8 + 2.9-SNAPSHOT test-sigma From 98c889c86547d58a14efdc013542d30ed04e2222 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 11 Nov 2024 19:27:42 +0000 Subject: [PATCH 1167/1323] Bump the dependencies group with 4 updates Bumps the dependencies group with 4 updates: [io.avaje:avaje-inject](https://github.com/avaje/avaje-inject), io.avaje:avaje-inject-generator, io.avaje:avaje-spi-service and io.avaje:avaje-inject-maven-plugin. Updates `io.avaje:avaje-inject` from 10.4 to 10.5 - [Release notes](https://github.com/avaje/avaje-inject/releases) - [Commits](https://github.com/avaje/avaje-inject/compare/10.4...10.5) Updates `io.avaje:avaje-inject-generator` from 10.4 to 10.5 Updates `io.avaje:avaje-inject-generator` from 10.4 to 10.5 Updates `io.avaje:avaje-spi-service` from 2.7 to 2.8 Updates `io.avaje:avaje-inject-maven-plugin` from 10.4 to 10.5 --- updated-dependencies: - dependency-name: io.avaje:avaje-inject dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.avaje:avaje-inject-generator dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.avaje:avaje-inject-generator dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.avaje:avaje-spi-service dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.avaje:avaje-inject-maven-plugin dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies ... Signed-off-by: dependabot[bot] --- htmx-nima-jstache/pom.xml | 4 ++-- http-client/pom.xml | 4 ++-- http-inject-plugin/pom.xml | 4 ++-- tests/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/htmx-nima-jstache/pom.xml b/htmx-nima-jstache/pom.xml index b394fc809..ee44af79d 100644 --- a/htmx-nima-jstache/pom.xml +++ b/htmx-nima-jstache/pom.xml @@ -39,14 +39,14 @@ io.avaje avaje-inject - 10.4 + 10.5 provided true io.avaje avaje-spi-service - 2.7 + 2.8 provided true diff --git a/http-client/pom.xml b/http-client/pom.xml index 8fc244ac0..24f3f9b5c 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -43,7 +43,7 @@ io.avaje avaje-inject - 10.4 + 10.5 true @@ -99,7 +99,7 @@ io.avaje avaje-inject-generator - 10.4 + 10.5 diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index 0fa8baff2..8262412a3 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -19,7 +19,7 @@ io.avaje avaje-inject - 10.4 + 10.5 provided true @@ -33,7 +33,7 @@ io.avaje avaje-spi-service - 2.7 + 2.8 provided true diff --git a/tests/pom.xml b/tests/pom.xml index a18e6a3ca..520a329bf 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -16,7 +16,7 @@ 3.26.3 2.18.1 2.5 - 10.4 + 10.5 4.1.3 6.3.0 diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index b37331ebd..50886cbeb 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -109,7 +109,7 @@ io.avaje avaje-inject-maven-plugin - 10.4 + 10.5 process-sources From 078d250da73d9cc9f89d8dffaf9ce0c18ecae20a Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Thu, 14 Nov 2024 03:42:51 -0500 Subject: [PATCH 1168/1323] make http client autocloseable (#512) --- http-client/pom.xml | 2 +- .../io/avaje/http/client/DHttpClientContext.java | 16 ++++++++++++++++ .../java/io/avaje/http/client/HttpClient.java | 16 ++++++++++++++-- .../http/generator/client/ClientWriter.java | 8 +++++++- 4 files changed, 38 insertions(+), 4 deletions(-) diff --git a/http-client/pom.xml b/http-client/pom.xml index 24f3f9b5c..971f79362 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -66,7 +66,7 @@ io.avaje avaje-http-api - 2.9-SNAPSHOT + ${project.version} test diff --git a/http-client/src/main/java/io/avaje/http/client/DHttpClientContext.java b/http-client/src/main/java/io/avaje/http/client/DHttpClientContext.java index 1d2934285..987b2a43b 100644 --- a/http-client/src/main/java/io/avaje/http/client/DHttpClientContext.java +++ b/http-client/src/main/java/io/avaje/http/client/DHttpClientContext.java @@ -1,5 +1,7 @@ package io.avaje.http.client; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; import java.lang.reflect.Type; import java.net.http.HttpHeaders; import java.net.http.HttpRequest; @@ -9,6 +11,7 @@ import java.util.List; import java.util.Map; import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutorService; import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.LongAccumulator; import java.util.concurrent.atomic.LongAdder; @@ -340,4 +343,17 @@ private String authToken() { String maxResponseBody(String body) { return body.length() > 1_000 ? body.substring(0, 1_000) + " ..." : body; } + + @Override + public void close() { + if (Integer.getInteger("java.specification.version") >= 21) { + try { + MethodHandles.lookup() + .findVirtual(java.net.http.HttpClient.class, "close", MethodType.methodType(void.class)) + .invokeExact(httpClient); + } catch (Throwable t) { + throw new IllegalStateException("Failed to close java.net.http.HttpClient instance"); + } + } + } } diff --git a/http-client/src/main/java/io/avaje/http/client/HttpClient.java b/http-client/src/main/java/io/avaje/http/client/HttpClient.java index 38dc149b4..73cd70444 100644 --- a/http-client/src/main/java/io/avaje/http/client/HttpClient.java +++ b/http-client/src/main/java/io/avaje/http/client/HttpClient.java @@ -3,7 +3,6 @@ import java.net.Authenticator; import java.net.CookieHandler; import java.net.ProxySelector; -import java.net.http.HttpRequest; import java.time.Duration; import java.util.Map; import java.util.concurrent.Executor; @@ -33,7 +32,7 @@ * * } */ -public interface HttpClient { +public interface HttpClient extends AutoCloseable { /** * Return the builder to config and build the client context. @@ -93,6 +92,19 @@ static Builder builder() { */ HttpClient.Metrics metrics(boolean reset); + /** + * Note: invoking this method has no effect on JDK versions less than 21. + * + *

    Initiates an orderly shutdown in which http requests previously submitted are run to + * completion, but no new requests will be accepted. Running a request to completion may involve + * running several operations in the background, including waiting for responses to be delivered. + * This method waits until all operations have completed execution and the client has terminated. + * + * @see {@linkplain java.net.http.HttpClient#close} + */ + @Override + void close(); + /** * Builds the HttpClient. * diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientWriter.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientWriter.java index 52d7d9445..1291a06eb 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientWriter.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientWriter.java @@ -1,5 +1,6 @@ package io.avaje.http.generator.client; +import io.avaje.http.generator.core.APContext; import io.avaje.http.generator.core.BaseControllerWriter; import io.avaje.http.generator.core.ControllerReader; import io.avaje.http.generator.core.MethodReader; @@ -62,12 +63,17 @@ private void writeMethods() { for (final ClientMethodWriter methodWriter : methodList) { methodWriter.write(); } + writer.append(" @Override").eol(); + writer.append(" public void close() {").eol(); + writer.append(" this.client.close();").eol(); + writer.append(" }").eol(); } private void writeClassStart() { writer.append(AT_GENERATED).eol(); AnnotationUtil.writeAnnotations(writer, reader.beanType()); - writer.append("public class %s%s implements %s {", shortName, suffix, shortName).eol().eol(); + + writer.append("public class %s%s implements %s, AutoCloseable {", shortName, suffix, shortName).eol().eol(); writer.append(" private final HttpClient client;").eol().eol(); From 9451927c48c427da67b89e6231e47c904ee3a657 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 18 Nov 2024 19:49:31 +0000 Subject: [PATCH 1169/1323] Bump the dependencies group with 6 updates Bumps the dependencies group with 6 updates: | Package | From | To | | --- | --- | --- | | [io.avaje:avaje-prisms](https://github.com/avaje/avaje-prisms) | `1.34` | `1.35` | | io.swagger.core.v3:swagger-annotations | `2.2.25` | `2.2.26` | | io.swagger.core.v3:swagger-models | `2.2.25` | `2.2.26` | | io.helidon.webserver:helidon-webserver | `4.1.3` | `4.1.4` | | io.helidon.webserver:helidon-webserver-security | `4.1.3` | `4.1.4` | | io.helidon.http.media:helidon-http-media-jsonb | `4.1.3` | `4.1.4` | Updates `io.avaje:avaje-prisms` from 1.34 to 1.35 - [Release notes](https://github.com/avaje/avaje-prisms/releases) - [Commits](https://github.com/avaje/avaje-prisms/compare/1.34...1.35) Updates `io.swagger.core.v3:swagger-annotations` from 2.2.25 to 2.2.26 Updates `io.swagger.core.v3:swagger-models` from 2.2.25 to 2.2.26 Updates `io.swagger.core.v3:swagger-models` from 2.2.25 to 2.2.26 Updates `io.helidon.webserver:helidon-webserver` from 4.1.3 to 4.1.4 Updates `io.helidon.webserver:helidon-webserver-security` from 4.1.3 to 4.1.4 Updates `io.helidon.http.media:helidon-http-media-jsonb` from 4.1.3 to 4.1.4 Updates `io.helidon.webserver:helidon-webserver-security` from 4.1.3 to 4.1.4 Updates `io.helidon.http.media:helidon-http-media-jsonb` from 4.1.3 to 4.1.4 --- updated-dependencies: - dependency-name: io.avaje:avaje-prisms dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.swagger.core.v3:swagger-annotations dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: io.swagger.core.v3:swagger-models dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: io.swagger.core.v3:swagger-models dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: io.helidon.webserver:helidon-webserver dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: io.helidon.webserver:helidon-webserver-security dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: io.helidon.http.media:helidon-http-media-jsonb dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: io.helidon.webserver:helidon-webserver-security dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: io.helidon.http.media:helidon-http-media-jsonb dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies ... Signed-off-by: dependabot[bot] --- htmx-nima/pom.xml | 2 +- pom.xml | 4 ++-- tests/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-sigma/pom.xml | 2 +- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/htmx-nima/pom.xml b/htmx-nima/pom.xml index 71e467ed8..397dd1316 100644 --- a/htmx-nima/pom.xml +++ b/htmx-nima/pom.xml @@ -26,7 +26,7 @@ io.helidon.webserver helidon-webserver - 4.1.3 + 4.1.4 diff --git a/pom.xml b/pom.xml index 39f9b3599..320cdd772 100644 --- a/pom.xml +++ b/pom.xml @@ -19,9 +19,9 @@ true - 2.2.25 + 2.2.26 2.14.2 - 1.34 + 1.35 ${project.build.directory}${file.separator}module-info.shade diff --git a/tests/pom.xml b/tests/pom.xml index 520a329bf..b4c892a83 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -17,7 +17,7 @@ 2.18.1 2.5 10.5 - 4.1.3 + 4.1.4 6.3.0 diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 028e40e02..ae3a0c81d 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -13,7 +13,7 @@ true org.example.myapp.Main - 2.2.25 + 2.2.26 1.3.71 diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 070793d6c..2647c2470 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -12,7 +12,7 @@ true org.example.myapp.Main - 2.2.25 + 2.2.26 1.3.71 diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 44821ce3d..d5889c04b 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -13,7 +13,7 @@ true org.example.myapp.Main 2.5 - 2.2.25 + 2.2.26 diff --git a/tests/test-sigma/pom.xml b/tests/test-sigma/pom.xml index a3ba24260..fd0f01ce7 100644 --- a/tests/test-sigma/pom.xml +++ b/tests/test-sigma/pom.xml @@ -13,7 +13,7 @@ 17 true - 2.2.25 + 2.2.26 1.3.71 From dab399ac6bf73bd20c2bf4489e97a62e33278997 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Mon, 18 Nov 2024 15:46:07 -0500 Subject: [PATCH 1170/1323] fix serializer --- http-generator-core/pom.xml | 6 ------ .../core/openapi/OpenAPISerializer.java | 20 ++++++++++++------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index f5cbba44c..6fea1e154 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -34,12 +34,6 @@ provided - - io.swagger.core.v3 - swagger-annotations - ${swagger.version} - provided - io.swagger.core.v3 swagger-models diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/OpenAPISerializer.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/OpenAPISerializer.java index 9b24d6037..0899323a7 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/OpenAPISerializer.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/OpenAPISerializer.java @@ -3,9 +3,20 @@ import java.lang.reflect.Field; import java.util.Collection; import java.util.Map; +import java.util.Set; final class OpenAPISerializer { + private static final Set IGNORED_FIELDS = Set.of( + "SCHEMA_RESOLUTION_PROPERTY", + "BIND_TYPE_AND_TYPES", + "BINARY_STRING_CONVERSION_PROPERTY", + "COMPONENTS_SCHEMAS_REF", + "APPLY_SCHEMA_RESOLUTION_PROPERTY", + "exampleSetFlag", + "types", + "specVersion"); + private OpenAPISerializer() {} /** @@ -65,13 +76,8 @@ static String serialize(Object obj) throws IllegalAccessException { for (final Field field : fields) { // skip JsonIgnored fields - if ("SCHEMA_RESOLUTION_PROPERTY".equals(field.getName()) - || "BIND_TYPE_AND_TYPES".equals(field.getName()) - || "BINARY_STRING_CONVERSION_PROPERTY".equals(field.getName()) - || "COMPONENTS_SCHEMAS_REF".equals(field.getName()) - || "exampleSetFlag".equals(field.getName()) - || "types".equals(field.getName()) - || "specVersion".equals(field.getName())) { + if (IGNORED_FIELDS + .contains(field.getName())) { continue; } From 069e1853234204c5f5b26d31a3c1b0afc36ab5e4 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Mon, 25 Nov 2024 21:31:38 +1300 Subject: [PATCH 1171/1323] [Jex] Modify generated code for Jex controllers to use handler methods This will make it easier to support an HTMX extension for jex --- .../generator/jex/ControllerMethodWriter.java | 44 +++++++++++-------- .../http/generator/jex/ControllerWriter.java | 25 ++++++++--- .../avaje/http/generator/jex/JexAdapter.java | 4 +- 3 files changed, 46 insertions(+), 27 deletions(-) diff --git a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java index da6d99a86..9c45addb7 100644 --- a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java +++ b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java @@ -14,7 +14,7 @@ class ControllerMethodWriter { private final MethodReader method; private final Append writer; private final WebMethod webMethod; - private boolean instrumentContext; + private final boolean instrumentContext; ControllerMethodWriter(MethodReader method, Append writer) { this.method = method; @@ -23,16 +23,37 @@ class ControllerMethodWriter { this.instrumentContext = method.instrumentContext(); } - void write(boolean requestScoped) { + void writeRouting() { final PathSegments segments = method.pathSegments(); final String fullPath = segments.fullPath(); + writer.append(" routing.%s(\"%s\", this::_%s)", webMethod.name().toLowerCase(), fullPath, method.simpleName()); + List roles = method.roles(); + if (!roles.isEmpty()) { + writer.append(".withRoles("); + for (int i = 0; i < roles.size(); i++) { + if (i > 0) { + writer.append(", "); + } + writer.append(Util.shortName(roles.get(i), true)); + } + writer.append(")"); + } + writer.append(";").eol(); + } - writer.append(" routing.%s(\"%s\", ctx -> {", webMethod.name().toLowerCase(), fullPath).eol(); + void writeHandler(boolean requestScoped) { + writer.append(" private void _%s(Context ctx) {", method.simpleName()).eol(); + write(requestScoped); + writer.append(" }").eol().eol(); + } + + private void write(boolean requestScoped) { int statusCode = method.statusCode(); if (statusCode > 0) { - writer.append(" ctx.status(%d);", statusCode).eol(); + writer.append(" ctx.status(%d);", statusCode).eol(); } + final PathSegments segments = method.pathSegments(); List matrixSegments = segments.matrixSegments(); for (PathSegments.Segment matrixSegment : matrixSegments) { matrixSegment.writeCreateSegment(writer, platform()); @@ -47,7 +68,7 @@ void write(boolean requestScoped) { param.writeValidate(writer); } } - writer.append(" "); + writer.append(" "); if (!method.isVoid()) { writeContextReturn(); } @@ -74,19 +95,6 @@ void write(boolean requestScoped) { writer.append(")"); } writer.append(";").eol(); - writer.append(" }"); - - List roles = method.roles(); - if (!roles.isEmpty()) { - writer.append(").withRoles("); - for (int i = 0; i < roles.size(); i++) { - if (i > 0) { - writer.append(", "); - } - writer.append(Util.shortName(roles.get(i), true)); - } - } - writer.append(");").eol().eol(); } private void writeContextReturn() { diff --git a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerWriter.java b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerWriter.java index 5f8bcad00..96d0bee61 100644 --- a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerWriter.java +++ b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerWriter.java @@ -11,11 +11,13 @@ class ControllerWriter extends BaseControllerWriter { private static final String AT_GENERATED = "@Generated(\"avaje-jex-generator\")"; + private static final String API_CONTEXT = "io.avaje.jex.Context"; private static final String API_ROUTING = "io.avaje.jex.Routing"; private static final String API_ROUTING_SERVICE = "io.avaje.jex.Routing.Service"; ControllerWriter(ControllerReader reader) throws IOException { super(reader); + reader.addImportType(API_CONTEXT); reader.addImportType(API_ROUTING); reader.addImportType(API_ROUTING_SERVICE); } @@ -25,27 +27,36 @@ void write() { writeImports(); writeClassStart(); writeAddRoutes(); + writeHandlers(); writeClassEnd(); } private void writeAddRoutes() { writer.append(" @Override").eol(); - writer.append(" public void add(Routing routing) {").eol().eol(); + writer.append(" public void add(Routing routing) {").eol(); for (MethodReader method : reader.methods()) { if (method.isWebMethod()) { - writeForMethod(method); + writeRouting(method); } } writer.append(" }").eol().eol(); } - private void writeForMethod(MethodReader method) { - new ControllerMethodWriter(method, writer).write(isRequestScoped()); - if (!reader.isDocHidden()) { - method.buildApiDocumentation(); + private void writeHandlers() { + for (MethodReader method : reader.methods()) { + if (method.isWebMethod()) { + new ControllerMethodWriter(method, writer).writeHandler(isRequestScoped()); + if (!reader.isDocHidden()) { + method.buildApiDocumentation(); + } + } } } + private void writeRouting(MethodReader method) { + new ControllerMethodWriter(method, writer).writeRouting(); + } + private void writeClassStart() { writer.append(AT_GENERATED).eol(); writer.append(diAnnotation()).eol(); @@ -62,7 +73,7 @@ private void writeClassStart() { if (reader.isIncludeValidator()) { writer.append(" private final Validator validator;").eol(); } - + if (instrumentContext) { writer.append(" private final RequestContextResolver resolver;").eol(); } diff --git a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/JexAdapter.java b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/JexAdapter.java index fc0daba4e..9943c1e31 100644 --- a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/JexAdapter.java +++ b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/JexAdapter.java @@ -38,7 +38,7 @@ public String bodyAsClass(UType uType) { @Override public String indent() { - return " "; + return " "; } @Override @@ -85,7 +85,7 @@ public void writeReadCollectionParameter( } writer.append("withDefault(ctx.queryParams(\"%s\"), java.util.List.of(\"%s\"))", paramName, String.join(",", paramDefault)); } - + @Override public void writeAcceptLanguage(Append writer) { writer.append("ctx.header(\"%s\")", Constants.ACCEPT_LANGUAGE); From e6dc1c57221bc9565b2fe7865ed66137f138ba8d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 Nov 2024 20:00:59 +0000 Subject: [PATCH 1172/1323] Bump the dependencies group with 3 updates Bumps the dependencies group with 3 updates: [io.avaje:avaje-inject](https://github.com/avaje/avaje-inject), io.avaje:avaje-inject-generator and io.avaje:avaje-inject-maven-plugin. Updates `io.avaje:avaje-inject` from 10.5 to 11.0 - [Release notes](https://github.com/avaje/avaje-inject/releases) - [Commits](https://github.com/avaje/avaje-inject/compare/10.5...11.0) Updates `io.avaje:avaje-inject-generator` from 10.5 to 11.0 Updates `io.avaje:avaje-inject-generator` from 10.5 to 11.0 Updates `io.avaje:avaje-inject-maven-plugin` from 10.5 to 11.0 --- updated-dependencies: - dependency-name: io.avaje:avaje-inject dependency-type: direct:production update-type: version-update:semver-major dependency-group: dependencies - dependency-name: io.avaje:avaje-inject-generator dependency-type: direct:production update-type: version-update:semver-major dependency-group: dependencies - dependency-name: io.avaje:avaje-inject-generator dependency-type: direct:production update-type: version-update:semver-major dependency-group: dependencies - dependency-name: io.avaje:avaje-inject-maven-plugin dependency-type: direct:production update-type: version-update:semver-major dependency-group: dependencies ... Signed-off-by: dependabot[bot] --- htmx-nima-jstache/pom.xml | 2 +- http-client/pom.xml | 4 ++-- http-inject-plugin/pom.xml | 2 +- tests/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/htmx-nima-jstache/pom.xml b/htmx-nima-jstache/pom.xml index ee44af79d..db268a8b8 100644 --- a/htmx-nima-jstache/pom.xml +++ b/htmx-nima-jstache/pom.xml @@ -39,7 +39,7 @@ io.avaje avaje-inject - 10.5 + 11.0 provided true diff --git a/http-client/pom.xml b/http-client/pom.xml index 971f79362..eec42decd 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -43,7 +43,7 @@ io.avaje avaje-inject - 10.5 + 11.0 true @@ -99,7 +99,7 @@ io.avaje avaje-inject-generator - 10.5 + 11.0 diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index 8262412a3..284aea3ea 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -19,7 +19,7 @@ io.avaje avaje-inject - 10.5 + 11.0 provided true diff --git a/tests/pom.xml b/tests/pom.xml index b4c892a83..a0e9a2602 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -16,7 +16,7 @@ 3.26.3 2.18.1 2.5 - 10.5 + 11.0 4.1.4 6.3.0 diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 50886cbeb..85487c196 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -109,7 +109,7 @@ io.avaje avaje-inject-maven-plugin - 10.5 + 11.0 process-sources From 480bfb644220a974dd9fc9337e6d99540332141b Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Mon, 25 Nov 2024 17:21:21 -0500 Subject: [PATCH 1173/1323] fix validation --- http-hibernate-validator/pom.xml | 2 +- tests/test-javalin/pom.xml | 16 ++++++++++++++-- .../java/org/example/myapp/web/GetBeanForm.java | 8 ++++---- .../org/example/myapp/web/HelloController.java | 2 +- .../java/org/example/myapp/web/HelloForm.java | 15 +++++++-------- .../org/example/myapp/HelloControllerTest.java | 11 +++++------ 6 files changed, 32 insertions(+), 22 deletions(-) diff --git a/http-hibernate-validator/pom.xml b/http-hibernate-validator/pom.xml index 323d53949..82c917cc6 100644 --- a/http-hibernate-validator/pom.xml +++ b/http-hibernate-validator/pom.xml @@ -43,7 +43,7 @@ io.avaje avaje-inject - 10.1 + 11.0 provided diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 2647c2470..f6e89d175 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -56,8 +56,14 @@ io.avaje - avaje-http-hibernate-validator - 3.5-RC3 + avaje-validator + 2.3 + + + + io.avaje + avaje-validator-constraints + 2.3 @@ -81,6 +87,12 @@ ${project.version} provided + + + io.avaje + avaje-validator-generator + 2.3 + diff --git a/tests/test-javalin/src/main/java/org/example/myapp/web/GetBeanForm.java b/tests/test-javalin/src/main/java/org/example/myapp/web/GetBeanForm.java index d9337c43d..7fba63af6 100644 --- a/tests/test-javalin/src/main/java/org/example/myapp/web/GetBeanForm.java +++ b/tests/test-javalin/src/main/java/org/example/myapp/web/GetBeanForm.java @@ -1,9 +1,9 @@ package org.example.myapp.web; -import jakarta.validation.Valid; -import jakarta.validation.constraints.Email; -import jakarta.validation.constraints.NotNull; -import jakarta.validation.constraints.Size; +import io.avaje.validation.constraints.Email; +import io.avaje.validation.constraints.NotNull; +import io.avaje.validation.constraints.Size; +import io.avaje.validation.constraints.Valid; @Valid public class GetBeanForm { diff --git a/tests/test-javalin/src/main/java/org/example/myapp/web/HelloController.java b/tests/test-javalin/src/main/java/org/example/myapp/web/HelloController.java index bfad1c72a..0dbc23f18 100644 --- a/tests/test-javalin/src/main/java/org/example/myapp/web/HelloController.java +++ b/tests/test-javalin/src/main/java/org/example/myapp/web/HelloController.java @@ -21,10 +21,10 @@ import io.avaje.http.api.Post; import io.avaje.http.api.Produces; import io.avaje.http.api.QueryParam; +import io.avaje.http.api.Valid; import io.javalin.http.Context; import io.swagger.v3.oas.annotations.Hidden; import jakarta.inject.Inject; -import jakarta.validation.Valid; /** * Hello resource manager. diff --git a/tests/test-javalin/src/main/java/org/example/myapp/web/HelloForm.java b/tests/test-javalin/src/main/java/org/example/myapp/web/HelloForm.java index ea8750600..45eaa5909 100644 --- a/tests/test-javalin/src/main/java/org/example/myapp/web/HelloForm.java +++ b/tests/test-javalin/src/main/java/org/example/myapp/web/HelloForm.java @@ -2,13 +2,12 @@ import java.time.LocalDate; -import org.hibernate.validator.constraints.URL; - -import jakarta.validation.Valid; -import jakarta.validation.constraints.Email; -import jakarta.validation.constraints.Future; -import jakarta.validation.constraints.NotNull; -import jakarta.validation.constraints.Size; +import io.avaje.validation.constraints.Email; +import io.avaje.validation.constraints.Future; +import io.avaje.validation.constraints.NotNull; +import io.avaje.validation.constraints.Size; +import io.avaje.validation.constraints.URI; +import io.avaje.validation.constraints.Valid; @Valid public class HelloForm { @@ -19,7 +18,7 @@ public class HelloForm { @Email @Size(max = 100) String email; - @URL + @URI String url; @Future diff --git a/tests/test-javalin/src/test/java/org/example/myapp/HelloControllerTest.java b/tests/test-javalin/src/test/java/org/example/myapp/HelloControllerTest.java index a1d38a1ea..4686d58ad 100644 --- a/tests/test-javalin/src/test/java/org/example/myapp/HelloControllerTest.java +++ b/tests/test-javalin/src/test/java/org/example/myapp/HelloControllerTest.java @@ -45,7 +45,7 @@ void hello() { @Test void hello2() { - TypeRef> listDto = new TypeRef>() { }; + TypeRef> listDto = new TypeRef<>() { }; final List beans = given() .get(baseUrl + "/hello") .then() @@ -65,7 +65,7 @@ void hello2() { @Test void helloAsyncRequestHandling() { - TypeRef> listDto = new TypeRef>() { }; + TypeRef> listDto = new TypeRef<>() { }; final List beans = given() .get(baseUrl + "/hello/async") .then() @@ -209,9 +209,7 @@ void postForm_validation_expect_badRequest() { .as(ErrorResponse.class); assertNotNull(res); - assertThat(res.getMessage()).contains("failed validation"); - assertThat(res.get("url")).isEqualTo("must be a valid URL"); - assertThat(res.get("name")).isEqualTo("must not be null"); + assertThat(res.getMessage()).contains("must not be null"); try { client.request() @@ -229,7 +227,8 @@ void postForm_validation_expect_badRequest() { assertEquals(422, httpResponse.statusCode()); final ErrorResponse errorResponse = e.bean(ErrorResponse.class); - assertThat(errorResponse.get("url")).isEqualTo("must be a valid URL"); + + assertThat(res.getMessage()).contains("must not be null"); assertThat(errorResponse.get("name")).isEqualTo("must not be null"); } } From 0531ce0927549f4bf012e2ae331e528f6164f926 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Mon, 25 Nov 2024 17:29:16 -0500 Subject: [PATCH 1174/1323] fix jsonb --- tests/test-javalin-jsonb/pom.xml | 25 ++++++++++++++----- .../org/example/myapp/web/GetBeanForm.java | 9 ++++--- .../java/org/example/myapp/web/HelloForm.java | 23 +++++++++-------- .../example/myapp/HelloControllerTest.java | 8 +++--- 4 files changed, 39 insertions(+), 26 deletions(-) diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index ae3a0c81d..08ba13d24 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -49,16 +49,22 @@ ${project.version} - - io.avaje - avaje-http-hibernate-validator - 3.5-RC3 - - io.swagger.core.v3 swagger-annotations ${swagger.version} + + + + io.avaje + avaje-validator + 2.3 + + + + io.avaje + avaje-validator-constraints + 2.3 @@ -89,6 +95,13 @@ 2.3 provided + + + io.avaje + avaje-validator-generator + 2.3 + + diff --git a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/GetBeanForm.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/GetBeanForm.java index 70818500d..e6f5150bd 100644 --- a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/GetBeanForm.java +++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/GetBeanForm.java @@ -3,14 +3,15 @@ import java.util.List; import java.util.Set; +import org.jetbrains.annotations.NotNull; + import io.avaje.http.api.Header; import io.avaje.http.api.Ignore; import io.avaje.http.api.QueryParam; +import io.avaje.http.api.Valid; import io.avaje.jsonb.Json; -import jakarta.validation.Valid; -import jakarta.validation.constraints.Email; -import jakarta.validation.constraints.NotNull; -import jakarta.validation.constraints.Size; +import io.avaje.validation.constraints.Email; +import io.avaje.validation.constraints.Size; @Json @Valid diff --git a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/HelloForm.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/HelloForm.java index 51dcfb085..c278df5ac 100644 --- a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/HelloForm.java +++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/HelloForm.java @@ -2,14 +2,13 @@ import java.time.LocalDate; -import org.hibernate.validator.constraints.URL; - +import io.avaje.http.api.Valid; import io.avaje.jsonb.Json; -import jakarta.validation.Valid; -import jakarta.validation.constraints.Email; -import jakarta.validation.constraints.Future; -import jakarta.validation.constraints.NotNull; -import jakarta.validation.constraints.Size; +import io.avaje.validation.constraints.Email; +import io.avaje.validation.constraints.Future; +import io.avaje.validation.constraints.NotNull; +import io.avaje.validation.constraints.Size; +import io.avaje.validation.constraints.URI; @Json @Valid @@ -22,10 +21,12 @@ public class HelloForm { @Email @Size(max = 100) String email; -@URL - private String url; -@Future - public LocalDate startDate; + + @URI + private String url; + + @Future + public LocalDate startDate; public HelloForm(String name, String email) { this.name = name; diff --git a/tests/test-javalin-jsonb/src/test/java/org/example/myapp/HelloControllerTest.java b/tests/test-javalin-jsonb/src/test/java/org/example/myapp/HelloControllerTest.java index 80f8619cb..f6296b4d2 100644 --- a/tests/test-javalin-jsonb/src/test/java/org/example/myapp/HelloControllerTest.java +++ b/tests/test-javalin-jsonb/src/test/java/org/example/myapp/HelloControllerTest.java @@ -45,7 +45,7 @@ void hello() { @Test void hello2() { - TypeRef> listDto = new TypeRef>() { }; + TypeRef> listDto = new TypeRef<>() { }; final List beans = given() .get(baseUrl + "/hello") .then() @@ -64,7 +64,7 @@ void hello2() { @Test void helloAsyncRequestHandling() { - TypeRef> listDto = new TypeRef>() { }; + TypeRef> listDto = new TypeRef<>() { }; final List beans = given() .get(baseUrl + "/hello/async") .then() @@ -207,8 +207,6 @@ void postForm_validation_expect_badRequest() { .as(ErrorResponse.class); assertNotNull(res); - assertThat(res.getMessage()).contains("failed validation"); - assertThat(res.get("url")).isEqualTo("must be a valid URL"); assertThat(res.get("name")).isEqualTo("must not be null"); try { @@ -227,7 +225,7 @@ void postForm_validation_expect_badRequest() { assertEquals(422, httpResponse.statusCode()); final ErrorResponse errorResponse = e.bean(ErrorResponse.class); - assertThat(errorResponse.get("url")).isEqualTo("must be a valid URL"); + assertThat(res.get("name")).isEqualTo("must not be null"); assertThat(errorResponse.get("name")).isEqualTo("must not be null"); } } From 811de3b91bd9d75ac9240e9fc18d910ea9557f94 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Mon, 25 Nov 2024 17:42:37 -0500 Subject: [PATCH 1175/1323] fix valid --- .../src/main/java/org/example/myapp/web/GetBeanForm.java | 2 +- tests/test-javalin/src/main/java/org/example/myapp/Main.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/GetBeanForm.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/GetBeanForm.java index e6f5150bd..0c7c46682 100644 --- a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/GetBeanForm.java +++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/GetBeanForm.java @@ -8,10 +8,10 @@ import io.avaje.http.api.Header; import io.avaje.http.api.Ignore; import io.avaje.http.api.QueryParam; -import io.avaje.http.api.Valid; import io.avaje.jsonb.Json; import io.avaje.validation.constraints.Email; import io.avaje.validation.constraints.Size; +import io.avaje.validation.constraints.Valid; @Json @Valid diff --git a/tests/test-javalin/src/main/java/org/example/myapp/Main.java b/tests/test-javalin/src/main/java/org/example/myapp/Main.java index c08fbd8d9..5a6c402af 100644 --- a/tests/test-javalin/src/main/java/org/example/myapp/Main.java +++ b/tests/test-javalin/src/main/java/org/example/myapp/Main.java @@ -19,7 +19,7 @@ import io.swagger.v3.oas.annotations.OpenAPIDefinition; import io.swagger.v3.oas.annotations.info.Info; -@InjectModule(name = "app", requires = Validator.class) +@InjectModule(name = "app") @OpenAPIDefinition(info = @Info(title = "Example service", description = "Example Javalin controllers with Java and Maven")) public class Main { From 68b7759e2e6f784010ef9b719c53276650514cff Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Mon, 25 Nov 2024 18:20:08 -0500 Subject: [PATCH 1176/1323] fix tests --- .gitignore | 2 ++ tests/pom.xml | 21 ++++++++++++++++++ tests/test-javalin-jsonb/pom.xml | 21 +----------------- .../org/example/myapp/web/GetBeanForm.java | 3 +-- tests/test-javalin/pom.xml | 13 ----------- tests/test-jex/pom.xml | 6 ----- .../src/main/java/org/example/Main.java | 3 --- .../main/java/org/example/web/HelloDto.java | 4 ++-- tests/test-nima-jsonb/.project | 2 +- tests/test-nima-jsonb/pom.xml | 10 ++++----- .../src/test/java/org/example/TestPair.java | 8 ++++--- tests/test-sigma/pom.xml | 8 +------ .../org/example/myapp/web/GetBeanForm.java | 8 +++---- .../java/org/example/myapp/web/HelloForm.java | 22 +++++++++---------- 14 files changed, 54 insertions(+), 77 deletions(-) diff --git a/.gitignore b/.gitignore index 387d29edc..6eb138889 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,5 @@ build/ *.Module dependency-reduced-pom.xml .DS_Store +tests/test-sigma/avaje-processors.txt +tests/test-sigma/io.avaje.jsonb.spi.JsonbExtension diff --git a/tests/pom.xml b/tests/pom.xml index a0e9a2602..8c5631b15 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -43,5 +43,26 @@ + + + + io.avaje + avaje-validator + 2.3 + + + + io.avaje + avaje-validator-constraints + 2.3 + + + + io.avaje + avaje-validator-generator + 2.3 + + + diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 08ba13d24..a51f92fd3 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -54,19 +54,7 @@ swagger-annotations ${swagger.version} - - - io.avaje - avaje-validator - 2.3 - - - - io.avaje - avaje-validator-constraints - 2.3 - - + @@ -96,13 +84,6 @@ provided - - io.avaje - avaje-validator-generator - 2.3 - - - io.avaje diff --git a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/GetBeanForm.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/GetBeanForm.java index 0c7c46682..b264954b5 100644 --- a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/GetBeanForm.java +++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/GetBeanForm.java @@ -3,13 +3,12 @@ import java.util.List; import java.util.Set; -import org.jetbrains.annotations.NotNull; - import io.avaje.http.api.Header; import io.avaje.http.api.Ignore; import io.avaje.http.api.QueryParam; import io.avaje.jsonb.Json; import io.avaje.validation.constraints.Email; +import io.avaje.validation.constraints.NotNull; import io.avaje.validation.constraints.Size; import io.avaje.validation.constraints.Valid; diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index f6e89d175..cbec16d39 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -60,12 +60,6 @@ 2.3 - - io.avaje - avaje-validator-constraints - 2.3 - - io.swagger.core.v3 swagger-annotations @@ -87,13 +81,6 @@ ${project.version} provided - - - io.avaje - avaje-validator-generator - 2.3 - - diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index d5889c04b..ab8184eef 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -54,12 +54,6 @@ ${project.version} - - io.avaje - avaje-http-hibernate-validator - 3.5-RC3 - - io.swagger.core.v3 swagger-annotations diff --git a/tests/test-jex/src/main/java/org/example/Main.java b/tests/test-jex/src/main/java/org/example/Main.java index c1bb6d537..a485c3905 100644 --- a/tests/test-jex/src/main/java/org/example/Main.java +++ b/tests/test-jex/src/main/java/org/example/Main.java @@ -1,16 +1,13 @@ package org.example; import io.avaje.http.api.ValidationException; -import io.avaje.http.api.Validator; import io.avaje.inject.BeanScope; -import io.avaje.inject.InjectModule; import io.avaje.jex.Jex; import io.avaje.jex.Routing; import java.util.LinkedHashMap; import java.util.Map; -@InjectModule(requires = Validator.class) public class Main { public static void main(String[] args) { diff --git a/tests/test-jex/src/main/java/org/example/web/HelloDto.java b/tests/test-jex/src/main/java/org/example/web/HelloDto.java index 721795d78..7f1c00686 100644 --- a/tests/test-jex/src/main/java/org/example/web/HelloDto.java +++ b/tests/test-jex/src/main/java/org/example/web/HelloDto.java @@ -1,7 +1,7 @@ package org.example.web; -import jakarta.validation.Valid; -import jakarta.validation.constraints.NotNull; +import io.avaje.validation.constraints.NotNull; +import io.avaje.validation.constraints.Valid; @Valid public class HelloDto { diff --git a/tests/test-nima-jsonb/.project b/tests/test-nima-jsonb/.project index 14b9f0648..e2e024db0 100644 --- a/tests/test-nima-jsonb/.project +++ b/tests/test-nima-jsonb/.project @@ -1,6 +1,6 @@ - test-nima + test-nima-jsonb diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 85487c196..a2c1587e6 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -33,11 +33,6 @@ avaje-jsonb 2.3 - - io.avaje - avaje-http-hibernate-validator - 3.3 - io.helidon.webserver helidon-webserver @@ -92,6 +87,11 @@ avaje-jsonb-generator 2.3 + + io.avaje + avaje-validator-generator + 2.3 + diff --git a/tests/test-nima-jsonb/src/test/java/org/example/TestPair.java b/tests/test-nima-jsonb/src/test/java/org/example/TestPair.java index 6ab76b5d9..2260d6088 100644 --- a/tests/test-nima-jsonb/src/test/java/org/example/TestPair.java +++ b/tests/test-nima-jsonb/src/test/java/org/example/TestPair.java @@ -1,10 +1,12 @@ package org.example; -import io.avaje.http.api.Validator; +import java.util.List; +import java.util.Locale; + import io.avaje.http.api.context.ThreadLocalRequestContextResolver; import io.avaje.http.client.HttpClient; -import io.avaje.http.hibernate.validator.BeanValidator; import io.avaje.jsonb.Jsonb; +import io.avaje.validation.http.BeanValidator; import io.helidon.webserver.WebServer; import io.helidon.webserver.http.HttpRouting; @@ -38,7 +40,7 @@ void stop() { private static HttpRouting.Builder routing() { HttpRouting.Builder routing = HttpRouting.builder(); - var beanValidator = new BeanValidator(); + var beanValidator = new BeanValidator(List.of(Locale.getDefault())); Jsonb jsonb = Jsonb.builder().build(); var ec = new ErrorController(); diff --git a/tests/test-sigma/pom.xml b/tests/test-sigma/pom.xml index fd0f01ce7..9efbcce36 100644 --- a/tests/test-sigma/pom.xml +++ b/tests/test-sigma/pom.xml @@ -42,13 +42,7 @@ avaje-http-api ${project.version} - - - io.avaje - avaje-http-hibernate-validator - 3.5-RC3 - - + io.swagger.core.v3 swagger-annotations diff --git a/tests/test-sigma/src/main/java/org/example/myapp/web/GetBeanForm.java b/tests/test-sigma/src/main/java/org/example/myapp/web/GetBeanForm.java index 70818500d..b264954b5 100644 --- a/tests/test-sigma/src/main/java/org/example/myapp/web/GetBeanForm.java +++ b/tests/test-sigma/src/main/java/org/example/myapp/web/GetBeanForm.java @@ -7,10 +7,10 @@ import io.avaje.http.api.Ignore; import io.avaje.http.api.QueryParam; import io.avaje.jsonb.Json; -import jakarta.validation.Valid; -import jakarta.validation.constraints.Email; -import jakarta.validation.constraints.NotNull; -import jakarta.validation.constraints.Size; +import io.avaje.validation.constraints.Email; +import io.avaje.validation.constraints.NotNull; +import io.avaje.validation.constraints.Size; +import io.avaje.validation.constraints.Valid; @Json @Valid diff --git a/tests/test-sigma/src/main/java/org/example/myapp/web/HelloForm.java b/tests/test-sigma/src/main/java/org/example/myapp/web/HelloForm.java index 51dcfb085..1b4331867 100644 --- a/tests/test-sigma/src/main/java/org/example/myapp/web/HelloForm.java +++ b/tests/test-sigma/src/main/java/org/example/myapp/web/HelloForm.java @@ -2,14 +2,13 @@ import java.time.LocalDate; -import org.hibernate.validator.constraints.URL; - import io.avaje.jsonb.Json; -import jakarta.validation.Valid; -import jakarta.validation.constraints.Email; -import jakarta.validation.constraints.Future; -import jakarta.validation.constraints.NotNull; -import jakarta.validation.constraints.Size; +import io.avaje.validation.constraints.Email; +import io.avaje.validation.constraints.Future; +import io.avaje.validation.constraints.NotNull; +import io.avaje.validation.constraints.Size; +import io.avaje.validation.constraints.URI; +import io.avaje.validation.constraints.Valid; @Json @Valid @@ -22,10 +21,11 @@ public class HelloForm { @Email @Size(max = 100) String email; -@URL - private String url; -@Future - public LocalDate startDate; + + @URI + private String url; + @Future + public LocalDate startDate; public HelloForm(String name, String email) { this.name = name; From e3e00330560f187b555ea0f4917f4a8edb26e9bb Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Tue, 26 Nov 2024 15:03:24 -0500 Subject: [PATCH 1177/1323] Update Jex Generation (#517) * bring jex generator up to speed * copy over some tests * Update pom.xml * Update JexAdapter.java * Update pom.xml * Update pom.xml * Update pom.xml * Update WebController.java --- .../main/java/io/avaje/http/api/Options.java | 20 + .../http/generator/core/CoreWebMethod.java | 5 +- .../generator/jex/ControllerMethodWriter.java | 53 +- .../http/generator/jex/ControllerWriter.java | 11 +- .../avaje/http/generator/jex/JexAdapter.java | 63 +- pom.xml | 4 +- tests/pom.xml | 12 +- tests/test-client-generation/pom.xml | 16 +- .../main/java/org/example/server/Main.java | 8 +- .../src/main/resources/public/openapi.json | 12 +- .../src/main/resources/public/openapi.json | 12 +- tests/test-jex/pom.xml | 18 +- .../src/main/java/org/example/Main.java | 4 +- .../main/java/org/example/web/AppRoles.java | 7 +- .../java/org/example/web/TestController.java | 22 +- .../main/java/org/example/web/myapp/Bar.java | 10 + .../org/example/web/myapp/BarController.java | 28 + .../org/example/web/myapp/BarInterface.java | 25 + .../org/example/web/myapp/BaseController.java | 31 + .../main/java/org/example/web/myapp/Baz.java | 15 + .../org/example/web/myapp/BazController.java | 43 + .../org/example/web/myapp/GetBeanForm.java | 88 ++ .../java/org/example/web/myapp/Hallo.java | 13 + .../java/org/example/web/myapp/HelloDto.java | 56 + .../java/org/example/web/myapp/HelloForm.java | 84 ++ .../org/example/web/myapp/Repository.java | 13 + .../java/org/example/web/myapp/Roles.java | 23 + .../example/web/myapp/SecurityController.java | 23 + .../org/example/web/myapp/SecurityRoles.java | 26 + .../org/example/web/myapp/ServerType.java | 7 + .../org/example/web/myapp/WebController.java | 194 +++ .../java/org/example/web/myapp/other/Foo.java | 7 + .../example/web/myapp/service/BazRepo.java | 32 + .../web/myapp/service/MyDependency.java | 11 + .../example/web/myapp/service/MyService.java | 21 + .../src/main/resources/public/openapi.json | 1041 ++++++++++++++++- tests/test-nima-htmx/pom.xml | 6 + 37 files changed, 1957 insertions(+), 107 deletions(-) create mode 100644 http-api/src/main/java/io/avaje/http/api/Options.java create mode 100644 tests/test-jex/src/main/java/org/example/web/myapp/Bar.java create mode 100644 tests/test-jex/src/main/java/org/example/web/myapp/BarController.java create mode 100644 tests/test-jex/src/main/java/org/example/web/myapp/BarInterface.java create mode 100644 tests/test-jex/src/main/java/org/example/web/myapp/BaseController.java create mode 100644 tests/test-jex/src/main/java/org/example/web/myapp/Baz.java create mode 100644 tests/test-jex/src/main/java/org/example/web/myapp/BazController.java create mode 100644 tests/test-jex/src/main/java/org/example/web/myapp/GetBeanForm.java create mode 100644 tests/test-jex/src/main/java/org/example/web/myapp/Hallo.java create mode 100644 tests/test-jex/src/main/java/org/example/web/myapp/HelloDto.java create mode 100644 tests/test-jex/src/main/java/org/example/web/myapp/HelloForm.java create mode 100644 tests/test-jex/src/main/java/org/example/web/myapp/Repository.java create mode 100644 tests/test-jex/src/main/java/org/example/web/myapp/Roles.java create mode 100644 tests/test-jex/src/main/java/org/example/web/myapp/SecurityController.java create mode 100644 tests/test-jex/src/main/java/org/example/web/myapp/SecurityRoles.java create mode 100644 tests/test-jex/src/main/java/org/example/web/myapp/ServerType.java create mode 100644 tests/test-jex/src/main/java/org/example/web/myapp/WebController.java create mode 100644 tests/test-jex/src/main/java/org/example/web/myapp/other/Foo.java create mode 100644 tests/test-jex/src/main/java/org/example/web/myapp/service/BazRepo.java create mode 100644 tests/test-jex/src/main/java/org/example/web/myapp/service/MyDependency.java create mode 100644 tests/test-jex/src/main/java/org/example/web/myapp/service/MyService.java diff --git a/http-api/src/main/java/io/avaje/http/api/Options.java b/http-api/src/main/java/io/avaje/http/api/Options.java new file mode 100644 index 000000000..a60e74104 --- /dev/null +++ b/http-api/src/main/java/io/avaje/http/api/Options.java @@ -0,0 +1,20 @@ +package io.avaje.http.api; + +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +/** + * Marks a method that handles HTTP OPTIONS requests. + */ +@Target(METHOD) +@Retention(RUNTIME) +@HttpMethod("OPTIONS") +public @interface Options { + + /** Specify the path. */ + String value() default ""; + +} diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/CoreWebMethod.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/CoreWebMethod.java index ff41b6f9d..91cc737e7 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/CoreWebMethod.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/CoreWebMethod.java @@ -6,12 +6,13 @@ public enum CoreWebMethod implements WebMethod { PUT(200, 204), PATCH(200, 204), DELETE(200, 204), + OPTIONS(200, 204), ERROR(500), FILTER(0), OTHER(0, 0); - private int statusCode; - private int voidStatusCode; + private final int statusCode; + private final int voidStatusCode; CoreWebMethod(int statusCode, int voidStatusCode) { this.statusCode = statusCode; diff --git a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java index 9c45addb7..517db90a0 100644 --- a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java +++ b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java @@ -1,6 +1,10 @@ package io.avaje.http.generator.jex; +import static io.avaje.http.generator.core.ProcessingContext.isAssignable2Interface; +import static io.avaje.http.generator.core.ProcessingContext.logError; import static io.avaje.http.generator.core.ProcessingContext.platform; + +import java.io.IOException; import java.util.List; import io.avaje.http.generator.core.*; @@ -15,18 +19,35 @@ class ControllerMethodWriter { private final Append writer; private final WebMethod webMethod; private final boolean instrumentContext; + private final boolean isFilter; ControllerMethodWriter(MethodReader method, Append writer) { this.method = method; this.writer = writer; this.webMethod = method.webMethod(); this.instrumentContext = method.instrumentContext(); + this.isFilter = webMethod == CoreWebMethod.FILTER; + if (isFilter) { + validateMethod(); + } + } + + private void validateMethod() { + if (method.params().stream().map(MethodParam::shortType).noneMatch("FilterChain"::equals)) { + logError(method.element(), "Filters must contain a FilterChain parameter"); + } } void writeRouting() { final PathSegments segments = method.pathSegments(); final String fullPath = segments.fullPath(); - writer.append(" routing.%s(\"%s\", this::_%s)", webMethod.name().toLowerCase(), fullPath, method.simpleName()); + + if (isFilter) { + writer.append(" routing.filter(this::_%s)", method.simpleName()); + } else { + writer.append(" routing.%s(\"%s\", this::_%s)", webMethod.name().toLowerCase(), fullPath, method.simpleName()); + } + List roles = method.roles(); if (!roles.isEmpty()) { writer.append(".withRoles("); @@ -42,7 +63,17 @@ void writeRouting() { } void writeHandler(boolean requestScoped) { - writer.append(" private void _%s(Context ctx) {", method.simpleName()).eol(); + + if (method.isErrorMethod()) { + writer.append(" private void _%s(Context ctx, %s ex)", method.simpleName(), method.exceptionShortName()); + } else if (isFilter) { + writer.append(" private void _%s(Context ctx, FilterChain chain)", method.simpleName()); + } else { + writer.append(" private void _%s(Context ctx)", method.simpleName()); + } + + writer.append(" throws IOException {", method.simpleName()).eol(); + write(requestScoped); writer.append(" }").eol().eol(); } @@ -61,7 +92,9 @@ private void write(boolean requestScoped) { final List params = method.params(); for (MethodParam param : params) { - param.writeCtxGet(writer, segments); + if (!isExceptionOrFilterChain(param)) { + param.writeCtxGet(writer, segments); + } } if (method.includeValidate()) { for (MethodParam param : params) { @@ -85,7 +118,14 @@ private void write(boolean requestScoped) { if (i > 0) { writer.append(", "); } - params.get(i).buildParamName(writer); + final var param = params.get(i); + if (isAssignable2Interface(param.utype().mainType(), "java.lang.Exception")) { + writer.append("ex"); + } else if ("FilterChain".equals(param.shortType())) { + writer.append("chain"); + } else { + param.buildParamName(writer); + } } writer.append(")"); if (!method.isVoid()) { @@ -111,4 +151,9 @@ private void writeContextReturn() { writer.append("ctx.contentType(\"%s\").write(", produces); } } + + private static boolean isExceptionOrFilterChain(MethodParam param) { + return isAssignable2Interface(param.utype().mainType(), "java.lang.Exception") + || "FilterChain".equals(param.shortType()); + } } diff --git a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerWriter.java b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerWriter.java index 96d0bee61..f22876af6 100644 --- a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerWriter.java +++ b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerWriter.java @@ -13,13 +13,18 @@ class ControllerWriter extends BaseControllerWriter { private static final String AT_GENERATED = "@Generated(\"avaje-jex-generator\")"; private static final String API_CONTEXT = "io.avaje.jex.Context"; private static final String API_ROUTING = "io.avaje.jex.Routing"; - private static final String API_ROUTING_SERVICE = "io.avaje.jex.Routing.Service"; ControllerWriter(ControllerReader reader) throws IOException { super(reader); reader.addImportType(API_CONTEXT); reader.addImportType(API_ROUTING); - reader.addImportType(API_ROUTING_SERVICE); + reader.addImportType("java.io.IOException"); + + if (reader.methods().stream() + .map(MethodReader::webMethod) + .anyMatch(w -> CoreWebMethod.FILTER == w)) { + reader.addImportType("io.avaje.jex.FilterChain"); + } } void write() { @@ -60,7 +65,7 @@ private void writeRouting(MethodReader method) { private void writeClassStart() { writer.append(AT_GENERATED).eol(); writer.append(diAnnotation()).eol(); - writer.append("public class ").append(shortName).append("$Route implements Routing.Service {").eol().eol(); + writer.append("public class ").append(shortName).append("$Route implements Routing.HttpService {").eol().eol(); String controllerName = "controller"; String controllerType = shortName; diff --git a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/JexAdapter.java b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/JexAdapter.java index 9943c1e31..03a13fb2f 100644 --- a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/JexAdapter.java +++ b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/JexAdapter.java @@ -29,11 +29,17 @@ public boolean isBodyMethodParam() { } @Override - public String bodyAsClass(UType uType) { - if ("java.lang.String".equals(uType.full())) { + public String bodyAsClass(UType type) { + + if ("java.io.InputStream".equals(type.full())) { + return "ctx.bodyInputStream()"; + } else if ("java.lang.String".equals(type.full())) { return "ctx.body()"; + } else if ("byte[]".equals(type.full())) { + return "ctx.bodyAsBytes()"; } - return "ctx.bodyAsClass(" + uType.mainType() + ".class)"; + + return "ctx.bodyAsClass(" + type.mainType() + ".class)"; } @Override @@ -67,27 +73,62 @@ public void writeReadParameter(Append writer, ParamType paramType, String paramN writer.append("withDefault(ctx.%s(\"%s\"), \"%s\")", paramType, paramName, paramDefault); } + @Override + public void writeReadMapParameter(Append writer, ParamType paramType) { + + switch (paramType) { + case QUERYPARAM: + writer.append("ctx.queryParamMap()"); + break; + case FORM: + case FORMPARAM: + writer.append("ctx.formParamMap()"); + break; + default: + throw new UnsupportedOperationException( + "Only Query/Form Params have Map> supported in Jex"); + } + } + @Override public void writeReadCollectionParameter(Append writer, ParamType paramType, String paramName) { - if (paramType != ParamType.QUERYPARAM) { - throw new UnsupportedOperationException( - "Only MultiValue Query Params are supported in Jex"); + switch (paramType) { + case QUERYPARAM: + writer.append("ctx.queryParams(\"%s\")", paramName); + break; + case FORMPARAM: + writer.append("ctx.formParams(\"%s\")", paramName); + break; + default: + throw new UnsupportedOperationException( + "Only MultiValue Form/Query Params are supported in Jex"); } - writer.append("ctx.queryParams(\"%s\")", paramName); } @Override public void writeReadCollectionParameter( Append writer, ParamType paramType, String paramName, List paramDefault) { - if (paramType != ParamType.QUERYPARAM) { - throw new UnsupportedOperationException( - "Only MultiValue Query Params are supported in Jex"); + + switch (paramType) { + case QUERYPARAM: + writer.append( + "withDefault(ctx.queryParams(\"%s\"), java.util.List.of(\"%s\"))", + paramName, String.join(",", paramDefault)); + break; + case FORMPARAM: + writer.append( + "withDefault(ctx.formParams(\"%s\"), java.util.List.of(\"%s\"))", + paramName, String.join(",", paramDefault)); + break; + default: + throw new UnsupportedOperationException( + "Only MultiValue Form/Query Params are supported in Jex"); } - writer.append("withDefault(ctx.queryParams(\"%s\"), java.util.List.of(\"%s\"))", paramName, String.join(",", paramDefault)); } @Override public void writeAcceptLanguage(Append writer) { writer.append("ctx.header(\"%s\")", Constants.ACCEPT_LANGUAGE); } + } diff --git a/pom.xml b/pom.xml index 320cdd772..ed7e219c7 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,9 @@ true 2.2.26 2.14.2 + 3.0-SNAPSHOT 1.35 + 2024-10-28T03:18:56Z ${project.build.directory}${file.separator}module-info.shade @@ -44,7 +46,6 @@ http-inject-plugin http-generator-core http-generator-javalin - http-generator-jex http-generator-sigma http-generator-client @@ -68,6 +69,7 @@ htmx-nima htmx-nima-jstache http-generator-helidon + http-generator-jex diff --git a/tests/pom.xml b/tests/pom.xml index 8c5631b15..43b80e628 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -15,7 +15,7 @@ 5.11.3 3.26.3 2.18.1 - 2.5 + 3.0-RC1 11.0 4.1.4 6.3.0 @@ -24,9 +24,7 @@ test-javalin test-javalin-jsonb - test-jex test-client - test-client-generation test-sigma @@ -38,19 +36,21 @@ test-nima + test-jex test-nima-jsonb test-nima-htmx + test-client-generation - + io.avaje avaje-validator 2.3 - + io.avaje avaje-validator-constraints @@ -62,7 +62,7 @@ avaje-validator-generator 2.3 - + diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index 7ce89b71c..dbefef671 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -61,7 +61,7 @@ io.avaje - avaje-jex-jetty + avaje-jex ${jex.version} @@ -90,7 +90,19 @@ ${assertj.version} test - + + + + io.avaje + avaje-http-client-generator + ${project.version} + + + io.avaje + avaje-http-jex-generator + ${project.version} + + diff --git a/tests/test-client-generation/src/main/java/org/example/server/Main.java b/tests/test-client-generation/src/main/java/org/example/server/Main.java index 1479466e2..73830351c 100644 --- a/tests/test-client-generation/src/main/java/org/example/server/Main.java +++ b/tests/test-client-generation/src/main/java/org/example/server/Main.java @@ -2,9 +2,6 @@ import io.avaje.inject.BeanScope; import io.avaje.jex.Jex; -import io.avaje.jex.Routing; - -import java.util.List; public class Main { @@ -19,10 +16,7 @@ public static Jex.Server start(int port) { public static Jex.Server start(int port, BeanScope context) { - final List services = context.list(Routing.Service.class); - - final Jex jex = Jex.create(); - jex.routing().addAll(services); + final Jex jex = Jex.create().configureWith(context); return jex.port(port).start(); } } diff --git a/tests/test-javalin-jsonb/src/main/resources/public/openapi.json b/tests/test-javalin-jsonb/src/main/resources/public/openapi.json index 549828b2d..00d934e26 100644 --- a/tests/test-javalin-jsonb/src/main/resources/public/openapi.json +++ b/tests/test-javalin-jsonb/src/main/resources/public/openapi.json @@ -757,8 +757,6 @@ "name" : "name", "in" : "query", "schema" : { - "maxLength" : 150, - "minLength" : 2, "type" : "string", "nullable" : false } @@ -767,9 +765,7 @@ "name" : "email", "in" : "query", "schema" : { - "maxLength" : 100, - "type" : "string", - "format" : "email" + "type" : "string" } }, { @@ -2151,15 +2147,11 @@ "type" : "object", "properties" : { "name" : { - "maxLength" : 150, - "minLength" : 2, "type" : "string", "nullable" : false }, "email" : { - "maxLength" : 100, - "type" : "string", - "format" : "email" + "type" : "string" }, "url" : { "type" : "string" diff --git a/tests/test-javalin/src/main/resources/public/openapi.json b/tests/test-javalin/src/main/resources/public/openapi.json index 76a5ad5b4..7088ed71f 100644 --- a/tests/test-javalin/src/main/resources/public/openapi.json +++ b/tests/test-javalin/src/main/resources/public/openapi.json @@ -691,8 +691,6 @@ "name" : "name", "in" : "query", "schema" : { - "maxLength" : 150, - "minLength" : 2, "type" : "string", "nullable" : false } @@ -701,9 +699,7 @@ "name" : "email", "in" : "query", "schema" : { - "maxLength" : 100, - "type" : "string", - "format" : "email" + "type" : "string" } } ], @@ -884,15 +880,11 @@ "type" : "object", "properties" : { "name" : { - "maxLength" : 150, - "minLength" : 2, "type" : "string", "nullable" : false }, "email" : { - "maxLength" : 100, - "type" : "string", - "format" : "email" + "type" : "string" }, "url" : { "type" : "string" diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index ab8184eef..a0fc1420c 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -12,7 +12,6 @@ true org.example.myapp.Main - 2.5 2.2.26 @@ -30,12 +29,6 @@ ${jex.version} - - io.avaje - avaje-jex-jetty - ${jex.version} - - com.fasterxml.jackson.core jackson-databind @@ -59,6 +52,12 @@ swagger-annotations ${swagger.version} + + + io.avaje + avaje-jsonb + 2.3 + @@ -76,6 +75,11 @@ provided + + io.avaje + avaje-jsonb-generator + 2.3 + diff --git a/tests/test-jex/src/main/java/org/example/Main.java b/tests/test-jex/src/main/java/org/example/Main.java index a485c3905..fc951fcbe 100644 --- a/tests/test-jex/src/main/java/org/example/Main.java +++ b/tests/test-jex/src/main/java/org/example/Main.java @@ -21,9 +21,9 @@ public static Jex.Server start(int port) { public static Jex.Server start(int port, BeanScope context) { final Jex jex = Jex.create(); - jex.routing().addAll(context.list(Routing.Service.class)); + jex.routing().addAll(context.list(Routing.HttpService.class)); - jex.exception(ValidationException.class, (exception, ctx) -> { + jex.routing().error(ValidationException.class, (exception, ctx) -> { Map map = new LinkedHashMap<>(); map.put("message", exception.getMessage()); map.put("errors", exception.getErrors()); diff --git a/tests/test-jex/src/main/java/org/example/web/AppRoles.java b/tests/test-jex/src/main/java/org/example/web/AppRoles.java index ad481f73c..9d80dbeee 100644 --- a/tests/test-jex/src/main/java/org/example/web/AppRoles.java +++ b/tests/test-jex/src/main/java/org/example/web/AppRoles.java @@ -1,8 +1,9 @@ package org.example.web; - -import io.avaje.jex.Role; +import io.avaje.jex.security.Role; public enum AppRoles implements Role { - ANYONE, ADMIN, BASIC_USER + ANYONE, + ADMIN, + BASIC_USER } diff --git a/tests/test-jex/src/main/java/org/example/web/TestController.java b/tests/test-jex/src/main/java/org/example/web/TestController.java index 00f23d717..76791b0e0 100644 --- a/tests/test-jex/src/main/java/org/example/web/TestController.java +++ b/tests/test-jex/src/main/java/org/example/web/TestController.java @@ -1,13 +1,23 @@ package org.example.web; +import java.io.IOException; import java.util.Set; -import io.avaje.http.api.*; +import io.avaje.http.api.BodyString; +import io.avaje.http.api.Controller; +import io.avaje.http.api.Default; +import io.avaje.http.api.Filter; +import io.avaje.http.api.Get; +import io.avaje.http.api.InstrumentServerContext; +import io.avaje.http.api.Options; +import io.avaje.http.api.Path; +import io.avaje.http.api.Post; +import io.avaje.http.api.QueryParam; import io.avaje.jex.Context; +import io.avaje.jex.FilterChain; @Path("test/") @Controller -@InstrumentServerContext public class TestController { @Get("/paramMulti") @@ -30,8 +40,14 @@ String enumQueryImplied(String s, @QueryParam ServerType type) { return type.name(); } - @Post("/strBody") + @Options("/strBody") String strBody(@BodyString String body, Context ctx) { return body; } + + @Filter + void filter(FilterChain chain) throws IOException { + System.err.println("do nothing lmao"); + chain.proceed(); + } } diff --git a/tests/test-jex/src/main/java/org/example/web/myapp/Bar.java b/tests/test-jex/src/main/java/org/example/web/myapp/Bar.java new file mode 100644 index 000000000..facbae43a --- /dev/null +++ b/tests/test-jex/src/main/java/org/example/web/myapp/Bar.java @@ -0,0 +1,10 @@ +package org.example.web.myapp; + +import io.avaje.jsonb.Json; + +@Json +public class Bar { + + public long id; + public String name; +} diff --git a/tests/test-jex/src/main/java/org/example/web/myapp/BarController.java b/tests/test-jex/src/main/java/org/example/web/myapp/BarController.java new file mode 100644 index 000000000..868061d45 --- /dev/null +++ b/tests/test-jex/src/main/java/org/example/web/myapp/BarController.java @@ -0,0 +1,28 @@ +package org.example.web.myapp; + +import io.avaje.http.api.Controller; + +import java.util.ArrayList; +import java.util.List; + +@Controller +public class BarController implements BarInterface { + + @Override + public Bar getById(long id) { + Bar bar = new Bar(); + bar.id = id; + bar.name = "Rob" + id; + return bar; + } + + @Override + public List findByCode(String code) { + return new ArrayList<>(); + } + + @Override + public String barMessage() { + return "Hello"; + } +} diff --git a/tests/test-jex/src/main/java/org/example/web/myapp/BarInterface.java b/tests/test-jex/src/main/java/org/example/web/myapp/BarInterface.java new file mode 100644 index 000000000..34dde1b63 --- /dev/null +++ b/tests/test-jex/src/main/java/org/example/web/myapp/BarInterface.java @@ -0,0 +1,25 @@ +package org.example.web.myapp; + +import io.avaje.http.api.Get; +import io.avaje.http.api.MediaType; +import io.avaje.http.api.Path; +import io.avaje.http.api.Produces; +import io.swagger.v3.oas.annotations.links.Link; +import io.swagger.v3.oas.annotations.responses.ApiResponse; + +import java.util.List; + +@Path("/bars") +public interface BarInterface { + + @Get(":id") + @ApiResponse(links = @Link(name="find", ref ="/find/:code", description="find by code")) + Bar getById(long id); + + @Get("/find/:code") + List findByCode(String code); + + @Produces(MediaType.TEXT_PLAIN) + @Get + String barMessage(); +} diff --git a/tests/test-jex/src/main/java/org/example/web/myapp/BaseController.java b/tests/test-jex/src/main/java/org/example/web/myapp/BaseController.java new file mode 100644 index 000000000..4e9f17910 --- /dev/null +++ b/tests/test-jex/src/main/java/org/example/web/myapp/BaseController.java @@ -0,0 +1,31 @@ +package org.example.web.myapp; + +import io.avaje.http.api.Get; +import io.avaje.http.api.Post; + +import java.util.List; + +abstract class BaseController { + + protected final Repository repository; + + BaseController(Repository repository) { + this.repository = repository; + } + + @Get(":id") + T getById(I id) { + return repository.findById(id); + } + + @Get + List findAll() { + return repository.findAll(); + } + + @Post + I save(T bean) { + return repository.save(bean); + } + +} diff --git a/tests/test-jex/src/main/java/org/example/web/myapp/Baz.java b/tests/test-jex/src/main/java/org/example/web/myapp/Baz.java new file mode 100644 index 000000000..cc10d242d --- /dev/null +++ b/tests/test-jex/src/main/java/org/example/web/myapp/Baz.java @@ -0,0 +1,15 @@ +package org.example.web.myapp; + +import java.time.LocalDate; + +import io.avaje.jsonb.Json; +@Json +public class Baz { + + public Long id; + + public String name; + + public LocalDate startDate; + +} diff --git a/tests/test-jex/src/main/java/org/example/web/myapp/BazController.java b/tests/test-jex/src/main/java/org/example/web/myapp/BazController.java new file mode 100644 index 000000000..8d0a13f27 --- /dev/null +++ b/tests/test-jex/src/main/java/org/example/web/myapp/BazController.java @@ -0,0 +1,43 @@ +package org.example.web.myapp; + +import io.avaje.http.api.Controller; +import io.avaje.http.api.Get; +import io.avaje.http.api.Path; + +import java.util.Arrays; +import java.util.List; + +@Controller +@Path("/baz") +class BazController extends BaseController { + + BazController(Repository repository) { + super(repository); + } + + /** + * Find the baz by name. + *

    + * This is some more comments about this method. + * + * @return The list of baz + */ + @Get("findbyname/{name}") + List searchByName(String name) { + + Baz b1 = new Baz(); + b1.id = 1L; + b1.name = "baz1-" + name; + + Baz b2 = new Baz(); + b2.id = 2L; + b2.name = "baz2"; + + return Arrays.asList(b1, b2); + } + + @Get("checkparams/{id}") + String checkParams(int id, String p1, Double p2, Integer p3, Float p4, String body) { + return "dummy-response"; + } +} diff --git a/tests/test-jex/src/main/java/org/example/web/myapp/GetBeanForm.java b/tests/test-jex/src/main/java/org/example/web/myapp/GetBeanForm.java new file mode 100644 index 000000000..1eb3bb7cd --- /dev/null +++ b/tests/test-jex/src/main/java/org/example/web/myapp/GetBeanForm.java @@ -0,0 +1,88 @@ +package org.example.web.myapp; + +import java.util.List; +import java.util.Set; + +import io.avaje.http.api.Header; +import io.avaje.http.api.Ignore; +import io.avaje.http.api.QueryParam; +import io.avaje.jsonb.Json; +import io.avaje.validation.constraints.Email; +import io.avaje.validation.constraints.NotNull; +import io.avaje.validation.constraints.Size; +import io.avaje.validation.constraints.Valid; + +@Json +@Valid +public class GetBeanForm { + + @NotNull + @Size(min = 2, max = 150) + private String name; + + @Email + @Size(max = 100) + private String email; + + private List addresses; + + @Header private String head; + + @QueryParam private Set type; + + @Json.Ignore @Ignore private String ignored; + + public String getIgnored() { + return ignored; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public GetBeanForm(String name, String email) { + this.name = name; + this.email = email; + } + + @Override + public String toString() { + return "HelloForm{" + "name='" + name + '\'' + ", email='" + email + '\'' + '}'; + } + + public List getAddresses() { + return addresses; + } + + public void setAddresses(List addresses) { + this.addresses = addresses; + } + + public String getHead() { + return head; + } + + public void setHead(String head) { + this.head = head; + } + + public Set getType() { + return type; + } + + public void setType(Set type) { + this.type = type; + } +} diff --git a/tests/test-jex/src/main/java/org/example/web/myapp/Hallo.java b/tests/test-jex/src/main/java/org/example/web/myapp/Hallo.java new file mode 100644 index 000000000..534520f68 --- /dev/null +++ b/tests/test-jex/src/main/java/org/example/web/myapp/Hallo.java @@ -0,0 +1,13 @@ +package org.example.web.myapp; + +import io.avaje.http.api.Controller; +import io.avaje.http.api.Path; + +@Controller +@Path("hallo") +public class Hallo { + + public String getStuff() { + return "Hallo"; + } +} diff --git a/tests/test-jex/src/main/java/org/example/web/myapp/HelloDto.java b/tests/test-jex/src/main/java/org/example/web/myapp/HelloDto.java new file mode 100644 index 000000000..3474c6c63 --- /dev/null +++ b/tests/test-jex/src/main/java/org/example/web/myapp/HelloDto.java @@ -0,0 +1,56 @@ +package org.example.web.myapp; + +import java.time.Instant; +import java.util.UUID; + +import io.avaje.jsonb.Json; +@Json +public class HelloDto { + + public int id; + /** + * This is a comment. + */ + public String name; + /** + * This is a comment + */ + public String otherParam; + private UUID gid; + + private Instant whenAction; + + public HelloDto(int id, String name, String otherParam) { + this.id = id; + this.name = name; + this.otherParam = otherParam; + } + + /** + * Jackson constructor. + */ + public HelloDto() { + } + + public UUID getGid() { + return gid; + } + + public void setGid(UUID gid) { + this.gid = gid; + } + + public Instant getWhenAction() { + return whenAction; + } + + public void setWhenAction(Instant whenAction) { + this.whenAction = whenAction; + } + + @Override + public String toString() { + return "id:" + id + " name:" + name + " other:" + otherParam; + } + +} diff --git a/tests/test-jex/src/main/java/org/example/web/myapp/HelloForm.java b/tests/test-jex/src/main/java/org/example/web/myapp/HelloForm.java new file mode 100644 index 000000000..dcd732052 --- /dev/null +++ b/tests/test-jex/src/main/java/org/example/web/myapp/HelloForm.java @@ -0,0 +1,84 @@ +package org.example.web.myapp; + +import java.time.LocalDate; + +import io.avaje.http.api.Valid; +import io.avaje.jsonb.Json; +import io.avaje.validation.constraints.Email; +import io.avaje.validation.constraints.Future; +import io.avaje.validation.constraints.NotNull; +import io.avaje.validation.constraints.Size; +import io.avaje.validation.constraints.URI; + +@Json +@Valid +public class HelloForm { + + @NotNull + @Size(min = 2, max = 150) + String name; + + @Email + @Size(max = 100) + String email; + + @URI + private String url; + + @Future + public LocalDate startDate; + + public HelloForm(String name, String email) { + this.name = name; + this.email = email; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public LocalDate getStartDate() { + return startDate; + } + + public void setStartDate(LocalDate startDate) { + this.startDate = startDate; + } + + @Override + public String toString() { + return "HelloForm{" + + "name='" + + name + + '\'' + + ", email='" + + email + + '\'' + + ", url='" + + url + + '\'' + + ", startDate=" + + startDate + + '}'; + } +} diff --git a/tests/test-jex/src/main/java/org/example/web/myapp/Repository.java b/tests/test-jex/src/main/java/org/example/web/myapp/Repository.java new file mode 100644 index 000000000..6dd0d1a74 --- /dev/null +++ b/tests/test-jex/src/main/java/org/example/web/myapp/Repository.java @@ -0,0 +1,13 @@ +package org.example.web.myapp; + +import java.util.List; + +public interface Repository { + + T findById(I id); + + List findAll(); + + I save(T bean); +} + diff --git a/tests/test-jex/src/main/java/org/example/web/myapp/Roles.java b/tests/test-jex/src/main/java/org/example/web/myapp/Roles.java new file mode 100644 index 000000000..b3bd94e98 --- /dev/null +++ b/tests/test-jex/src/main/java/org/example/web/myapp/Roles.java @@ -0,0 +1,23 @@ +package org.example.web.myapp; + +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import org.example.web.AppRoles; + +/** + * Specify permitted roles. + */ +@Target(value={METHOD, TYPE}) +@Retention(value=RUNTIME) +public @interface Roles { + + /** + * Specify the permitted roles. + */ + AppRoles[] value() default {}; +} diff --git a/tests/test-jex/src/main/java/org/example/web/myapp/SecurityController.java b/tests/test-jex/src/main/java/org/example/web/myapp/SecurityController.java new file mode 100644 index 000000000..dde8d6de1 --- /dev/null +++ b/tests/test-jex/src/main/java/org/example/web/myapp/SecurityController.java @@ -0,0 +1,23 @@ +package org.example.web.myapp; + +import io.avaje.http.api.Controller; +import io.avaje.http.api.Get; +import io.avaje.http.api.Path; +import io.swagger.v3.oas.annotations.security.SecurityRequirement; + +@Controller +@Path("/security") +class SecurityController { + + @Get("/first") + @SecurityRequirement(name = "JWT") + String first() { + return "simple"; + } + + @Get("/second") + @SecurityRoles + String second() { + return "simple"; + } +} diff --git a/tests/test-jex/src/main/java/org/example/web/myapp/SecurityRoles.java b/tests/test-jex/src/main/java/org/example/web/myapp/SecurityRoles.java new file mode 100644 index 000000000..9a67a8b39 --- /dev/null +++ b/tests/test-jex/src/main/java/org/example/web/myapp/SecurityRoles.java @@ -0,0 +1,26 @@ +package org.example.web.myapp; + +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import org.example.web.AppRoles; + +import io.swagger.v3.oas.annotations.security.SecurityRequirement; + +/** + * Specify permitted roles. + */ +@SecurityRequirement(name = "JWT") +@Target(value={METHOD, TYPE}) +@Retention(value=RUNTIME) +public @interface SecurityRoles { + + /** + * Specify the permitted roles. + */ + AppRoles[] value() default {}; +} diff --git a/tests/test-jex/src/main/java/org/example/web/myapp/ServerType.java b/tests/test-jex/src/main/java/org/example/web/myapp/ServerType.java new file mode 100644 index 000000000..8b621d0e8 --- /dev/null +++ b/tests/test-jex/src/main/java/org/example/web/myapp/ServerType.java @@ -0,0 +1,7 @@ +package org.example.web.myapp; + +public enum ServerType { + PROXY, + HIDE_N_SEEK, + FFA +} diff --git a/tests/test-jex/src/main/java/org/example/web/myapp/WebController.java b/tests/test-jex/src/main/java/org/example/web/myapp/WebController.java new file mode 100644 index 000000000..9aae94a0b --- /dev/null +++ b/tests/test-jex/src/main/java/org/example/web/myapp/WebController.java @@ -0,0 +1,194 @@ +package org.example.web.myapp; + +import static java.util.Objects.requireNonNull; + +import java.time.LocalDate; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.Executors; + +import org.example.web.AppRoles; +import org.example.web.myapp.other.Foo; +import org.example.web.myapp.service.MyService; + +import io.avaje.http.api.BeanParam; +import io.avaje.http.api.Controller; +import io.avaje.http.api.Default; +import io.avaje.http.api.Delete; +import io.avaje.http.api.Form; +import io.avaje.http.api.Get; +import io.avaje.http.api.MediaType; +import io.avaje.http.api.Path; +import io.avaje.http.api.Post; +import io.avaje.http.api.Produces; +import io.avaje.http.api.QueryParam; +import io.avaje.http.api.Valid; +import io.avaje.jex.Context; +import io.swagger.v3.oas.annotations.Hidden; +import jakarta.inject.Inject; + +/** + * Hello resource manager. + *

    + * Simple API for Hello resources. + */ +//@Hidden +@Valid +@Controller +@Path("/hello") +class WebController { + + private final MyService myService; + + @Inject + WebController(MyService myService) { + this.myService = myService; + } + + @Produces(MediaType.TEXT_PLAIN) + @Get("message") + String getPlainMessage() { + return "hello world"; + } + + /** + * Return the Hello DTO. + * + * @param id The hello Id. + * @param date The name of the hello + * @param otherParam Optional other parameter + * @return The Hello DTO given the id and name. + * @deprecated Please migrate away + */ + @Deprecated + @Roles({AppRoles.ADMIN, AppRoles.BASIC_USER}) + @Get("/:id/:date") + HelloDto hello(int id, LocalDate date, String otherParam) { + return new HelloDto(id, date.toString(), otherParam); + } + + /** + * Find Hellos by name. + * + * @param name The name to search for + * @param myParam My option parameter + * @return The Hellos that we found. + */ + @Roles(AppRoles.ADMIN) + @Get("/findbyname/{name}") + List findByName(String name, @QueryParam("my-param") @Default("one") String myParam) { + return new ArrayList<>(); + } + + /** + * Simple example post with JSON body response. + */ + @Produces(MediaType.APPLICATION_JSON_PATCH_JSON) + @Post + HelloDto post(HelloDto dto) { + dto.name = "posted"; + return dto; + } + + /** + * Save the hello using json body. + * + * @param foo The hello doo id + * @param dto The hello body as json + */ +// @Roles({ADMIN}) + @Post("/savebean/:foo") + void saveBean(String foo, HelloDto dto, Context context) { + // save hello data ... + System.out.println("save " + foo + " dto:" + dto); + requireNonNull(foo); + requireNonNull(dto); + requireNonNull(context); + } + + /** + * Create the new Hello using a form. + */ + @Post("saveform") + @Form + void saveForm(HelloForm helloForm) { + System.out.println("saving " + helloForm); + } + + @Form @Post("mySave") + void saveForm324(@Default("junk") String name, String email, String url) { + System.out.println("name " + name + " email:" + email + " url:" + url); + } + + + @Post("saveform2") + @Form + void saveForm2(String name, String email, String url) { + System.out.println("name " + name + " email:" + email + " url:" + url); + } + + @Post("saveform3") + @Form + HelloDto saveForm3(HelloForm helloForm) { + return new HelloDto(52, helloForm.name, helloForm.email); + } + + @Produces("text/plain") + @Get("withValidBean") + String getGetBeanForm(@BeanParam GetBeanForm bean) { + return "ok name:" + bean.getName(); + } + + @Hidden + @Get + List getAll() { + return myService.findAll(); + } + + @Get("/async") + CompletableFuture> getAllAsync() { + return CompletableFuture.supplyAsync(() -> { + // Simulate a delay as if an actual IO operation is being executed. + // This also helps ensure that we aren't just getting lucky with timings. + try { + Thread.sleep(10L); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + + return myService.findAll(); + }, Executors.newSingleThreadExecutor()); // Example of how to use a custom executor. + } + + // @Hidden + @Delete(":id") + void deleteById(int id) { + System.out.println("deleting " + id); + } + + @Produces("text/plain") + @Get("/withMatrix/:year;author;country/:other") + String getWithMatrixParam(int year, String author, String country, String other, String extra) { + return "yr:" + year + " au:" + author + " co:" + country + " other:" + other + " extra:" + extra; + } + + @Produces("text/plain") + @Get("slash/{name}//other/") + String slashAccepting(String name, String nam0, String nam1) { + return "got name:" + name + " splat0:" + nam0 + " splat1:" + nam1; + } + + @Produces(value = "text/plain") + @Get("controlStatusCode") + String controlStatusCode(Context ctx) { + ctx.status(201); + return "controlStatusCode"; + } + + @Produces(value = "text/plain") + @Get("takesNestedEnum") + String takesNestedEnum(Foo.NestedEnum myEnum) { + return "takesNestedEnum-" + myEnum; + } +} diff --git a/tests/test-jex/src/main/java/org/example/web/myapp/other/Foo.java b/tests/test-jex/src/main/java/org/example/web/myapp/other/Foo.java new file mode 100644 index 000000000..016ef5097 --- /dev/null +++ b/tests/test-jex/src/main/java/org/example/web/myapp/other/Foo.java @@ -0,0 +1,7 @@ +package org.example.web.myapp.other; + +public class Foo { + public enum NestedEnum { + A, B, C + } +} diff --git a/tests/test-jex/src/main/java/org/example/web/myapp/service/BazRepo.java b/tests/test-jex/src/main/java/org/example/web/myapp/service/BazRepo.java new file mode 100644 index 000000000..d92410456 --- /dev/null +++ b/tests/test-jex/src/main/java/org/example/web/myapp/service/BazRepo.java @@ -0,0 +1,32 @@ +package org.example.web.myapp.service; + +import java.util.ArrayList; +import java.util.List; + +import org.example.web.myapp.Baz; +import org.example.web.myapp.Repository; + +import jakarta.inject.Singleton; + +@Singleton +public class BazRepo implements Repository { + + @Override + public Baz findById(Long id) { + Baz baz = new Baz(); + baz.id = id; + baz.name = "Baz" + id; + //baz.startDate = LocalDate.of(2020, 1, 1); + return baz; + } + + @Override + public List findAll() { + return new ArrayList<>(); + } + + @Override + public Long save(Baz bean) { + return 42L; + } +} diff --git a/tests/test-jex/src/main/java/org/example/web/myapp/service/MyDependency.java b/tests/test-jex/src/main/java/org/example/web/myapp/service/MyDependency.java new file mode 100644 index 000000000..7cdd9d3d8 --- /dev/null +++ b/tests/test-jex/src/main/java/org/example/web/myapp/service/MyDependency.java @@ -0,0 +1,11 @@ +package org.example.web.myapp.service; + +import jakarta.inject.Singleton; + +@Singleton +public class MyDependency { + + public String hello() { + return "my dependency"; + } +} diff --git a/tests/test-jex/src/main/java/org/example/web/myapp/service/MyService.java b/tests/test-jex/src/main/java/org/example/web/myapp/service/MyService.java new file mode 100644 index 000000000..3021fb4cc --- /dev/null +++ b/tests/test-jex/src/main/java/org/example/web/myapp/service/MyService.java @@ -0,0 +1,21 @@ +package org.example.web.myapp.service; + +import java.util.ArrayList; +import java.util.List; + +import org.example.web.myapp.HelloDto; + +import jakarta.inject.Singleton; + +@Singleton +public class MyService { + + public List findAll() { + + List list = new ArrayList<>(); + list.add(new HelloDto(12, "Jim", "asd")); + list.add(new HelloDto(13, "Spock", "456456")); + + return list; + } +} diff --git a/tests/test-jex/src/main/resources/public/openapi.json b/tests/test-jex/src/main/resources/public/openapi.json index b761bf8db..88ce42132 100644 --- a/tests/test-jex/src/main/resources/public/openapi.json +++ b/tests/test-jex/src/main/resources/public/openapi.json @@ -54,6 +54,283 @@ } } }, + "/bars" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/bars/find/{code}" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "parameters" : [ + { + "name" : "code", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "array", + "items" : { + "$ref" : "#/components/schemas/Bar" + } + } + } + } + } + } + } + }, + "/bars/{id}" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "parameters" : [ + { + "name" : "id", + "in" : "path", + "required" : true, + "schema" : { + "type" : "integer", + "format" : "int64", + "nullable" : false + } + } + ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Bar" + } + } + } + } + } + } + }, + "/baz" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "array", + "items" : { + "$ref" : "#/components/schemas/Baz" + } + } + } + } + } + } + }, + "post" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Baz" + } + } + }, + "required" : true + }, + "responses" : { + "201" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "integer", + "format" : "int64" + } + } + } + } + } + } + }, + "/baz/checkparams/{id}" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "parameters" : [ + { + "name" : "id", + "in" : "path", + "required" : true, + "schema" : { + "type" : "integer", + "format" : "int32", + "nullable" : false + } + }, + { + "name" : "p1", + "in" : "query", + "schema" : { + "type" : "string" + } + }, + { + "name" : "p2", + "in" : "query", + "schema" : { + "type" : "number" + } + }, + { + "name" : "p3", + "in" : "query", + "schema" : { + "type" : "integer", + "format" : "int32" + } + }, + { + "name" : "p4", + "in" : "query", + "schema" : { + "type" : "number" + } + }, + { + "name" : "body", + "in" : "query", + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/baz/findbyname/{name}" : { + "get" : { + "tags" : [ + + ], + "summary" : "Find the baz by name", + "description" : "This is some more comments about this method.", + "parameters" : [ + { + "name" : "name", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "description" : "The list of baz", + "content" : { + "application/json" : { + "schema" : { + "type" : "array", + "items" : { + "$ref" : "#/components/schemas/Baz" + } + } + } + } + } + } + } + }, + "/baz/{id}" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "parameters" : [ + { + "name" : "id", + "in" : "path", + "required" : true, + "schema" : { + "type" : "integer", + "format" : "int64" + } + } + ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Baz" + } + } + } + } + } + } + }, "/bigInt/{val}" : { "get" : { "tags" : [ @@ -63,11 +340,527 @@ "description" : "", "parameters" : [ { - "name" : "val", - "in" : "path", - "required" : true, + "name" : "val", + "in" : "path", + "required" : true, + "schema" : { + "type" : "number" + } + } + ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/hello" : { + "post" : { + "tags" : [ + + ], + "summary" : "Simple example post with JSON body response", + "description" : "", + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/HelloDto" + } + } + }, + "required" : true + }, + "responses" : { + "201" : { + "description" : "", + "content" : { + "application/json-patch+json" : { + "schema" : { + "$ref" : "#/components/schemas/HelloDto" + } + } + } + } + } + } + }, + "/hello/async" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "array", + "items" : { + "$ref" : "#/components/schemas/HelloDto" + } + } + } + } + } + } + } + }, + "/hello/controlStatusCode" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/hello/findbyname/{name}" : { + "get" : { + "tags" : [ + + ], + "summary" : "Find Hellos by name", + "description" : "", + "parameters" : [ + { + "name" : "name", + "in" : "path", + "description" : "The name to search for", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "name" : "myParam", + "in" : "query", + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "description" : "The Hellos that we found.", + "content" : { + "application/json" : { + "schema" : { + "type" : "array", + "items" : { + "$ref" : "#/components/schemas/HelloDto" + } + } + } + } + } + } + } + }, + "/hello/message" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/hello/mySave" : { + "post" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "requestBody" : { + "content" : { + "application/x-www-form-urlencoded" : { + "schema" : { + "type" : "object", + "properties" : { + "name" : { + "type" : "string" + }, + "email" : { + "type" : "string" + }, + "url" : { + "type" : "string" + } + } + } + } + }, + "required" : true + }, + "responses" : { + "201" : { + "description" : "No content" + } + } + } + }, + "/hello/savebean/{foo}" : { + "post" : { + "tags" : [ + + ], + "summary" : "Save the hello using json body", + "description" : "", + "parameters" : [ + { + "name" : "foo", + "in" : "path", + "description" : "The hello doo id", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "requestBody" : { + "description" : "The hello body as json", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/HelloDto" + } + } + }, + "required" : true + }, + "responses" : { + "201" : { + "description" : "No content" + } + } + } + }, + "/hello/saveform" : { + "post" : { + "tags" : [ + + ], + "summary" : "Create the new Hello using a form", + "description" : "", + "requestBody" : { + "content" : { + "application/x-www-form-urlencoded" : { + "schema" : { + "$ref" : "#/components/schemas/HelloForm" + } + } + }, + "required" : true + }, + "responses" : { + "201" : { + "description" : "No content" + } + } + } + }, + "/hello/saveform2" : { + "post" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "requestBody" : { + "content" : { + "application/x-www-form-urlencoded" : { + "schema" : { + "type" : "object", + "properties" : { + "name" : { + "type" : "string" + }, + "email" : { + "type" : "string" + }, + "url" : { + "type" : "string" + } + } + } + } + }, + "required" : true + }, + "responses" : { + "201" : { + "description" : "No content" + } + } + } + }, + "/hello/saveform3" : { + "post" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "requestBody" : { + "content" : { + "application/x-www-form-urlencoded" : { + "schema" : { + "$ref" : "#/components/schemas/HelloForm" + } + } + }, + "required" : true + }, + "responses" : { + "201" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/HelloDto" + } + } + } + } + } + } + }, + "/hello/slash/{name}//other/" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "parameters" : [ + { + "name" : "name", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "name" : "nam0", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "name" : "nam1", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/hello/takesNestedEnum" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "parameters" : [ + { + "name" : "myEnum", + "in" : "query", + "schema" : { + "type" : "string", + "enum" : [ + "A", + "B", + "C" + ] + } + } + ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/hello/withMatrix/{year_segment}/{other}" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "parameters" : [ + { + "name" : "year", + "in" : "path", + "required" : true, + "schema" : { + "type" : "integer", + "format" : "int32", + "nullable" : false + } + }, + { + "name" : "author", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "name" : "country", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "name" : "other", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "name" : "extra", + "in" : "query", + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/hello/withValidBean" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "parameters" : [ + { + "name" : "name", + "in" : "query", "schema" : { - "type" : "number" + "type" : "string", + "nullable" : false + } + }, + { + "name" : "email", + "in" : "query", + "schema" : { + "type" : "string" + } + }, + { + "name" : "addresses", + "in" : "query", + "schema" : { + "type" : "array", + "items" : { + "type" : "string" + } + } + }, + { + "name" : "head", + "in" : "header", + "schema" : { + "type" : "string" + } + }, + { + "name" : "type", + "in" : "query", + "schema" : { + "type" : "array", + "items" : { + "type" : "string", + "enum" : [ + "PROXY", + "HIDE_N_SEEK", + "FFA" + ] + } } } ], @@ -75,7 +868,7 @@ "200" : { "description" : "", "content" : { - "application/json" : { + "text/plain" : { "schema" : { "type" : "string" } @@ -85,6 +878,85 @@ } } }, + "/hello/{id}" : { + "delete" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "parameters" : [ + { + "name" : "id", + "in" : "path", + "required" : true, + "schema" : { + "type" : "integer", + "format" : "int32", + "nullable" : false + } + } + ], + "responses" : { + "204" : { + "description" : "No content" + } + } + } + }, + "/hello/{id}/{date}" : { + "get" : { + "tags" : [ + + ], + "summary" : "Return the Hello DTO", + "description" : "", + "parameters" : [ + { + "name" : "id", + "in" : "path", + "description" : "The hello Id.", + "required" : true, + "schema" : { + "type" : "integer", + "format" : "int32", + "nullable" : false + } + }, + { + "name" : "date", + "in" : "path", + "description" : "The name of the hello", + "required" : true, + "schema" : { + "type" : "string", + "format" : "date" + } + }, + { + "name" : "otherParam", + "in" : "query", + "description" : "Optional other parameter", + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "description" : "Return the Hello DTO.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/HelloDto" + } + } + } + } + }, + "deprecated" : true + } + }, "/other/{name}" : { "get" : { "tags" : [ @@ -137,6 +1009,83 @@ } } }, + "/req-scoped" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/security/first" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "string" + } + } + } + } + }, + "security" : [ + { + "JWT" : [ + + ] + } + ] + } + }, + "/security/second" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "string" + } + } + } + } + }, + "security" : [ + { + "JWT" : [ + + ] + } + ] + } + }, "/splat/{name}//other/" : { "get" : { "tags" : [ @@ -363,37 +1312,6 @@ } } }, - "/test/strBody" : { - "post" : { - "tags" : [ - - ], - "summary" : "", - "description" : "", - "requestBody" : { - "content" : { - "application/text" : { - "schema" : { - "type" : "string" - } - } - }, - "required" : true - }, - "responses" : { - "201" : { - "description" : "", - "content" : { - "application/json" : { - "schema" : { - "type" : "string" - } - } - } - } - } - } - }, "/withDefault/{name}" : { "get" : { "tags" : [ @@ -435,6 +1353,35 @@ }, "components" : { "schemas" : { + "Bar" : { + "type" : "object", + "properties" : { + "id" : { + "type" : "integer", + "format" : "int64", + "nullable" : false + }, + "name" : { + "type" : "string" + } + } + }, + "Baz" : { + "type" : "object", + "properties" : { + "id" : { + "type" : "integer", + "format" : "int64" + }, + "name" : { + "type" : "string" + }, + "startDate" : { + "type" : "string", + "format" : "date" + } + } + }, "HelloDto" : { "required" : [ "name" @@ -459,6 +1406,28 @@ ] } } + }, + "HelloForm" : { + "required" : [ + "name" + ], + "type" : "object", + "properties" : { + "name" : { + "type" : "string", + "nullable" : false + }, + "email" : { + "type" : "string" + }, + "url" : { + "type" : "string" + }, + "startDate" : { + "type" : "string", + "format" : "date" + } + } } } } diff --git a/tests/test-nima-htmx/pom.xml b/tests/test-nima-htmx/pom.xml index 7f3aaee66..3e949f364 100644 --- a/tests/test-nima-htmx/pom.xml +++ b/tests/test-nima-htmx/pom.xml @@ -49,6 +49,12 @@ avaje-nima 1.0 + + + io.avaje + avaje-http-helidon-generator + ${project.version} + From e5367d3945229d2365fa235977c47acd52576874 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Wed, 27 Nov 2024 09:12:50 +1300 Subject: [PATCH 1178/1323] Version 2.9-RC1 --- htmx-api/pom.xml | 2 +- htmx-nima-jstache/pom.xml | 2 +- htmx-nima/pom.xml | 4 ++-- http-api-javalin/pom.xml | 2 +- http-api/pom.xml | 2 +- http-client-gson-adapter/pom.xml | 4 ++-- http-client-moshi-adapter/pom.xml | 4 ++-- http-client/pom.xml | 2 +- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 2 +- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-generator-sigma/pom.xml | 2 +- http-inject-plugin/pom.xml | 2 +- pom.xml | 4 ++-- tests/pom.xml | 2 +- tests/test-client-generation/pom.xml | 2 +- tests/test-client/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- .../src/main/resources/public/openapi.json | 21 ------------------- tests/test-nima-htmx/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- tests/test-sigma/pom.xml | 2 +- 27 files changed, 30 insertions(+), 51 deletions(-) diff --git a/htmx-api/pom.xml b/htmx-api/pom.xml index e932c70eb..b2d3cedcd 100644 --- a/htmx-api/pom.xml +++ b/htmx-api/pom.xml @@ -6,7 +6,7 @@ io.avaje avaje-http-parent - 2.9-SNAPSHOT + 2.9-RC1 avaje-htmx-api diff --git a/htmx-nima-jstache/pom.xml b/htmx-nima-jstache/pom.xml index db268a8b8..c498b8667 100644 --- a/htmx-nima-jstache/pom.xml +++ b/htmx-nima-jstache/pom.xml @@ -6,7 +6,7 @@ io.avaje avaje-http-parent - 2.9-SNAPSHOT + 2.9-RC1 avaje-htmx-nima-jstache diff --git a/htmx-nima/pom.xml b/htmx-nima/pom.xml index 397dd1316..c59af28e7 100644 --- a/htmx-nima/pom.xml +++ b/htmx-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje avaje-http-parent - 2.9-SNAPSHOT + 2.9-RC1 avaje-htmx-nima @@ -21,7 +21,7 @@ io.avaje avaje-htmx-api - 2.9-SNAPSHOT + 2.9-RC1 io.helidon.webserver diff --git a/http-api-javalin/pom.xml b/http-api-javalin/pom.xml index a0310fba5..be83d8b57 100644 --- a/http-api-javalin/pom.xml +++ b/http-api-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.9-SNAPSHOT + 2.9-RC1 .. diff --git a/http-api/pom.xml b/http-api/pom.xml index a3aa1476e..9ce46ce6e 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.9-SNAPSHOT + 2.9-RC1 .. diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index c672484af..3098b2de8 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.9-SNAPSHOT + 2.9-RC1 avaje-http-client-gson @@ -20,7 +20,7 @@ io.avaje avaje-http-client - 2.9-SNAPSHOT + 2.9-RC1 provided diff --git a/http-client-moshi-adapter/pom.xml b/http-client-moshi-adapter/pom.xml index 44ae0bf64..4cfefc70d 100644 --- a/http-client-moshi-adapter/pom.xml +++ b/http-client-moshi-adapter/pom.xml @@ -3,7 +3,7 @@ io.avaje avaje-http-parent - 2.9-SNAPSHOT + 2.9-RC1 avaje-http-client-moshi @@ -19,7 +19,7 @@ io.avaje avaje-http-client - 2.9-SNAPSHOT + 2.9-RC1 provided diff --git a/http-client/pom.xml b/http-client/pom.xml index eec42decd..a1230c877 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.9-SNAPSHOT + 2.9-RC1 avaje-http-client diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index 5f60f7f29..b84eef915 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.9-SNAPSHOT + 2.9-RC1 avaje-http-client-generator diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 6fea1e154..5e5bdba5b 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.9-SNAPSHOT + 2.9-RC1 avaje-http-generator-core diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index fa0717bf5..b1af20fdc 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.9-SNAPSHOT + 2.9-RC1 avaje-http-helidon-generator diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index aa91a16fb..2c4a8e988 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.9-SNAPSHOT + 2.9-RC1 avaje-http-javalin-generator diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index b48989ce7..6dee54601 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.9-SNAPSHOT + 2.9-RC1 avaje-http-jex-generator diff --git a/http-generator-sigma/pom.xml b/http-generator-sigma/pom.xml index d73f8f708..6dc34cb16 100644 --- a/http-generator-sigma/pom.xml +++ b/http-generator-sigma/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.9-SNAPSHOT + 2.9-RC1 avaje-http-sigma-generator diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index 284aea3ea..3dcc59e12 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.9-SNAPSHOT + 2.9-RC1 .. diff --git a/pom.xml b/pom.xml index ed7e219c7..546f67747 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-parent - 2.9-SNAPSHOT + 2.9-RC1 pom @@ -23,7 +23,7 @@ 2.14.2 3.0-SNAPSHOT 1.35 - 2024-10-28T03:18:56Z + 2024-11-26T20:06:26Z ${project.build.directory}${file.separator}module-info.shade diff --git a/tests/pom.xml b/tests/pom.xml index 43b80e628..39c94d55e 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.9-SNAPSHOT + 2.9-RC1 tests diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index dbefef671..b213b0fef 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.9-SNAPSHOT + 2.9-RC1 test-client-generation diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index 56ee06c4c..21c2521c6 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.9-SNAPSHOT + 2.9-RC1 test-client diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index a51f92fd3..1e840dc91 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 2.9-SNAPSHOT + 2.9-RC1 test-javalin-jsonb diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index cbec16d39..4a15cda9f 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.9-SNAPSHOT + 2.9-RC1 test-javalin diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index a0fc1420c..7f3e59b17 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.9-SNAPSHOT + 2.9-RC1 test-jex diff --git a/tests/test-jex/src/main/resources/public/openapi.json b/tests/test-jex/src/main/resources/public/openapi.json index 88ce42132..a6f5ac6b7 100644 --- a/tests/test-jex/src/main/resources/public/openapi.json +++ b/tests/test-jex/src/main/resources/public/openapi.json @@ -1009,27 +1009,6 @@ } } }, - "/req-scoped" : { - "get" : { - "tags" : [ - - ], - "summary" : "", - "description" : "", - "responses" : { - "200" : { - "description" : "", - "content" : { - "text/plain" : { - "schema" : { - "type" : "string" - } - } - } - } - } - } - }, "/security/first" : { "get" : { "tags" : [ diff --git a/tests/test-nima-htmx/pom.xml b/tests/test-nima-htmx/pom.xml index 3e949f364..f739f2fa2 100644 --- a/tests/test-nima-htmx/pom.xml +++ b/tests/test-nima-htmx/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.9-SNAPSHOT + 2.9-RC1 test-nima-htmx diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index a2c1587e6..40898199f 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.9-SNAPSHOT + 2.9-RC1 test-nima-jsonb diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index 9fa8e803d..7cb50c280 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.9-SNAPSHOT + 2.9-RC1 test-nima diff --git a/tests/test-sigma/pom.xml b/tests/test-sigma/pom.xml index 9efbcce36..d5493994b 100644 --- a/tests/test-sigma/pom.xml +++ b/tests/test-sigma/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 2.9-SNAPSHOT + 2.9-RC1 test-sigma From 83e98e547eac474a42f6f14dd0598b9bed5b1446 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Wed, 27 Nov 2024 18:49:16 +1300 Subject: [PATCH 1179/1323] [Jex generation] Add check for non null result in generated code Example: var result = controller.someMethod(args); if (result != null) { ctx.json(result); } --- .../http/generator/jex/ControllerMethodWriter.java | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java index 517db90a0..4d08fcb74 100644 --- a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java +++ b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java @@ -103,7 +103,8 @@ private void write(boolean requestScoped) { } writer.append(" "); if (!method.isVoid()) { - writeContextReturn(); + writer.append("var result = "); + } if (instrumentContext) { method.writeContext(writer, "ctx", "ctx"); @@ -128,13 +129,17 @@ private void write(boolean requestScoped) { } } writer.append(")"); - if (!method.isVoid()) { - writer.append(")"); - } if (instrumentContext) { writer.append(")"); } writer.append(";").eol(); + if (!method.isVoid()) { + writer.append(" if (result != null) {").eol(); + writer.append(" "); + writeContextReturn(); + writer.append("result);").eol(); + writer.append(" }").eol(); + } } private void writeContextReturn() { From 46956dbb96f502f87ddcbc319d222742a343f51c Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Wed, 27 Nov 2024 00:53:28 -0500 Subject: [PATCH 1180/1323] fix jex error controller generation (#518) --- .../generator/jex/ControllerMethodWriter.java | 16 +++++++++------ tests/pom.xml | 2 +- .../src/main/java/org/example/Main.java | 2 +- .../java/org/example/web/TestController.java | 20 ++++++++++++++++++- 4 files changed, 31 insertions(+), 9 deletions(-) diff --git a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java index 4d08fcb74..e043b299f 100644 --- a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java +++ b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java @@ -42,10 +42,14 @@ void writeRouting() { final PathSegments segments = method.pathSegments(); final String fullPath = segments.fullPath(); - if (isFilter) { + if (method.isErrorMethod()) { + writer.append(" routing.error(%s.class, this::_%s)", method.exceptionShortName(), method.simpleName()); + } else if (isFilter) { writer.append(" routing.filter(this::_%s)", method.simpleName()); } else { - writer.append(" routing.%s(\"%s\", this::_%s)", webMethod.name().toLowerCase(), fullPath, method.simpleName()); + writer.append( + " routing.%s(\"%s\", this::_%s)", + webMethod.name().toLowerCase(), fullPath, method.simpleName()); } List roles = method.roles(); @@ -65,14 +69,14 @@ void writeRouting() { void writeHandler(boolean requestScoped) { if (method.isErrorMethod()) { - writer.append(" private void _%s(Context ctx, %s ex)", method.simpleName(), method.exceptionShortName()); + writer.append(" private void _%s(Context ctx, %s ex) {", method.simpleName(), method.exceptionShortName()); } else if (isFilter) { - writer.append(" private void _%s(Context ctx, FilterChain chain)", method.simpleName()); + writer.append(" private void _%s(Context ctx, FilterChain chain) throws IOException {", method.simpleName()); } else { - writer.append(" private void _%s(Context ctx)", method.simpleName()); + writer.append(" private void _%s(Context ctx) throws IOException {", method.simpleName()); } - writer.append(" throws IOException {", method.simpleName()).eol(); + writer.eol(); write(requestScoped); writer.append(" }").eol().eol(); diff --git a/tests/pom.xml b/tests/pom.xml index 39c94d55e..8d146e655 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -15,7 +15,7 @@ 5.11.3 3.26.3 2.18.1 - 3.0-RC1 + 3.0-RC2 11.0 4.1.4 6.3.0 diff --git a/tests/test-jex/src/main/java/org/example/Main.java b/tests/test-jex/src/main/java/org/example/Main.java index fc951fcbe..abc569d81 100644 --- a/tests/test-jex/src/main/java/org/example/Main.java +++ b/tests/test-jex/src/main/java/org/example/Main.java @@ -23,7 +23,7 @@ public static Jex.Server start(int port, BeanScope context) { final Jex jex = Jex.create(); jex.routing().addAll(context.list(Routing.HttpService.class)); - jex.routing().error(ValidationException.class, (exception, ctx) -> { + jex.routing().error(ValidationException.class, (ctx, exception) -> { Map map = new LinkedHashMap<>(); map.put("message", exception.getMessage()); map.put("errors", exception.getErrors()); diff --git a/tests/test-jex/src/main/java/org/example/web/TestController.java b/tests/test-jex/src/main/java/org/example/web/TestController.java index 76791b0e0..1f3216767 100644 --- a/tests/test-jex/src/main/java/org/example/web/TestController.java +++ b/tests/test-jex/src/main/java/org/example/web/TestController.java @@ -6,12 +6,13 @@ import io.avaje.http.api.BodyString; import io.avaje.http.api.Controller; import io.avaje.http.api.Default; +import io.avaje.http.api.ExceptionHandler; import io.avaje.http.api.Filter; import io.avaje.http.api.Get; -import io.avaje.http.api.InstrumentServerContext; import io.avaje.http.api.Options; import io.avaje.http.api.Path; import io.avaje.http.api.Post; +import io.avaje.http.api.Produces; import io.avaje.http.api.QueryParam; import io.avaje.jex.Context; import io.avaje.jex.FilterChain; @@ -50,4 +51,21 @@ void filter(FilterChain chain) throws IOException { System.err.println("do nothing lmao"); chain.proceed(); } + + @ExceptionHandler + String exception(IllegalArgumentException ex) { + return "Err: " + ex; + } + + @Produces(statusCode = 501) + @ExceptionHandler + HelloDto exceptionCtx(Exception ex, Context ctx) { + return null; + } + + @ExceptionHandler(IllegalStateException.class) + void exceptionVoid(Context ctx) { + ctx.status(503); + ctx.text("IllegalStateException"); + } } From 95d95098ab8ec401cac99841e7e51f3aee3da545 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Wed, 27 Nov 2024 23:39:36 +1300 Subject: [PATCH 1181/1323] [Jex generation] Add initial support for htmx (#520) Currently, it does not handle the case of common routing entry (for normal processing and hx). --- .../generator/jex/ControllerMethodWriter.java | 172 +++++++++++++++--- .../http/generator/jex/ControllerWriter.java | 36 +++- tests/test-jex/pom.xml | 26 ++- .../org/example/web/ContentController.java | 26 +++ .../org/example/web/MyTemplateRender.java | 14 ++ .../org/example/web/template/ViewHome.java | 12 ++ .../example/web/template/package-info.java | 4 + .../src/main/resources/public/openapi.json | 24 +++ .../resources/ui/fragments/layout.mustache | 11 ++ .../src/main/resources/ui/home.mustache | 8 + .../src/main/resources/ui/name.mustache | 6 + 11 files changed, 305 insertions(+), 34 deletions(-) create mode 100644 tests/test-jex/src/main/java/org/example/web/ContentController.java create mode 100644 tests/test-jex/src/main/java/org/example/web/MyTemplateRender.java create mode 100644 tests/test-jex/src/main/java/org/example/web/template/ViewHome.java create mode 100644 tests/test-jex/src/main/java/org/example/web/template/package-info.java create mode 100644 tests/test-jex/src/main/resources/ui/fragments/layout.mustache create mode 100644 tests/test-jex/src/main/resources/ui/home.mustache create mode 100644 tests/test-jex/src/main/resources/ui/name.mustache diff --git a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java index e043b299f..9085e7255 100644 --- a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java +++ b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java @@ -1,14 +1,12 @@ package io.avaje.http.generator.jex; -import static io.avaje.http.generator.core.ProcessingContext.isAssignable2Interface; -import static io.avaje.http.generator.core.ProcessingContext.logError; -import static io.avaje.http.generator.core.ProcessingContext.platform; - -import java.io.IOException; import java.util.List; import io.avaje.http.generator.core.*; -import io.avaje.http.generator.core.openapi.MediaType; + +import javax.lang.model.type.TypeMirror; + +import static io.avaje.http.generator.core.ProcessingContext.*; /** * Write code to register Web route for a given controller method. @@ -17,13 +15,15 @@ class ControllerMethodWriter { private final MethodReader method; private final Append writer; + private final ControllerReader reader; private final WebMethod webMethod; private final boolean instrumentContext; private final boolean isFilter; - ControllerMethodWriter(MethodReader method, Append writer) { + ControllerMethodWriter(MethodReader method, Append writer, ControllerReader reader) { this.method = method; this.writer = writer; + this.reader = reader; this.webMethod = method.webMethod(); this.instrumentContext = method.instrumentContext(); this.isFilter = webMethod == CoreWebMethod.FILTER; @@ -47,11 +47,19 @@ void writeRouting() { } else if (isFilter) { writer.append(" routing.filter(this::_%s)", method.simpleName()); } else { - writer.append( - " routing.%s(\"%s\", this::_%s)", - webMethod.name().toLowerCase(), fullPath, method.simpleName()); + writer.append(" routing.%s(\"%s\", ", webMethod.name().toLowerCase(), fullPath); + var hxRequest = method.hxRequest(); + if (hxRequest != null) { + writeHxHandler(hxRequest); + } else { + writer.append("this::_%s)", method.simpleName()); + } } + writeRoles(); + writer.append(";").eol(); + } + private void writeRoles() { List roles = method.roles(); if (!roles.isEmpty()) { writer.append(".withRoles("); @@ -63,11 +71,88 @@ void writeRouting() { } writer.append(")"); } - writer.append(";").eol(); } - void writeHandler(boolean requestScoped) { + private void writeHxHandler(HxRequestPrism hxRequest) { + writer.append("HxHandler.builder(this::_%s)", method.simpleName()); + if (hasValue(hxRequest.target())) { + writer.append(".target(\"%s\")", hxRequest.target()); + } + if (hasValue(hxRequest.triggerId())) { + writer.append(".trigger(\"%s\")", hxRequest.triggerId()); + } else if (hasValue(hxRequest.value())) { + writer.append(".trigger(\"%s\")", hxRequest.value()); + } + if (hasValue(hxRequest.triggerName())) { + writer.append(".triggerName(\"%s\")", hxRequest.triggerName()); + } else if (hasValue(hxRequest.value())) { + writer.append(".triggerName(\"%s\")", hxRequest.value()); + } + writer.append(".build())"); + } + private static boolean hasValue(String value) { + return value != null && !value.isBlank(); + } + + enum ResponseMode { + Void, + Json, + Text, + Templating, + InputStream, + Other + } + + ResponseMode responseMode() { + if (method.isVoid() || isFilter) { + return ResponseMode.Void; + } + if (isInputStream(method.returnType())) { + return ResponseMode.InputStream; + } + if (producesJson()) { + return ResponseMode.Json; + } + if (useTemplating()) { + return ResponseMode.Templating; + } + if (producesText()) { + return ResponseMode.Text; + } + return ResponseMode.Other; + } + + private boolean isInputStream(TypeMirror type) { + return isAssignable2Interface(type.toString(), "java.io.InputStream"); + } + + private boolean producesJson() { + return // useJsonB + !disabledDirectWrites() + && !"byte[]".equals(method.returnType().toString()) + && (method.produces() == null || method.produces().toLowerCase().contains("json")); + } + + private boolean producesText() { + return (method.produces() != null && method.produces().toLowerCase().contains("text")); + } + + private boolean useContentCache() { + return method.hasContentCache(); + } + + private boolean useTemplating() { + return reader.html() + && !"byte[]".equals(method.returnType().toString()) + && (method.produces() == null || method.produces().toLowerCase().contains("html")); + } + + private boolean usesFormParams() { + return method.params().stream().anyMatch(p -> p.isForm() || ParamType.FORMPARAM.equals(p.paramType())); + } + + void writeHandler(boolean requestScoped) { if (method.isErrorMethod()) { writer.append(" private void _%s(Context ctx, %s ex) {", method.simpleName(), method.exceptionShortName()); } else if (isFilter) { @@ -77,7 +162,6 @@ void writeHandler(boolean requestScoped) { } writer.eol(); - write(requestScoped); writer.append(" }").eol().eol(); } @@ -105,6 +189,23 @@ private void write(boolean requestScoped) { param.writeValidate(writer); } } + final var withFormParams = usesFormParams(); + final ResponseMode responseMode = responseMode(); + final boolean withContentCache = responseMode == ResponseMode.Templating && useContentCache(); + if (withContentCache) { + writer.append(" var key = contentCache.key(ctx"); + if (withFormParams) { + writer.append(", ctx.formParamMap()"); + } + writer.append(");").eol(); + writer.append(" var cacheContent = contentCache.content(key);").eol(); + writer.append(" if (cacheContent != null) {").eol(); + writeContextReturn(responseMode); + writer.append(" res.send(cacheContent);").eol(); + writer.append(" return;").eol(); + writer.append(" }").eol(); + } + writer.append(" "); if (!method.isVoid()) { writer.append("var result = "); @@ -138,26 +239,39 @@ private void write(boolean requestScoped) { } writer.append(";").eol(); if (!method.isVoid()) { - writer.append(" if (result != null) {").eol(); - writer.append(" "); - writeContextReturn(); - writer.append("result);").eol(); - writer.append(" }").eol(); + TypeMirror typeMirror = method.returnType(); + boolean includeNoContent = !typeMirror.getKind().isPrimitive(); + String indent = includeNoContent ? " " : " "; + if (includeNoContent) { + writer.append(" if (result != null) {").eol(); + } + if (responseMode == ResponseMode.Templating) { + writer.append(indent).append("var content = renderer.render(result);").eol(); + if (withContentCache) { + writer.append(indent).append("contentCache.contentPut(key, content);").eol(); + } + writer.append(indent); + writeContextReturn(responseMode); + writer.append("content);").eol(); + } else { + writer.append(indent); + writeContextReturn(responseMode); + writer.append("result);").eol(); + } + if (includeNoContent) { + writer.append(" }").eol(); + } } } - private void writeContextReturn() { + private void writeContextReturn(ResponseMode responseMode) { final var produces = method.produces(); - if (produces == null || produces.equalsIgnoreCase(MediaType.APPLICATION_JSON.getValue())) { - writer.append("ctx.json("); - } else if (produces.equalsIgnoreCase(MediaType.TEXT_HTML.getValue())) { - writer.append("ctx.html("); - } else if (produces.equalsIgnoreCase(MediaType.TEXT_PLAIN.getValue())) { - writer.append("ctx.text("); - } else if (JsonBUtil.isJsonMimeType(produces)) { - writer.append("ctx.contentType(\"%s\").json(", produces); - } else { - writer.append("ctx.contentType(\"%s\").write(", produces); + switch (responseMode) { + case Void: break; + case Json: writer.append("ctx.json("); break; + case Text: writer.append("ctx.text("); break; + case Templating: writer.append("ctx.html("); break; + default: writer.append("ctx.contentType(\"%s\").write(", produces); } } diff --git a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerWriter.java b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerWriter.java index f22876af6..cf694a5e7 100644 --- a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerWriter.java +++ b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerWriter.java @@ -4,6 +4,7 @@ import io.avaje.http.generator.core.*; import java.io.IOException; +import java.util.Objects; /** * Write Jex specific Controller WebRoute handling adapter. @@ -19,12 +20,22 @@ class ControllerWriter extends BaseControllerWriter { reader.addImportType(API_CONTEXT); reader.addImportType(API_ROUTING); reader.addImportType("java.io.IOException"); - if (reader.methods().stream() .map(MethodReader::webMethod) .anyMatch(w -> CoreWebMethod.FILTER == w)) { reader.addImportType("io.avaje.jex.FilterChain"); } + if (reader.methods().stream() + .map(MethodReader::hxRequest) + .anyMatch(Objects::nonNull)) { + reader.addImportType("io.avaje.jex.htmx.HxHandler"); + } + if (reader.html()) { + reader.addImportType("io.avaje.jex.htmx.TemplateRender"); + if (reader.hasContentCache()) { + reader.addImportType("io.avaje.jex.htmx.TemplateContentCache"); + } + } } void write() { @@ -50,7 +61,7 @@ private void writeAddRoutes() { private void writeHandlers() { for (MethodReader method : reader.methods()) { if (method.isWebMethod()) { - new ControllerMethodWriter(method, writer).writeHandler(isRequestScoped()); + new ControllerMethodWriter(method, writer, reader).writeHandler(isRequestScoped()); if (!reader.isDocHidden()) { method.buildApiDocumentation(); } @@ -59,7 +70,7 @@ private void writeHandlers() { } private void writeRouting(MethodReader method) { - new ControllerMethodWriter(method, writer).writeRouting(); + new ControllerMethodWriter(method, writer, reader).writeRouting(); } private void writeClassStart() { @@ -82,7 +93,12 @@ private void writeClassStart() { if (instrumentContext) { writer.append(" private final RequestContextResolver resolver;").eol(); } - + if (reader.html()) { + writer.append(" private final TemplateRender renderer;").eol(); + if (reader.hasContentCache()) { + writer.append(" private final TemplateContentCache contentCache;").eol(); + } + } writer.eol(); writer.append(" public %s$Route(%s %s", shortName, controllerType, controllerName); @@ -92,6 +108,12 @@ private void writeClassStart() { if (instrumentContext) { writer.append(", RequestContextResolver resolver"); } + if (reader.html()) { + writer.append(", TemplateRender renderer"); + if (reader.hasContentCache()) { + writer.append(", TemplateContentCache contentCache"); + } + } writer.append(") {").eol(); writer.append(" this.%s = %s;", controllerName, controllerName).eol(); if (reader.isIncludeValidator()) { @@ -100,6 +122,12 @@ private void writeClassStart() { if (instrumentContext) { writer.append(" this.resolver = resolver;").eol(); } + if (reader.html()) { + writer.append(" this.renderer = renderer;").eol(); + if (reader.hasContentCache()) { + writer.append(" this.contentCache = contentCache;").eol(); + } + } writer.append(" }").eol().eol(); } diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 7f3e59b17..1f73a43f0 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -29,6 +29,24 @@ ${jex.version} + + io.avaje + avaje-htmx-api + ${project.version} + + + + io.avaje + avaje-jex-htmx + ${jex.version} + + + + io.jstach + jstachio + 1.3.6 + + com.fasterxml.jackson.core jackson-databind @@ -52,7 +70,7 @@ swagger-annotations ${swagger.version} - + io.avaje avaje-jsonb @@ -81,6 +99,12 @@ 2.3 + + io.jstach + jstachio-apt + 1.3.6 + + io.avaje diff --git a/tests/test-jex/src/main/java/org/example/web/ContentController.java b/tests/test-jex/src/main/java/org/example/web/ContentController.java new file mode 100644 index 000000000..86ebac2e1 --- /dev/null +++ b/tests/test-jex/src/main/java/org/example/web/ContentController.java @@ -0,0 +1,26 @@ +package org.example.web; + +import io.avaje.htmx.api.Html; +import io.avaje.htmx.api.HxRequest; +import io.avaje.http.api.Controller; +import io.avaje.http.api.Get; +import io.avaje.http.api.Path; +import org.example.web.template.ViewHome; + +@Controller +@Html +@Path("ui") +public class ContentController { + + @Get + Object index() { + return new ViewHome("Hi"); + } + + @HxRequest + @Get + Object indexHxReqest() { + return new ViewHome("Hi"); + } + +} diff --git a/tests/test-jex/src/main/java/org/example/web/MyTemplateRender.java b/tests/test-jex/src/main/java/org/example/web/MyTemplateRender.java new file mode 100644 index 000000000..e6fa40a7c --- /dev/null +++ b/tests/test-jex/src/main/java/org/example/web/MyTemplateRender.java @@ -0,0 +1,14 @@ +package org.example.web; + +import io.avaje.inject.Component; +import io.avaje.jex.htmx.TemplateRender; +import io.jstach.jstache.JStache; +import io.jstach.jstachio.JStachio; + +@Component +public class MyTemplateRender implements TemplateRender { + @Override + public String render(Object viewModel) { + return JStachio.render(viewModel); + } +} diff --git a/tests/test-jex/src/main/java/org/example/web/template/ViewHome.java b/tests/test-jex/src/main/java/org/example/web/template/ViewHome.java new file mode 100644 index 000000000..c4cd9c824 --- /dev/null +++ b/tests/test-jex/src/main/java/org/example/web/template/ViewHome.java @@ -0,0 +1,12 @@ +package org.example.web.template; + +import io.jstach.jstache.JStache; + +@JStache(path = "home") +public class ViewHome { + public final String name; + + public ViewHome(String name) { + this.name = name; + } +} diff --git a/tests/test-jex/src/main/java/org/example/web/template/package-info.java b/tests/test-jex/src/main/java/org/example/web/template/package-info.java new file mode 100644 index 000000000..ab3d673f0 --- /dev/null +++ b/tests/test-jex/src/main/java/org/example/web/template/package-info.java @@ -0,0 +1,4 @@ +@JStachePath(prefix = "ui/", suffix = ".mustache") +package org.example.web.template; + +import io.jstach.jstache.JStachePath; diff --git a/tests/test-jex/src/main/resources/public/openapi.json b/tests/test-jex/src/main/resources/public/openapi.json index a6f5ac6b7..c80b60f6a 100644 --- a/tests/test-jex/src/main/resources/public/openapi.json +++ b/tests/test-jex/src/main/resources/public/openapi.json @@ -1291,6 +1291,27 @@ } } }, + "/ui" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "", + "content" : { + "text/html;charset=UTF8" : { + "schema" : { + "$ref" : "#/components/schemas/Object" + } + } + } + } + } + } + }, "/withDefault/{name}" : { "get" : { "tags" : [ @@ -1407,6 +1428,9 @@ "format" : "date" } } + }, + "Object" : { + "type" : "object" } } } diff --git a/tests/test-jex/src/main/resources/ui/fragments/layout.mustache b/tests/test-jex/src/main/resources/ui/fragments/layout.mustache new file mode 100644 index 000000000..26a8c9e85 --- /dev/null +++ b/tests/test-jex/src/main/resources/ui/fragments/layout.mustache @@ -0,0 +1,11 @@ + + + + Hi + + + +

    Heading

    +{{$body}}Empty body{{/body}} + + diff --git a/tests/test-jex/src/main/resources/ui/home.mustache b/tests/test-jex/src/main/resources/ui/home.mustache new file mode 100644 index 000000000..af4686584 --- /dev/null +++ b/tests/test-jex/src/main/resources/ui/home.mustache @@ -0,0 +1,8 @@ +{{ + Hi there {{ name }} + + +{{/body}} +{{/fragments/layout}} diff --git a/tests/test-jex/src/main/resources/ui/name.mustache b/tests/test-jex/src/main/resources/ui/name.mustache new file mode 100644 index 000000000..4c2f0f851 --- /dev/null +++ b/tests/test-jex/src/main/resources/ui/name.mustache @@ -0,0 +1,6 @@ +
    +Yond {{ name }} its {{ when }} !! and {{ more }} sad + {{#mlist}} + in {{.}} ot + {{/mlist}} +
    From 296c8fb1476e0c7b37236f3ab4d5e90fe4303d83 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Wed, 27 Nov 2024 23:51:22 +1300 Subject: [PATCH 1182/1323] Version 2.9-RC2 --- htmx-api/pom.xml | 2 +- htmx-nima-jstache/pom.xml | 2 +- htmx-nima/pom.xml | 4 ++-- http-api-javalin/pom.xml | 2 +- http-api/pom.xml | 2 +- http-client-gson-adapter/pom.xml | 4 ++-- http-client-moshi-adapter/pom.xml | 4 ++-- http-client/pom.xml | 2 +- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 2 +- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-generator-sigma/pom.xml | 2 +- http-inject-plugin/pom.xml | 2 +- pom.xml | 4 ++-- tests/pom.xml | 2 +- tests/test-client-generation/pom.xml | 2 +- tests/test-client/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-htmx/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- tests/test-sigma/pom.xml | 2 +- 26 files changed, 30 insertions(+), 30 deletions(-) diff --git a/htmx-api/pom.xml b/htmx-api/pom.xml index b2d3cedcd..100749cfa 100644 --- a/htmx-api/pom.xml +++ b/htmx-api/pom.xml @@ -6,7 +6,7 @@ io.avaje avaje-http-parent - 2.9-RC1 + 2.9-RC2 avaje-htmx-api diff --git a/htmx-nima-jstache/pom.xml b/htmx-nima-jstache/pom.xml index c498b8667..74558d19b 100644 --- a/htmx-nima-jstache/pom.xml +++ b/htmx-nima-jstache/pom.xml @@ -6,7 +6,7 @@ io.avaje avaje-http-parent - 2.9-RC1 + 2.9-RC2 avaje-htmx-nima-jstache diff --git a/htmx-nima/pom.xml b/htmx-nima/pom.xml index c59af28e7..86853da21 100644 --- a/htmx-nima/pom.xml +++ b/htmx-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje avaje-http-parent - 2.9-RC1 + 2.9-RC2 avaje-htmx-nima @@ -21,7 +21,7 @@ io.avaje avaje-htmx-api - 2.9-RC1 + 2.9-RC2 io.helidon.webserver diff --git a/http-api-javalin/pom.xml b/http-api-javalin/pom.xml index be83d8b57..e9ccf7bb2 100644 --- a/http-api-javalin/pom.xml +++ b/http-api-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.9-RC1 + 2.9-RC2 .. diff --git a/http-api/pom.xml b/http-api/pom.xml index 9ce46ce6e..68f347a09 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.9-RC1 + 2.9-RC2 .. diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index 3098b2de8..3d97d4233 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.9-RC1 + 2.9-RC2 avaje-http-client-gson @@ -20,7 +20,7 @@ io.avaje avaje-http-client - 2.9-RC1 + 2.9-RC2 provided diff --git a/http-client-moshi-adapter/pom.xml b/http-client-moshi-adapter/pom.xml index 4cfefc70d..51cfad5c7 100644 --- a/http-client-moshi-adapter/pom.xml +++ b/http-client-moshi-adapter/pom.xml @@ -3,7 +3,7 @@ io.avaje avaje-http-parent - 2.9-RC1 + 2.9-RC2 avaje-http-client-moshi @@ -19,7 +19,7 @@ io.avaje avaje-http-client - 2.9-RC1 + 2.9-RC2 provided diff --git a/http-client/pom.xml b/http-client/pom.xml index a1230c877..40e1c45ea 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.9-RC1 + 2.9-RC2 avaje-http-client diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index b84eef915..9868b1713 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.9-RC1 + 2.9-RC2 avaje-http-client-generator diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 5e5bdba5b..06a65263b 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.9-RC1 + 2.9-RC2 avaje-http-generator-core diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index b1af20fdc..4c5a94d0b 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.9-RC1 + 2.9-RC2 avaje-http-helidon-generator diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index 2c4a8e988..1ab71bddd 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.9-RC1 + 2.9-RC2 avaje-http-javalin-generator diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index 6dee54601..87730122a 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.9-RC1 + 2.9-RC2 avaje-http-jex-generator diff --git a/http-generator-sigma/pom.xml b/http-generator-sigma/pom.xml index 6dc34cb16..eb47b08a0 100644 --- a/http-generator-sigma/pom.xml +++ b/http-generator-sigma/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.9-RC1 + 2.9-RC2 avaje-http-sigma-generator diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index 3dcc59e12..006df8d82 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.9-RC1 + 2.9-RC2 .. diff --git a/pom.xml b/pom.xml index 546f67747..26551aa07 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-parent - 2.9-RC1 + 2.9-RC2 pom @@ -23,7 +23,7 @@ 2.14.2 3.0-SNAPSHOT 1.35 - 2024-11-26T20:06:26Z + 2024-11-27T10:39:59Z ${project.build.directory}${file.separator}module-info.shade diff --git a/tests/pom.xml b/tests/pom.xml index 8d146e655..dcf10e4e8 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.9-RC1 + 2.9-RC2 tests diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index b213b0fef..1ec7c737c 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.9-RC1 + 2.9-RC2 test-client-generation diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index 21c2521c6..68a4ef735 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.9-RC1 + 2.9-RC2 test-client diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 1e840dc91..ce96a280c 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 2.9-RC1 + 2.9-RC2 test-javalin-jsonb diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 4a15cda9f..b2df30de6 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.9-RC1 + 2.9-RC2 test-javalin diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 1f73a43f0..5dc1b1c4b 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.9-RC1 + 2.9-RC2 test-jex diff --git a/tests/test-nima-htmx/pom.xml b/tests/test-nima-htmx/pom.xml index f739f2fa2..0d912fd47 100644 --- a/tests/test-nima-htmx/pom.xml +++ b/tests/test-nima-htmx/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.9-RC1 + 2.9-RC2 test-nima-htmx diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 40898199f..f518a528e 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.9-RC1 + 2.9-RC2 test-nima-jsonb diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index 7cb50c280..ec4dc63f6 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.9-RC1 + 2.9-RC2 test-nima diff --git a/tests/test-sigma/pom.xml b/tests/test-sigma/pom.xml index d5493994b..5e5897865 100644 --- a/tests/test-sigma/pom.xml +++ b/tests/test-sigma/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 2.9-RC1 + 2.9-RC2 test-sigma From 2a78984f8e951c2c1ea21423eac5e4362f060e95 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Wed, 27 Nov 2024 13:52:04 -0500 Subject: [PATCH 1183/1323] [jex-generator] Update Filters and use enhanced switch (#521) * update filters and switch * Update pom.xml * Update TestController.java * Update ControllerMethodWriter.java --- http-generator-jex/pom.xml | 6 +- .../generator/jex/ControllerMethodWriter.java | 16 +++--- .../http/generator/jex/ControllerWriter.java | 2 +- .../avaje/http/generator/jex/JexAdapter.java | 57 ++++++++----------- tests/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- .../java/org/example/web/TestController.java | 2 +- 7 files changed, 40 insertions(+), 47 deletions(-) diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index 87730122a..2335699b8 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -8,7 +8,11 @@ avaje-http-jex-generator - + + + 21 + + diff --git a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java index 9085e7255..c091c9bf1 100644 --- a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java +++ b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java @@ -33,7 +33,7 @@ class ControllerMethodWriter { } private void validateMethod() { - if (method.params().stream().map(MethodParam::shortType).noneMatch("FilterChain"::equals)) { + if (method.params().stream().map(MethodParam::shortType).noneMatch("HttpFilter.FilterChain"::equals)) { logError(method.element(), "Filters must contain a FilterChain parameter"); } } @@ -227,7 +227,7 @@ private void write(boolean requestScoped) { final var param = params.get(i); if (isAssignable2Interface(param.utype().mainType(), "java.lang.Exception")) { writer.append("ex"); - } else if ("FilterChain".equals(param.shortType())) { + } else if ("HttpFilter.FilterChain".equals(param.shortType())) { writer.append("chain"); } else { param.buildParamName(writer); @@ -267,16 +267,16 @@ private void write(boolean requestScoped) { private void writeContextReturn(ResponseMode responseMode) { final var produces = method.produces(); switch (responseMode) { - case Void: break; - case Json: writer.append("ctx.json("); break; - case Text: writer.append("ctx.text("); break; - case Templating: writer.append("ctx.html("); break; - default: writer.append("ctx.contentType(\"%s\").write(", produces); + case Void -> {} + case Json -> writer.append("ctx.json("); + case Text -> writer.append("ctx.text("); + case Templating -> writer.append("ctx.html("); + default -> writer.append("ctx.contentType(\"%s\").write(", produces); } } private static boolean isExceptionOrFilterChain(MethodParam param) { return isAssignable2Interface(param.utype().mainType(), "java.lang.Exception") - || "FilterChain".equals(param.shortType()); + || "HttpFilter.FilterChain".equals(param.shortType()); } } diff --git a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerWriter.java b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerWriter.java index cf694a5e7..e8972635c 100644 --- a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerWriter.java +++ b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerWriter.java @@ -23,7 +23,7 @@ class ControllerWriter extends BaseControllerWriter { if (reader.methods().stream() .map(MethodReader::webMethod) .anyMatch(w -> CoreWebMethod.FILTER == w)) { - reader.addImportType("io.avaje.jex.FilterChain"); + reader.addImportType("io.avaje.jex.HttpFilter.FilterChain"); } if (reader.methods().stream() .map(MethodReader::hxRequest) diff --git a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/JexAdapter.java b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/JexAdapter.java index 03a13fb2f..3ed2e3df8 100644 --- a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/JexAdapter.java +++ b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/JexAdapter.java @@ -69,7 +69,8 @@ public void writeReadParameter(Append writer, ParamType paramType, String paramN } @Override - public void writeReadParameter(Append writer, ParamType paramType, String paramName, String paramDefault) { + public void writeReadParameter( + Append writer, ParamType paramType, String paramName, String paramDefault) { writer.append("withDefault(ctx.%s(\"%s\"), \"%s\")", paramType, paramName, paramDefault); } @@ -77,31 +78,22 @@ public void writeReadParameter(Append writer, ParamType paramType, String paramN public void writeReadMapParameter(Append writer, ParamType paramType) { switch (paramType) { - case QUERYPARAM: - writer.append("ctx.queryParamMap()"); - break; - case FORM: - case FORMPARAM: - writer.append("ctx.formParamMap()"); - break; - default: - throw new UnsupportedOperationException( - "Only Query/Form Params have Map> supported in Jex"); + case QUERYPARAM -> writer.append("ctx.queryParamMap()"); + case FORM, FORMPARAM -> writer.append("ctx.formParamMap()"); + default -> + throw new UnsupportedOperationException( + "Only Query/Form Params have Map> supported in Jex"); } } @Override public void writeReadCollectionParameter(Append writer, ParamType paramType, String paramName) { switch (paramType) { - case QUERYPARAM: - writer.append("ctx.queryParams(\"%s\")", paramName); - break; - case FORMPARAM: - writer.append("ctx.formParams(\"%s\")", paramName); - break; - default: - throw new UnsupportedOperationException( - "Only MultiValue Form/Query Params are supported in Jex"); + case QUERYPARAM -> writer.append("ctx.queryParams(\"%s\")", paramName); + case FORMPARAM -> writer.append("ctx.formParams(\"%s\")", paramName); + default -> + throw new UnsupportedOperationException( + "Only MultiValue Form/Query Params are supported in Jex"); } } @@ -110,19 +102,17 @@ public void writeReadCollectionParameter( Append writer, ParamType paramType, String paramName, List paramDefault) { switch (paramType) { - case QUERYPARAM: - writer.append( - "withDefault(ctx.queryParams(\"%s\"), java.util.List.of(\"%s\"))", - paramName, String.join(",", paramDefault)); - break; - case FORMPARAM: - writer.append( - "withDefault(ctx.formParams(\"%s\"), java.util.List.of(\"%s\"))", - paramName, String.join(",", paramDefault)); - break; - default: - throw new UnsupportedOperationException( - "Only MultiValue Form/Query Params are supported in Jex"); + case QUERYPARAM -> + writer.append( + "withDefault(ctx.queryParams(\"%s\"), java.util.List.of(\"%s\"))", + paramName, String.join(",", paramDefault)); + case FORMPARAM -> + writer.append( + "withDefault(ctx.formParams(\"%s\"), java.util.List.of(\"%s\"))", + paramName, String.join(",", paramDefault)); + default -> + throw new UnsupportedOperationException( + "Only MultiValue Form/Query Params are supported in Jex"); } } @@ -130,5 +120,4 @@ public void writeReadCollectionParameter( public void writeAcceptLanguage(Append writer) { writer.append("ctx.header(\"%s\")", Constants.ACCEPT_LANGUAGE); } - } diff --git a/tests/pom.xml b/tests/pom.xml index dcf10e4e8..68f5c038e 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -15,7 +15,7 @@ 5.11.3 3.26.3 2.18.1 - 3.0-RC2 + 3.0-RC3 11.0 4.1.4 6.3.0 diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 5dc1b1c4b..f8552f2ca 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -8,8 +8,8 @@ test-jex - + 21 true org.example.myapp.Main 2.2.26 diff --git a/tests/test-jex/src/main/java/org/example/web/TestController.java b/tests/test-jex/src/main/java/org/example/web/TestController.java index 1f3216767..3625c946d 100644 --- a/tests/test-jex/src/main/java/org/example/web/TestController.java +++ b/tests/test-jex/src/main/java/org/example/web/TestController.java @@ -15,7 +15,7 @@ import io.avaje.http.api.Produces; import io.avaje.http.api.QueryParam; import io.avaje.jex.Context; -import io.avaje.jex.FilterChain; +import io.avaje.jex.HttpFilter.FilterChain; @Path("test/") @Controller From ee262495209da1a22646b94ce6f234e0c006f6ca Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Mon, 2 Dec 2024 04:33:05 -0500 Subject: [PATCH 1184/1323] [Jex-Generator] Jsonb Type generation (#522) * jsonb jex generation * fix json * Use jex 3.0-RC6 (with RouteBuilder change) * Use jex 3.0-RC7 (with RouteBuilder change) --------- Co-authored-by: Rob Bygrave --- .../generator/jex/ControllerMethodWriter.java | 55 +++++++++++----- .../http/generator/jex/ControllerWriter.java | 34 +++++++++- .../http/generator/jex/JexProcessor.java | 3 +- pom.xml | 2 +- tests/pom.xml | 2 +- tests/test-client-generation/pom.xml | 16 +++-- .../src/main/resources/logback.xml | 18 ++++++ .../main/java/org/example/web/HelloDto.java | 2 + .../org/example/web/myapp/WebController.java | 31 +++------- .../myapp/{HelloDto.java => WebHelloDto.java} | 6 +- .../example/web/myapp/service/MyService.java | 10 +-- .../src/main/resources/public/openapi.json | 62 ++++++++++--------- 12 files changed, 152 insertions(+), 89 deletions(-) create mode 100644 tests/test-client-generation/src/main/resources/logback.xml rename tests/test-jex/src/main/java/org/example/web/myapp/{HelloDto.java => WebHelloDto.java} (87%) diff --git a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java index c091c9bf1..9c3d0b7b3 100644 --- a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java +++ b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java @@ -3,6 +3,7 @@ import java.util.List; import io.avaje.http.generator.core.*; +import io.avaje.http.generator.core.openapi.MediaType; import javax.lang.model.type.TypeMirror; @@ -17,22 +18,25 @@ class ControllerMethodWriter { private final Append writer; private final ControllerReader reader; private final WebMethod webMethod; + private final boolean useJsonB; private final boolean instrumentContext; private final boolean isFilter; - ControllerMethodWriter(MethodReader method, Append writer, ControllerReader reader) { + ControllerMethodWriter( + MethodReader method, Append writer, ControllerReader reader, boolean useJsonB) { this.method = method; this.writer = writer; this.reader = reader; + this.useJsonB = useJsonB; this.webMethod = method.webMethod(); this.instrumentContext = method.instrumentContext(); this.isFilter = webMethod == CoreWebMethod.FILTER; if (isFilter) { - validateMethod(); + validateFilter(); } } - private void validateMethod() { + private void validateFilter() { if (method.params().stream().map(MethodParam::shortType).noneMatch("HttpFilter.FilterChain"::equals)) { logError(method.element(), "Filters must contain a FilterChain parameter"); } @@ -128,9 +132,7 @@ private boolean isInputStream(TypeMirror type) { } private boolean producesJson() { - return // useJsonB - !disabledDirectWrites() - && !"byte[]".equals(method.returnType().toString()) + return !"byte[]".equals(method.returnType().toString()) && (method.produces() == null || method.produces().toLowerCase().contains("json")); } @@ -200,8 +202,7 @@ private void write(boolean requestScoped) { writer.append(");").eol(); writer.append(" var cacheContent = contentCache.content(key);").eol(); writer.append(" if (cacheContent != null) {").eol(); - writeContextReturn(responseMode); - writer.append(" res.send(cacheContent);").eol(); + writeContextReturn(responseMode, "cacheContent"); writer.append(" return;").eol(); writer.append(" }").eol(); } @@ -251,12 +252,11 @@ private void write(boolean requestScoped) { writer.append(indent).append("contentCache.contentPut(key, content);").eol(); } writer.append(indent); - writeContextReturn(responseMode); - writer.append("content);").eol(); + writeContextReturn(responseMode, "content"); } else { writer.append(indent); - writeContextReturn(responseMode); - writer.append("result);").eol(); + writeContextReturn(responseMode, "result"); + writer.eol(); } if (includeNoContent) { writer.append(" }").eol(); @@ -264,14 +264,35 @@ private void write(boolean requestScoped) { } } - private void writeContextReturn(ResponseMode responseMode) { + private void writeContextReturn(ResponseMode responseMode, String resultVariable) { + final UType type = UType.parse(method.returnType()); + if ("java.util.concurrent.CompletableFuture".equals(type.mainType())) { + logError(method.element(), "CompletableFuture is not a supported return type."); + writer.append("; //ERROR"); + return; + } + final var produces = method.produces(); switch (responseMode) { case Void -> {} - case Json -> writer.append("ctx.json("); - case Text -> writer.append("ctx.text("); - case Templating -> writer.append("ctx.html("); - default -> writer.append("ctx.contentType(\"%s\").write(", produces); + case Json -> writeJsonReturn(produces); + case Text -> writer.append("ctx.text(%s);", resultVariable); + case Templating -> writer.append("ctx.html(%s);", resultVariable); + default -> writer.append("ctx.contentType(\"%s\").write(%s);", produces, resultVariable); + } + } + + private void writeJsonReturn(String produces) { + if (useJsonB) { + var uType = UType.parse(method.returnType()); + if (produces == null) { + produces = MediaType.APPLICATION_JSON.getValue(); + } + writer.append( + "%sJsonType.toJson(result, ctx.contentType(\"%s\").outputStream());", + uType.shortName(), produces); + } else { + writer.append("ctx.json(result);"); } } diff --git a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerWriter.java b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerWriter.java index e8972635c..5a1027049 100644 --- a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerWriter.java +++ b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerWriter.java @@ -4,6 +4,7 @@ import io.avaje.http.generator.core.*; import java.io.IOException; +import java.util.Map; import java.util.Objects; /** @@ -14,9 +15,12 @@ class ControllerWriter extends BaseControllerWriter { private static final String AT_GENERATED = "@Generated(\"avaje-jex-generator\")"; private static final String API_CONTEXT = "io.avaje.jex.Context"; private static final String API_ROUTING = "io.avaje.jex.Routing"; + private final boolean useJsonB; + private final Map jsonTypes; - ControllerWriter(ControllerReader reader) throws IOException { + ControllerWriter(ControllerReader reader, boolean jsonb) throws IOException { super(reader); + this.useJsonB = jsonb; reader.addImportType(API_CONTEXT); reader.addImportType(API_ROUTING); reader.addImportType("java.io.IOException"); @@ -36,6 +40,15 @@ class ControllerWriter extends BaseControllerWriter { reader.addImportType("io.avaje.jex.htmx.TemplateContentCache"); } } + if (useJsonB) { + reader.addImportType("io.avaje.jsonb.Jsonb"); + reader.addImportType("io.avaje.jsonb.JsonType"); + reader.addImportType("io.avaje.jsonb.Types"); + this.jsonTypes = JsonBUtil.jsonTypes(reader); + jsonTypes.values().stream().map(UType::importTypes).forEach(reader::addImportTypes); + } else { + this.jsonTypes = Map.of(); + } } void write() { @@ -61,7 +74,7 @@ private void writeAddRoutes() { private void writeHandlers() { for (MethodReader method : reader.methods()) { if (method.isWebMethod()) { - new ControllerMethodWriter(method, writer, reader).writeHandler(isRequestScoped()); + new ControllerMethodWriter(method, writer, reader, useJsonB).writeHandler(isRequestScoped()); if (!reader.isDocHidden()) { method.buildApiDocumentation(); } @@ -70,7 +83,7 @@ private void writeHandlers() { } private void writeRouting(MethodReader method) { - new ControllerMethodWriter(method, writer, reader).writeRouting(); + new ControllerMethodWriter(method, writer, reader, useJsonB).writeRouting(); } private void writeClassStart() { @@ -93,18 +106,28 @@ private void writeClassStart() { if (instrumentContext) { writer.append(" private final RequestContextResolver resolver;").eol(); } + if (reader.html()) { writer.append(" private final TemplateRender renderer;").eol(); if (reader.hasContentCache()) { writer.append(" private final TemplateContentCache contentCache;").eol(); } } + + for (final UType type : jsonTypes.values()) { + final var typeString = PrimitiveUtil.wrap(type.shortType()).replace(",", ", "); + writer.append(" private final JsonType<%s> %sJsonType;", typeString, type.shortName()).eol(); + } + writer.eol(); writer.append(" public %s$Route(%s %s", shortName, controllerType, controllerName); if (reader.isIncludeValidator()) { writer.append(", Validator validator"); } + if (useJsonB) { + writer.append(", Jsonb jsonb"); + } if (instrumentContext) { writer.append(", RequestContextResolver resolver"); } @@ -128,6 +151,11 @@ private void writeClassStart() { writer.append(" this.contentCache = contentCache;").eol(); } } + if (useJsonB) { + for (final UType type : jsonTypes.values()) { + JsonBUtil.writeJsonbType(type, writer); + } + } writer.append(" }").eol().eol(); } diff --git a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/JexProcessor.java b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/JexProcessor.java index 95f4712fa..d6a112730 100644 --- a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/JexProcessor.java +++ b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/JexProcessor.java @@ -3,6 +3,7 @@ import io.avaje.http.generator.core.BaseProcessor; import io.avaje.http.generator.core.ControllerReader; import io.avaje.http.generator.core.PlatformAdapter; +import io.avaje.http.generator.core.ProcessingContext; import io.avaje.prism.AnnotationProcessor; import java.io.IOException; @@ -17,6 +18,6 @@ protected PlatformAdapter providePlatformAdapter() { @Override public void writeControllerAdapter(ControllerReader reader) throws IOException { - new ControllerWriter(reader).write(); + new ControllerWriter(reader, ProcessingContext.useJsonb()).write(); } } diff --git a/pom.xml b/pom.xml index 26551aa07..839e311b0 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ true 2.2.26 2.14.2 - 3.0-SNAPSHOT + 3.0-RC7 1.35 2024-11-27T10:39:59Z ${project.build.directory}${file.separator}module-info.shade diff --git a/tests/pom.xml b/tests/pom.xml index 68f5c038e..4515ac310 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -15,7 +15,7 @@ 5.11.3 3.26.3 2.18.1 - 3.0-RC3 + 3.0-RC7 11.0 4.1.4 6.3.0 diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index 1ec7c737c..b7fb04adb 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -18,9 +18,15 @@ - org.avaje - logback - 1.0 + org.slf4j + slf4j-jdk-platform-logging + 2.0.16 + + + + ch.qos.logback + logback-classic + 1.5.12 @@ -90,7 +96,7 @@ ${assertj.version} test - + io.avaje @@ -102,7 +108,7 @@ avaje-http-jex-generator ${project.version} - + diff --git a/tests/test-client-generation/src/main/resources/logback.xml b/tests/test-client-generation/src/main/resources/logback.xml new file mode 100644 index 000000000..4bcf2f924 --- /dev/null +++ b/tests/test-client-generation/src/main/resources/logback.xml @@ -0,0 +1,18 @@ + + + + TRACE + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + + + + diff --git a/tests/test-jex/src/main/java/org/example/web/HelloDto.java b/tests/test-jex/src/main/java/org/example/web/HelloDto.java index 7f1c00686..ce271eb27 100644 --- a/tests/test-jex/src/main/java/org/example/web/HelloDto.java +++ b/tests/test-jex/src/main/java/org/example/web/HelloDto.java @@ -1,9 +1,11 @@ package org.example.web; +import io.avaje.jsonb.Json; import io.avaje.validation.constraints.NotNull; import io.avaje.validation.constraints.Valid; @Valid +@Json public class HelloDto { public int id; @NotNull diff --git a/tests/test-jex/src/main/java/org/example/web/myapp/WebController.java b/tests/test-jex/src/main/java/org/example/web/myapp/WebController.java index 9aae94a0b..ae51b7e8f 100644 --- a/tests/test-jex/src/main/java/org/example/web/myapp/WebController.java +++ b/tests/test-jex/src/main/java/org/example/web/myapp/WebController.java @@ -64,8 +64,8 @@ String getPlainMessage() { @Deprecated @Roles({AppRoles.ADMIN, AppRoles.BASIC_USER}) @Get("/:id/:date") - HelloDto hello(int id, LocalDate date, String otherParam) { - return new HelloDto(id, date.toString(), otherParam); + WebHelloDto hello(int id, LocalDate date, String otherParam) { + return new WebHelloDto(id, date.toString(), otherParam); } /** @@ -77,7 +77,7 @@ HelloDto hello(int id, LocalDate date, String otherParam) { */ @Roles(AppRoles.ADMIN) @Get("/findbyname/{name}") - List findByName(String name, @QueryParam("my-param") @Default("one") String myParam) { + List findByName(String name, @QueryParam("my-param") @Default("one") String myParam) { return new ArrayList<>(); } @@ -86,7 +86,7 @@ List findByName(String name, @QueryParam("my-param") @Default("one") S */ @Produces(MediaType.APPLICATION_JSON_PATCH_JSON) @Post - HelloDto post(HelloDto dto) { + WebHelloDto post(WebHelloDto dto) { dto.name = "posted"; return dto; } @@ -99,7 +99,7 @@ HelloDto post(HelloDto dto) { */ // @Roles({ADMIN}) @Post("/savebean/:foo") - void saveBean(String foo, HelloDto dto, Context context) { + void saveBean(String foo, WebHelloDto dto, Context context) { // save hello data ... System.out.println("save " + foo + " dto:" + dto); requireNonNull(foo); @@ -130,8 +130,8 @@ void saveForm2(String name, String email, String url) { @Post("saveform3") @Form - HelloDto saveForm3(HelloForm helloForm) { - return new HelloDto(52, helloForm.name, helloForm.email); + WebHelloDto saveForm3(HelloForm helloForm) { + return new WebHelloDto(52, helloForm.name, helloForm.email); } @Produces("text/plain") @@ -142,25 +142,10 @@ String getGetBeanForm(@BeanParam GetBeanForm bean) { @Hidden @Get - List getAll() { + List getAll() { return myService.findAll(); } - @Get("/async") - CompletableFuture> getAllAsync() { - return CompletableFuture.supplyAsync(() -> { - // Simulate a delay as if an actual IO operation is being executed. - // This also helps ensure that we aren't just getting lucky with timings. - try { - Thread.sleep(10L); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } - - return myService.findAll(); - }, Executors.newSingleThreadExecutor()); // Example of how to use a custom executor. - } - // @Hidden @Delete(":id") void deleteById(int id) { diff --git a/tests/test-jex/src/main/java/org/example/web/myapp/HelloDto.java b/tests/test-jex/src/main/java/org/example/web/myapp/WebHelloDto.java similarity index 87% rename from tests/test-jex/src/main/java/org/example/web/myapp/HelloDto.java rename to tests/test-jex/src/main/java/org/example/web/myapp/WebHelloDto.java index 3474c6c63..72a076271 100644 --- a/tests/test-jex/src/main/java/org/example/web/myapp/HelloDto.java +++ b/tests/test-jex/src/main/java/org/example/web/myapp/WebHelloDto.java @@ -5,7 +5,7 @@ import io.avaje.jsonb.Json; @Json -public class HelloDto { +public class WebHelloDto { public int id; /** @@ -20,7 +20,7 @@ public class HelloDto { private Instant whenAction; - public HelloDto(int id, String name, String otherParam) { + public WebHelloDto(int id, String name, String otherParam) { this.id = id; this.name = name; this.otherParam = otherParam; @@ -29,7 +29,7 @@ public HelloDto(int id, String name, String otherParam) { /** * Jackson constructor. */ - public HelloDto() { + public WebHelloDto() { } public UUID getGid() { diff --git a/tests/test-jex/src/main/java/org/example/web/myapp/service/MyService.java b/tests/test-jex/src/main/java/org/example/web/myapp/service/MyService.java index 3021fb4cc..54201a27c 100644 --- a/tests/test-jex/src/main/java/org/example/web/myapp/service/MyService.java +++ b/tests/test-jex/src/main/java/org/example/web/myapp/service/MyService.java @@ -3,18 +3,18 @@ import java.util.ArrayList; import java.util.List; -import org.example.web.myapp.HelloDto; +import org.example.web.myapp.WebHelloDto; import jakarta.inject.Singleton; @Singleton public class MyService { - public List findAll() { + public List findAll() { - List list = new ArrayList<>(); - list.add(new HelloDto(12, "Jim", "asd")); - list.add(new HelloDto(13, "Spock", "456456")); + List list = new ArrayList<>(); + list.add(new WebHelloDto(12, "Jim", "asd")); + list.add(new WebHelloDto(13, "Spock", "456456")); return list; } diff --git a/tests/test-jex/src/main/resources/public/openapi.json b/tests/test-jex/src/main/resources/public/openapi.json index c80b60f6a..14d428f96 100644 --- a/tests/test-jex/src/main/resources/public/openapi.json +++ b/tests/test-jex/src/main/resources/public/openapi.json @@ -373,7 +373,7 @@ "content" : { "application/json" : { "schema" : { - "$ref" : "#/components/schemas/HelloDto" + "$ref" : "#/components/schemas/WebHelloDto" } } }, @@ -385,31 +385,7 @@ "content" : { "application/json-patch+json" : { "schema" : { - "$ref" : "#/components/schemas/HelloDto" - } - } - } - } - } - } - }, - "/hello/async" : { - "get" : { - "tags" : [ - - ], - "summary" : "", - "description" : "", - "responses" : { - "200" : { - "description" : "", - "content" : { - "application/json" : { - "schema" : { - "type" : "array", - "items" : { - "$ref" : "#/components/schemas/HelloDto" - } + "$ref" : "#/components/schemas/WebHelloDto" } } } @@ -471,7 +447,7 @@ "schema" : { "type" : "array", "items" : { - "$ref" : "#/components/schemas/HelloDto" + "$ref" : "#/components/schemas/WebHelloDto" } } } @@ -559,7 +535,7 @@ "content" : { "application/json" : { "schema" : { - "$ref" : "#/components/schemas/HelloDto" + "$ref" : "#/components/schemas/WebHelloDto" } } }, @@ -654,7 +630,7 @@ "content" : { "application/json" : { "schema" : { - "$ref" : "#/components/schemas/HelloDto" + "$ref" : "#/components/schemas/WebHelloDto" } } } @@ -948,7 +924,7 @@ "content" : { "application/json" : { "schema" : { - "$ref" : "#/components/schemas/HelloDto" + "$ref" : "#/components/schemas/WebHelloDto" } } } @@ -1431,6 +1407,32 @@ }, "Object" : { "type" : "object" + }, + "WebHelloDto" : { + "type" : "object", + "properties" : { + "id" : { + "type" : "integer", + "format" : "int32", + "nullable" : false + }, + "name" : { + "type" : "string", + "description" : "This is a comment" + }, + "otherParam" : { + "type" : "string", + "description" : "This is a comment" + }, + "gid" : { + "type" : "string", + "format" : "uuid" + }, + "whenAction" : { + "type" : "string", + "format" : "date-time" + } + } } } } From da4431eda8f844963dd00f9ccc1714a9737ea9b2 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Mon, 2 Dec 2024 23:00:11 +1300 Subject: [PATCH 1185/1323] [jex generation] fix newline in generated code (#523) --- .../generator/jex/ControllerMethodWriter.java | 4 ++-- .../org/example/web/ContentController.java | 11 ++++++----- .../org/example/web/template/ViewPartial.java | 12 ++++++++++++ .../src/main/resources/public/openapi.json | 19 ++++++++++++++++--- .../resources/ui/fragments/layout.mustache | 1 - .../src/main/resources/ui/home.mustache | 8 +++----- .../src/main/resources/ui/name.mustache | 6 ------ .../src/main/resources/ui/partial.mustache | 1 + 8 files changed, 40 insertions(+), 22 deletions(-) create mode 100644 tests/test-jex/src/main/java/org/example/web/template/ViewPartial.java delete mode 100644 tests/test-jex/src/main/resources/ui/name.mustache create mode 100644 tests/test-jex/src/main/resources/ui/partial.mustache diff --git a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java index 9c3d0b7b3..a1c3e2165 100644 --- a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java +++ b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java @@ -256,7 +256,6 @@ private void write(boolean requestScoped) { } else { writer.append(indent); writeContextReturn(responseMode, "result"); - writer.eol(); } if (includeNoContent) { writer.append(" }").eol(); @@ -268,7 +267,7 @@ private void writeContextReturn(ResponseMode responseMode, String resultVariable final UType type = UType.parse(method.returnType()); if ("java.util.concurrent.CompletableFuture".equals(type.mainType())) { logError(method.element(), "CompletableFuture is not a supported return type."); - writer.append("; //ERROR"); + writer.append("; //ERROR").eol(); return; } @@ -280,6 +279,7 @@ private void writeContextReturn(ResponseMode responseMode, String resultVariable case Templating -> writer.append("ctx.html(%s);", resultVariable); default -> writer.append("ctx.contentType(\"%s\").write(%s);", produces, resultVariable); } + writer.eol(); } private void writeJsonReturn(String produces) { diff --git a/tests/test-jex/src/main/java/org/example/web/ContentController.java b/tests/test-jex/src/main/java/org/example/web/ContentController.java index 86ebac2e1..4839b1437 100644 --- a/tests/test-jex/src/main/java/org/example/web/ContentController.java +++ b/tests/test-jex/src/main/java/org/example/web/ContentController.java @@ -6,21 +6,22 @@ import io.avaje.http.api.Get; import io.avaje.http.api.Path; import org.example.web.template.ViewHome; +import org.example.web.template.ViewPartial; @Controller @Html @Path("ui") public class ContentController { + @HxRequest @Get - Object index() { - return new ViewHome("Hi"); + ViewPartial indexHxPartial() { + return new ViewPartial("Rob"); } - @HxRequest @Get - Object indexHxReqest() { - return new ViewHome("Hi"); + ViewHome index() { + return new ViewHome("Hi"); } } diff --git a/tests/test-jex/src/main/java/org/example/web/template/ViewPartial.java b/tests/test-jex/src/main/java/org/example/web/template/ViewPartial.java new file mode 100644 index 000000000..e13474dc2 --- /dev/null +++ b/tests/test-jex/src/main/java/org/example/web/template/ViewPartial.java @@ -0,0 +1,12 @@ +package org.example.web.template; + +import io.jstach.jstache.JStache; + +@JStache(path = "partial") +public class ViewPartial { + public final String name; + + public ViewPartial(String name) { + this.name = name; + } +} diff --git a/tests/test-jex/src/main/resources/public/openapi.json b/tests/test-jex/src/main/resources/public/openapi.json index 14d428f96..08606d29d 100644 --- a/tests/test-jex/src/main/resources/public/openapi.json +++ b/tests/test-jex/src/main/resources/public/openapi.json @@ -1280,7 +1280,7 @@ "content" : { "text/html;charset=UTF8" : { "schema" : { - "$ref" : "#/components/schemas/Object" + "$ref" : "#/components/schemas/ViewHome" } } } @@ -1405,8 +1405,21 @@ } } }, - "Object" : { - "type" : "object" + "ViewHome" : { + "type" : "object", + "properties" : { + "name" : { + "type" : "string" + } + } + }, + "ViewPartial" : { + "type" : "object", + "properties" : { + "name" : { + "type" : "string" + } + } }, "WebHelloDto" : { "type" : "object", diff --git a/tests/test-jex/src/main/resources/ui/fragments/layout.mustache b/tests/test-jex/src/main/resources/ui/fragments/layout.mustache index 26a8c9e85..2d04ac9a8 100644 --- a/tests/test-jex/src/main/resources/ui/fragments/layout.mustache +++ b/tests/test-jex/src/main/resources/ui/fragments/layout.mustache @@ -5,7 +5,6 @@ -

    Heading

    {{$body}}Empty body{{/body}} diff --git a/tests/test-jex/src/main/resources/ui/home.mustache b/tests/test-jex/src/main/resources/ui/home.mustache index af4686584..5bcd3e6c0 100644 --- a/tests/test-jex/src/main/resources/ui/home.mustache +++ b/tests/test-jex/src/main/resources/ui/home.mustache @@ -1,8 +1,6 @@ {{ - Hi there {{ name }} - - +{{$body}} + +
    placeholder
    {{/body}} {{/fragments/layout}} diff --git a/tests/test-jex/src/main/resources/ui/name.mustache b/tests/test-jex/src/main/resources/ui/name.mustache deleted file mode 100644 index 4c2f0f851..000000000 --- a/tests/test-jex/src/main/resources/ui/name.mustache +++ /dev/null @@ -1,6 +0,0 @@ -
    -Yond {{ name }} its {{ when }} !! and {{ more }} sad - {{#mlist}} - in {{.}} ot - {{/mlist}} -
    diff --git a/tests/test-jex/src/main/resources/ui/partial.mustache b/tests/test-jex/src/main/resources/ui/partial.mustache new file mode 100644 index 000000000..b593aa7ff --- /dev/null +++ b/tests/test-jex/src/main/resources/ui/partial.mustache @@ -0,0 +1 @@ +

    Hi {{ name }}!!

    From ab436b6530762b8be47cfe91b75f9ee085ec820d Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Mon, 2 Dec 2024 23:07:59 +1300 Subject: [PATCH 1186/1323] Version 2.9-RC3 --- htmx-api/pom.xml | 2 +- htmx-nima-jstache/pom.xml | 2 +- htmx-nima/pom.xml | 4 ++-- http-api-javalin/pom.xml | 2 +- http-api/pom.xml | 2 +- http-client-gson-adapter/pom.xml | 4 ++-- http-client-moshi-adapter/pom.xml | 4 ++-- http-client/pom.xml | 2 +- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 2 +- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-generator-sigma/pom.xml | 2 +- http-inject-plugin/pom.xml | 2 +- pom.xml | 4 ++-- tests/pom.xml | 2 +- tests/test-client-generation/pom.xml | 2 +- tests/test-client/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-htmx/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- tests/test-sigma/pom.xml | 2 +- 26 files changed, 30 insertions(+), 30 deletions(-) diff --git a/htmx-api/pom.xml b/htmx-api/pom.xml index 100749cfa..38a88d75f 100644 --- a/htmx-api/pom.xml +++ b/htmx-api/pom.xml @@ -6,7 +6,7 @@ io.avaje avaje-http-parent - 2.9-RC2 + 2.9-RC3 avaje-htmx-api diff --git a/htmx-nima-jstache/pom.xml b/htmx-nima-jstache/pom.xml index 74558d19b..f58c100e3 100644 --- a/htmx-nima-jstache/pom.xml +++ b/htmx-nima-jstache/pom.xml @@ -6,7 +6,7 @@ io.avaje avaje-http-parent - 2.9-RC2 + 2.9-RC3 avaje-htmx-nima-jstache diff --git a/htmx-nima/pom.xml b/htmx-nima/pom.xml index 86853da21..5c4866e9a 100644 --- a/htmx-nima/pom.xml +++ b/htmx-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje avaje-http-parent - 2.9-RC2 + 2.9-RC3 avaje-htmx-nima @@ -21,7 +21,7 @@ io.avaje avaje-htmx-api - 2.9-RC2 + 2.9-RC3 io.helidon.webserver diff --git a/http-api-javalin/pom.xml b/http-api-javalin/pom.xml index e9ccf7bb2..722def0b0 100644 --- a/http-api-javalin/pom.xml +++ b/http-api-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.9-RC2 + 2.9-RC3 .. diff --git a/http-api/pom.xml b/http-api/pom.xml index 68f347a09..e30a3231b 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.9-RC2 + 2.9-RC3 .. diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index 3d97d4233..7def44ff4 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.9-RC2 + 2.9-RC3 avaje-http-client-gson @@ -20,7 +20,7 @@ io.avaje avaje-http-client - 2.9-RC2 + 2.9-RC3 provided diff --git a/http-client-moshi-adapter/pom.xml b/http-client-moshi-adapter/pom.xml index 51cfad5c7..065afcf0e 100644 --- a/http-client-moshi-adapter/pom.xml +++ b/http-client-moshi-adapter/pom.xml @@ -3,7 +3,7 @@ io.avaje avaje-http-parent - 2.9-RC2 + 2.9-RC3 avaje-http-client-moshi @@ -19,7 +19,7 @@ io.avaje avaje-http-client - 2.9-RC2 + 2.9-RC3 provided diff --git a/http-client/pom.xml b/http-client/pom.xml index 40e1c45ea..77e8aa01c 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.9-RC2 + 2.9-RC3 avaje-http-client diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index 9868b1713..e403993b8 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.9-RC2 + 2.9-RC3 avaje-http-client-generator diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 06a65263b..17bd0da48 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.9-RC2 + 2.9-RC3 avaje-http-generator-core diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index 4c5a94d0b..3324680f2 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.9-RC2 + 2.9-RC3 avaje-http-helidon-generator diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index 1ab71bddd..846c2199d 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.9-RC2 + 2.9-RC3 avaje-http-javalin-generator diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index 2335699b8..faf50ff77 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.9-RC2 + 2.9-RC3 avaje-http-jex-generator diff --git a/http-generator-sigma/pom.xml b/http-generator-sigma/pom.xml index eb47b08a0..0ea60125a 100644 --- a/http-generator-sigma/pom.xml +++ b/http-generator-sigma/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.9-RC2 + 2.9-RC3 avaje-http-sigma-generator diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index 006df8d82..10711fb82 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.9-RC2 + 2.9-RC3 .. diff --git a/pom.xml b/pom.xml index 839e311b0..24adca20a 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-parent - 2.9-RC2 + 2.9-RC3 pom @@ -23,7 +23,7 @@ 2.14.2 3.0-RC7 1.35 - 2024-11-27T10:39:59Z + 2024-12-02T10:06:23Z ${project.build.directory}${file.separator}module-info.shade
    diff --git a/tests/pom.xml b/tests/pom.xml index 4515ac310..011cf7796 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.9-RC2 + 2.9-RC3 tests diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index b7fb04adb..d7b616d35 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.9-RC2 + 2.9-RC3 test-client-generation diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index 68a4ef735..285ca6c0f 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.9-RC2 + 2.9-RC3 test-client diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index ce96a280c..67d99ec5c 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 2.9-RC2 + 2.9-RC3 test-javalin-jsonb diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index b2df30de6..ac3ad533e 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.9-RC2 + 2.9-RC3 test-javalin diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index f8552f2ca..2b5084722 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.9-RC2 + 2.9-RC3 test-jex diff --git a/tests/test-nima-htmx/pom.xml b/tests/test-nima-htmx/pom.xml index 0d912fd47..cdc3474a8 100644 --- a/tests/test-nima-htmx/pom.xml +++ b/tests/test-nima-htmx/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.9-RC2 + 2.9-RC3 test-nima-htmx diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index f518a528e..6222cb1db 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.9-RC2 + 2.9-RC3 test-nima-jsonb diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index ec4dc63f6..6c21e8edd 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.9-RC2 + 2.9-RC3 test-nima diff --git a/tests/test-sigma/pom.xml b/tests/test-sigma/pom.xml index 5e5897865..7fdc93cf6 100644 --- a/tests/test-sigma/pom.xml +++ b/tests/test-sigma/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 2.9-RC2 + 2.9-RC3 test-sigma From 57dc7965473d7d9a99894243f285edda072c8b05 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 3 Dec 2024 04:01:41 +1300 Subject: [PATCH 1187/1323] Generated $Route classes as final (#524) These can be final right? Co-authored-by: Josiah Noel <32279667+SentryMan@users.noreply.github.com> --- .../io/avaje/http/generator/helidon/nima/ControllerWriter.java | 2 +- .../java/io/avaje/http/generator/javalin/ControllerWriter.java | 2 +- .../main/java/io/avaje/http/generator/jex/ControllerWriter.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java index 1e3d75d5f..63ee0eab7 100644 --- a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java +++ b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java @@ -123,7 +123,7 @@ private void writeRoutes(List methods) { private void writeClassStart() { writer.append(AT_GENERATED).eol(); writer.append(diAnnotation()).eol(); - writer.append("public class %s$Route implements HttpFeature {", shortName).eol().eol(); + writer.append("public final class %s$Route implements HttpFeature {", shortName).eol().eol(); var controllerName = "controller"; var controllerType = shortName; diff --git a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java index 03fbbfca5..340b702e0 100644 --- a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java +++ b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java @@ -84,7 +84,7 @@ private void writeClassStart() { writer.append(AT_GENERATED).eol(); writer.append(diAnnotation()).eol(); writer - .append("public class ") + .append("public final class ") .append(shortName) .append(javalin6 ? "$Route extends AvajeJavalinPlugin {" : "$Route implements Plugin {") .eol() diff --git a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerWriter.java b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerWriter.java index 5a1027049..410bb0578 100644 --- a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerWriter.java +++ b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerWriter.java @@ -89,7 +89,7 @@ private void writeRouting(MethodReader method) { private void writeClassStart() { writer.append(AT_GENERATED).eol(); writer.append(diAnnotation()).eol(); - writer.append("public class ").append(shortName).append("$Route implements Routing.HttpService {").eol().eol(); + writer.append("public final class ").append(shortName).append("$Route implements Routing.HttpService {").eol().eol(); String controllerName = "controller"; String controllerType = shortName; From 599f55bfedd03fc7d59e487bfd97798fbeb7a26e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Dec 2024 20:41:12 +0000 Subject: [PATCH 1188/1323] Bump the dependencies group with 2 updates Bumps the dependencies group with 2 updates: [com.fasterxml.jackson.core:jackson-databind](https://github.com/FasterXML/jackson) and [io.avaje:avaje-sigma](https://github.com/avaje/avaje-sigma). Updates `com.fasterxml.jackson.core:jackson-databind` from 2.18.1 to 2.18.2 - [Commits](https://github.com/FasterXML/jackson/commits) Updates `io.avaje:avaje-sigma` from 0.2 to 0.3 - [Commits](https://github.com/avaje/avaje-sigma/commits/0.3) --- updated-dependencies: - dependency-name: com.fasterxml.jackson.core:jackson-databind dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: io.avaje:avaje-sigma dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies ... Signed-off-by: dependabot[bot] --- http-client/pom.xml | 2 +- tests/pom.xml | 2 +- tests/test-sigma/pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/http-client/pom.xml b/http-client/pom.xml index 77e8aa01c..eaabae2a1 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -29,7 +29,7 @@ com.fasterxml.jackson.core jackson-databind - 2.18.1 + 2.18.2 true diff --git a/tests/pom.xml b/tests/pom.xml index 011cf7796..aa296b045 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -14,7 +14,7 @@ true 5.11.3 3.26.3 - 2.18.1 + 2.18.2 3.0-RC7 11.0 4.1.4 diff --git a/tests/test-sigma/pom.xml b/tests/test-sigma/pom.xml index 7fdc93cf6..878371fad 100644 --- a/tests/test-sigma/pom.xml +++ b/tests/test-sigma/pom.xml @@ -28,7 +28,7 @@ io.avaje avaje-sigma - 0.2 + 0.3 From 1b587f1095a03539fe1e5c31fe836c24a6a254d7 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Mon, 2 Dec 2024 17:16:29 -0500 Subject: [PATCH 1189/1323] handle jex exceptions --- .../io/avaje/http/generator/jex/ControllerMethodWriter.java | 4 ++-- tests/pom.xml | 2 +- .../src/main/java/org/example/web/TestController.java | 3 +-- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java index a1c3e2165..e19729844 100644 --- a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java +++ b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java @@ -158,9 +158,9 @@ void writeHandler(boolean requestScoped) { if (method.isErrorMethod()) { writer.append(" private void _%s(Context ctx, %s ex) {", method.simpleName(), method.exceptionShortName()); } else if (isFilter) { - writer.append(" private void _%s(Context ctx, FilterChain chain) throws IOException {", method.simpleName()); + writer.append(" private void _%s(Context ctx, FilterChain chain) throws Exception {", method.simpleName()); } else { - writer.append(" private void _%s(Context ctx) throws IOException {", method.simpleName()); + writer.append(" private void _%s(Context ctx) throws Exception {", method.simpleName()); } writer.eol(); diff --git a/tests/pom.xml b/tests/pom.xml index aa296b045..a4a8917c4 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -15,7 +15,7 @@ 5.11.3 3.26.3 2.18.2 - 3.0-RC7 + 3.0-RC8 11.0 4.1.4 6.3.0 diff --git a/tests/test-jex/src/main/java/org/example/web/TestController.java b/tests/test-jex/src/main/java/org/example/web/TestController.java index 3625c946d..b25c6a393 100644 --- a/tests/test-jex/src/main/java/org/example/web/TestController.java +++ b/tests/test-jex/src/main/java/org/example/web/TestController.java @@ -1,6 +1,5 @@ package org.example.web; -import java.io.IOException; import java.util.Set; import io.avaje.http.api.BodyString; @@ -47,7 +46,7 @@ String strBody(@BodyString String body, Context ctx) { } @Filter - void filter(FilterChain chain) throws IOException { + void filter(FilterChain chain) throws Exception { System.err.println("do nothing lmao"); chain.proceed(); } From 5d6aca13f5e7085e7dddc8e7a36ecf138c271539 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Tue, 3 Dec 2024 02:20:06 -0500 Subject: [PATCH 1190/1323] filter chain (#526) --- .../sigma/ControllerMethodWriter.java | 38 ++++++++++++++----- .../http/generator/sigma/SigmaWebMethod.java | 21 ---------- tests/test-sigma/pom.xml | 4 +- .../myapp/web/test/TestController2.java | 3 +- 4 files changed, 32 insertions(+), 34 deletions(-) delete mode 100644 http-generator-sigma/src/main/java/io/avaje/http/generator/sigma/SigmaWebMethod.java diff --git a/http-generator-sigma/src/main/java/io/avaje/http/generator/sigma/ControllerMethodWriter.java b/http-generator-sigma/src/main/java/io/avaje/http/generator/sigma/ControllerMethodWriter.java index 787820979..cdd03ed26 100644 --- a/http-generator-sigma/src/main/java/io/avaje/http/generator/sigma/ControllerMethodWriter.java +++ b/http-generator-sigma/src/main/java/io/avaje/http/generator/sigma/ControllerMethodWriter.java @@ -14,15 +14,23 @@ class ControllerMethodWriter { private final Append writer; private final WebMethod webMethod; private final boolean instrumentContext; - private final boolean customMethod; + private final boolean isFilter; ControllerMethodWriter(MethodReader method, Append writer) { this.method = method; this.writer = writer; - final var webM = method.webMethod(); - this.webMethod = webM == CoreWebMethod.FILTER ? SigmaWebMethod.BEFORE : webM; + this.webMethod = method.webMethod(); this.instrumentContext = method.instrumentContext(); - customMethod = !(webMethod instanceof CoreWebMethod); + this.isFilter = webMethod == CoreWebMethod.FILTER; + if (isFilter) { + validateFilter(); + } + } + + private void validateFilter() { + if (method.params().stream().map(MethodParam::shortType).noneMatch("HttpFilter.FilterChain"::equals)) { + logError(method.element(), "Filters must contain a FilterChain parameter"); + } } void write() { @@ -33,7 +41,7 @@ void write() { final var params = writeParams(segments); writer.append(" "); - if (!method.isVoid() && !customMethod) { + if (!method.isVoid() && !isFilter) { writer.append("var result = "); } @@ -51,6 +59,8 @@ void write() { final var param = params.get(i); if (isAssignable2Interface(param.utype().mainType(), "java.lang.Exception")) { writer.append("ex"); + } else if ("HttpFilter.FilterChain".equals(param.shortType())) { + writer.append("chain"); } else { param.buildParamName(writer); } @@ -61,7 +71,7 @@ void write() { } writer.append(");").eol(); - if (!method.isVoid() && !customMethod) { + if (!method.isVoid() && !isFilter) { writeContextReturn(); writer.eol(); } @@ -71,15 +81,18 @@ void write() { } private void writeMethod(final String fullPath) { - if (method.isErrorMethod()) { + + if (isFilter) { + writer.append(" router.filter((ctx, chain) -> {"); + } else if (method.isErrorMethod()) { writer - .append(" router.exception(%s.class, (ex, ctx) -> {", method.exceptionShortName()) + .append(" router.exception(%s.class, (ctx, ex) -> {", method.exceptionShortName()) .eol(); } else { var methodName = webMethod.name().toLowerCase().replace("_m", "M"); writer.append(" router.%s(\"%s\", ctx -> {", methodName, fullPath).eol(); } - if (!customMethod) { + if (!isFilter) { int statusCode = method.statusCode(); if (statusCode > 0) { writer.append(" ctx.status(%d);", statusCode).eol(); @@ -95,7 +108,7 @@ private List writeParams(final PathSegments segments) { final var params = method.params(); for (final MethodParam param : params) { - if (!isAssignable2Interface(param.utype().mainType(), "java.lang.Exception")) { + if (!isExceptionOrFilterChain(param)) { param.writeCtxGet(writer, segments); } } @@ -125,4 +138,9 @@ private void writeContextReturn() { writer.append(" ctx.contentType(\"%s\").result(%s);", produces); } } + + private static boolean isExceptionOrFilterChain(MethodParam param) { + return isAssignable2Interface(param.utype().mainType(), "java.lang.Exception") + || "HttpFilter.FilterChain".equals(param.shortType()); + } } diff --git a/http-generator-sigma/src/main/java/io/avaje/http/generator/sigma/SigmaWebMethod.java b/http-generator-sigma/src/main/java/io/avaje/http/generator/sigma/SigmaWebMethod.java deleted file mode 100644 index 471b00da4..000000000 --- a/http-generator-sigma/src/main/java/io/avaje/http/generator/sigma/SigmaWebMethod.java +++ /dev/null @@ -1,21 +0,0 @@ -package io.avaje.http.generator.sigma; - -import io.avaje.http.generator.core.WebMethod; - -public enum SigmaWebMethod implements WebMethod { - BEFORE(0), - BEFORE_MATCHED(0), - AFTER(0), - AFTER_MATCHED(0); - - private final int statusCode; - - SigmaWebMethod(int statusCode) { - this.statusCode = statusCode; - } - - @Override - public int statusCode(boolean isVoid) { - return statusCode; - } -} diff --git a/tests/test-sigma/pom.xml b/tests/test-sigma/pom.xml index 878371fad..694599dee 100644 --- a/tests/test-sigma/pom.xml +++ b/tests/test-sigma/pom.xml @@ -28,7 +28,7 @@ io.avaje avaje-sigma - 0.3 + 0.4 @@ -42,7 +42,7 @@ avaje-http-api ${project.version} - + io.swagger.core.v3 swagger-annotations diff --git a/tests/test-sigma/src/main/java/org/example/myapp/web/test/TestController2.java b/tests/test-sigma/src/main/java/org/example/myapp/web/test/TestController2.java index b4b20804b..6049579b8 100644 --- a/tests/test-sigma/src/main/java/org/example/myapp/web/test/TestController2.java +++ b/tests/test-sigma/src/main/java/org/example/myapp/web/test/TestController2.java @@ -17,6 +17,7 @@ import io.avaje.http.api.Post; import io.avaje.http.api.QueryParam; import io.avaje.sigma.HttpContext; +import io.avaje.sigma.HttpFilter.FilterChain; @Path("test/") @Controller @@ -84,7 +85,7 @@ void before(String s, ServerType type, HttpContext ctx) { } @Filter - void filter(HttpContext ctx) { + void filter(HttpContext ctx, FilterChain chain) { } @Form From abb71a7bc835d4147864ebb8d9136d262051f04c Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 3 Dec 2024 22:01:33 +1300 Subject: [PATCH 1191/1323] test only - Add filter examples to ErrorController --- .../main/java/org/example/ErrorController.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/tests/test-nima-jsonb/src/main/java/org/example/ErrorController.java b/tests/test-nima-jsonb/src/main/java/org/example/ErrorController.java index 58ac93c82..b4f10dc76 100644 --- a/tests/test-nima-jsonb/src/main/java/org/example/ErrorController.java +++ b/tests/test-nima-jsonb/src/main/java/org/example/ErrorController.java @@ -2,8 +2,11 @@ import io.avaje.http.api.Controller; import io.avaje.http.api.ExceptionHandler; +import io.avaje.http.api.Filter; +import io.helidon.webserver.http.FilterChain; import io.helidon.webserver.http.ServerRequest; import io.helidon.webserver.http.ServerResponse; +import io.helidon.webserver.http.RoutingResponse; import java.util.Map; @@ -18,4 +21,18 @@ Map runEx(RuntimeException ex, ServerRequest req, ServerResponse return Map.of("err", String.valueOf(ex)); } + @Filter + void filter1(FilterChain chain, RoutingResponse res) { + chain.proceed(); + } + + @Filter + void filter2(FilterChain chain, RoutingResponse res) { + chain.proceed(); + } + + @Filter + void filter(FilterChain chain, RoutingResponse res) { + chain.proceed(); + } } From cd20f052265b1ab25d59af794f7164e6334911f4 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 3 Dec 2024 22:02:41 +1300 Subject: [PATCH 1192/1323] test only - Add generated openapi.json for test-sigma --- .../src/main/resources/public/openapi.json | 2046 +++++++++++++++++ 1 file changed, 2046 insertions(+) create mode 100644 tests/test-sigma/src/main/resources/public/openapi.json diff --git a/tests/test-sigma/src/main/resources/public/openapi.json b/tests/test-sigma/src/main/resources/public/openapi.json new file mode 100644 index 000000000..37b95ebb9 --- /dev/null +++ b/tests/test-sigma/src/main/resources/public/openapi.json @@ -0,0 +1,2046 @@ +{ + "openapi" : "3.0.1", + "info" : { + "title" : "Example service", + "description" : "Example Javalin controllers with Java and Maven", + "version" : "" + }, + "servers" : [ + { + "url" : "localhost:8080", + "description" : "local testing" + } + ], + "tags" : [ + { + "name" : "tag1", + "description" : "it's somethin" + }, + { + "name" : "tag1", + "description" : "this is added to openapi tags" + } + ], + "paths" : { + "/bars" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/bars/find/{code}" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "parameters" : [ + { + "name" : "code", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "array", + "items" : { + "$ref" : "#/components/schemas/Bar" + } + } + } + } + } + } + } + }, + "/bars/{id}" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "parameters" : [ + { + "name" : "id", + "in" : "path", + "required" : true, + "schema" : { + "type" : "integer", + "format" : "int64", + "nullable" : false + } + } + ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Bar" + } + } + } + } + } + } + }, + "/baz" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "array", + "items" : { + "$ref" : "#/components/schemas/Baz" + } + } + } + } + } + } + }, + "post" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Baz" + } + } + }, + "required" : true + }, + "responses" : { + "201" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "integer", + "format" : "int64" + } + } + } + } + } + } + }, + "/baz/checkparams/{id}" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "parameters" : [ + { + "name" : "id", + "in" : "path", + "required" : true, + "schema" : { + "type" : "integer", + "format" : "int32", + "nullable" : false + } + }, + { + "name" : "p1", + "in" : "query", + "schema" : { + "type" : "string" + } + }, + { + "name" : "p2", + "in" : "query", + "schema" : { + "type" : "number" + } + }, + { + "name" : "p3", + "in" : "query", + "schema" : { + "type" : "integer", + "format" : "int32" + } + }, + { + "name" : "p4", + "in" : "query", + "schema" : { + "type" : "number" + } + }, + { + "name" : "body", + "in" : "query", + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/baz/findbyname/{name}" : { + "get" : { + "tags" : [ + + ], + "summary" : "Find the baz by name", + "description" : "This is some more comments about this method.", + "parameters" : [ + { + "name" : "name", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "description" : "The list of baz", + "content" : { + "application/json" : { + "schema" : { + "type" : "array", + "items" : { + "$ref" : "#/components/schemas/Baz" + } + } + } + } + } + } + } + }, + "/baz/{id}" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "parameters" : [ + { + "name" : "id", + "in" : "path", + "required" : true, + "schema" : { + "type" : "integer", + "format" : "int64" + } + } + ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Baz" + } + } + } + } + } + } + }, + "/hello" : { + "post" : { + "tags" : [ + + ], + "summary" : "Simple example post with JSON body response", + "description" : "", + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/HelloDto" + } + } + }, + "required" : true + }, + "responses" : { + "201" : { + "description" : "", + "content" : { + "application/json-patch+json" : { + "schema" : { + "$ref" : "#/components/schemas/HelloDto" + } + } + } + } + } + } + }, + "/hello/async" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "array", + "items" : { + "$ref" : "#/components/schemas/HelloDto" + } + } + } + } + } + } + } + }, + "/hello/controlStatusCode" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/hello/findbyname/{name}" : { + "get" : { + "tags" : [ + + ], + "summary" : "Find Hellos by name", + "description" : "", + "parameters" : [ + { + "name" : "name", + "in" : "path", + "description" : "The name to search for", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "name" : "myParam", + "in" : "query", + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "description" : "The Hellos that we found.", + "content" : { + "application/json" : { + "schema" : { + "type" : "array", + "items" : { + "$ref" : "#/components/schemas/HelloDto" + } + } + } + } + } + } + } + }, + "/hello/message" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/hello/mySave" : { + "post" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "requestBody" : { + "content" : { + "application/x-www-form-urlencoded" : { + "schema" : { + "type" : "object", + "properties" : { + "name" : { + "type" : "string" + }, + "email" : { + "type" : "string" + }, + "url" : { + "type" : "string" + } + } + } + } + }, + "required" : true + }, + "responses" : { + "201" : { + "description" : "No content" + } + } + } + }, + "/hello/savebean/{foo}" : { + "post" : { + "tags" : [ + + ], + "summary" : "Save the hello using json body", + "description" : "", + "parameters" : [ + { + "name" : "foo", + "in" : "path", + "description" : "The hello doo id", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "requestBody" : { + "description" : "The hello body as json", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/HelloDto" + } + } + }, + "required" : true + }, + "responses" : { + "201" : { + "description" : "No content" + } + } + } + }, + "/hello/saveform" : { + "post" : { + "tags" : [ + + ], + "summary" : "Create the new Hello using a form", + "description" : "", + "requestBody" : { + "content" : { + "application/x-www-form-urlencoded" : { + "schema" : { + "$ref" : "#/components/schemas/HelloForm" + } + } + }, + "required" : true + }, + "responses" : { + "201" : { + "description" : "No content" + } + } + } + }, + "/hello/saveform2" : { + "post" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "requestBody" : { + "content" : { + "application/x-www-form-urlencoded" : { + "schema" : { + "type" : "object", + "properties" : { + "name" : { + "type" : "string" + }, + "email" : { + "type" : "string" + }, + "url" : { + "type" : "string" + } + } + } + } + }, + "required" : true + }, + "responses" : { + "201" : { + "description" : "No content" + } + } + } + }, + "/hello/saveform3" : { + "post" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "requestBody" : { + "content" : { + "application/x-www-form-urlencoded" : { + "schema" : { + "$ref" : "#/components/schemas/HelloForm" + } + } + }, + "required" : true + }, + "responses" : { + "201" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/HelloDto" + } + } + } + } + } + } + }, + "/hello/slash/{name}//other/" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "parameters" : [ + { + "name" : "name", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "name" : "nam0", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "name" : "nam1", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/hello/takesNestedEnum" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "parameters" : [ + { + "name" : "myEnum", + "in" : "query", + "schema" : { + "type" : "string", + "enum" : [ + "A", + "B", + "C" + ] + } + } + ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/hello/withMatrix/{year_segment}/{other}" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "parameters" : [ + { + "name" : "year", + "in" : "path", + "required" : true, + "schema" : { + "type" : "integer", + "format" : "int32", + "nullable" : false + } + }, + { + "name" : "author", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "name" : "country", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "name" : "other", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "name" : "extra", + "in" : "query", + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/hello/withValidBean" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "parameters" : [ + { + "name" : "name", + "in" : "query", + "schema" : { + "type" : "string", + "nullable" : false + } + }, + { + "name" : "email", + "in" : "query", + "schema" : { + "type" : "string" + } + }, + { + "name" : "addresses", + "in" : "query", + "schema" : { + "type" : "array", + "items" : { + "type" : "string" + } + } + }, + { + "name" : "head", + "in" : "header", + "schema" : { + "type" : "string" + } + }, + { + "name" : "type", + "in" : "query", + "schema" : { + "type" : "array", + "items" : { + "type" : "string", + "enum" : [ + "PROXY", + "HIDE_N_SEEK", + "FFA" + ] + } + } + } + ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/hello/{id}" : { + "delete" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "parameters" : [ + { + "name" : "id", + "in" : "path", + "required" : true, + "schema" : { + "type" : "integer", + "format" : "int32", + "nullable" : false + } + } + ], + "responses" : { + "204" : { + "description" : "No content" + } + } + } + }, + "/hello/{id}/{date}" : { + "get" : { + "tags" : [ + + ], + "summary" : "Return the Hello DTO", + "description" : "", + "parameters" : [ + { + "name" : "id", + "in" : "path", + "description" : "The hello Id.", + "required" : true, + "schema" : { + "type" : "integer", + "format" : "int32", + "nullable" : false + } + }, + { + "name" : "date", + "in" : "path", + "description" : "The name of the hello", + "required" : true, + "schema" : { + "type" : "string", + "format" : "date" + } + }, + { + "name" : "otherParam", + "in" : "query", + "description" : "Optional other parameter", + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "description" : "Return the Hello DTO.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/HelloDto" + } + } + } + } + }, + "deprecated" : true + } + }, + "/javalin/health" : { + "get" : { + "tags" : [ + "tag1" + ], + "summary" : "Standard Get", + "description" : "", + "responses" : { + "500" : { + "description" : "a health check", + "content" : { + "text/plain" : { + "schema" : { + "$ref" : "#/components/schemas/ErrorResponse" + } + } + } + }, + "403" : { + "description" : "Not Authorized" + }, + "200" : { + "description" : "a health check", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/openapi/get" : { + "get" : { + "tags" : [ + + ], + "summary" : "Example of Open API Get (up to the first period is the summary)", + "description" : "When using Javalin HttpContext only This Javadoc description is added to the generated openapi.json", + "responses" : { + "200" : { + "description" : "funny phrase (this part of the javadoc is added to the response desc)", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/openapi/post" : { + "post" : { + "tags" : [ + "tag1" + ], + "summary" : "Standard Post", + "description" : "uses tag annotation to add tags to openapi json", + "requestBody" : { + "description" : "the body (this is used for generated request body desc)", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Person" + } + } + }, + "required" : true + }, + "responses" : { + "200" : { + "description" : "overrides @return javadoc description", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Person" + } + } + } + }, + "201" : { + "description" : "the response body (from javadoc)", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Person" + } + } + } + }, + "400" : { + "description" : "User not found (Will not have an associated response schema)" + }, + "500" : { + "description" : "Some other Error (Will have this error class as the response class)", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ErrorResponse" + } + } + } + } + } + } + }, + "/openapi/post1" : { + "post" : { + "tags" : [ + + ], + "summary" : "Standard Post", + "description" : "The Deprecated annotation adds \"deprecacted:true\" to the generated json", + "requestBody" : { + "description" : "the body", + "content" : { + "application/json" : { + "schema" : { + "type" : "array", + "items" : { + "$ref" : "#/components/schemas/Person" + } + } + } + }, + "required" : true + }, + "responses" : { + "400" : { + "description" : "User not found" + }, + "500" : { + "description" : "Some other Error", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ErrorResponse" + } + } + } + }, + "201" : { + "description" : "the response body (from javadoc)", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Person" + } + } + } + } + }, + "deprecated" : true + } + }, + "/openapi/put" : { + "put" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "responses" : { + "204" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + }, + "203" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/security/first" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "string" + } + } + } + } + }, + "security" : [ + { + "JWT" : [ + + ] + } + ] + } + }, + "/security/second" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/test" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/test/async" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/HelloDto" + } + } + } + } + } + } + }, + "/test/ctx" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "No content" + } + } + } + }, + "/test/enumForm" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "requestBody" : { + "content" : { + "application/x-www-form-urlencoded" : { + "schema" : { + "type" : "object", + "properties" : { + "s" : { + "type" : "string" + }, + "type" : { + "type" : "string", + "enum" : [ + "PROXY", + "HIDE_N_SEEK", + "FFA" + ] + } + } + } + } + }, + "required" : true + }, + "responses" : { + "200" : { + "description" : "No content" + } + } + } + }, + "/test/enumFormParam" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "requestBody" : { + "content" : { + "application/x-www-form-urlencoded" : { + "schema" : { + "type" : "object", + "properties" : { + "s" : { + "type" : "string" + }, + "type" : { + "type" : "string", + "enum" : [ + "PROXY", + "HIDE_N_SEEK", + "FFA" + ] + } + } + } + } + }, + "required" : true + }, + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/test/enumPath/{type}" : { + "post" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "parameters" : [ + { + "name" : "type", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string", + "enum" : [ + "PROXY", + "HIDE_N_SEEK", + "FFA" + ] + } + } + ], + "responses" : { + "201" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/test/enumQuery" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "parameters" : [ + { + "name" : "type", + "in" : "query", + "schema" : { + "type" : "string", + "enum" : [ + "PROXY", + "HIDE_N_SEEK", + "FFA" + ] + } + } + ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/test/enumQuery2" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "parameters" : [ + { + "name" : "type", + "in" : "query", + "schema" : { + "type" : "array", + "items" : { + "type" : "string", + "enum" : [ + "PROXY", + "HIDE_N_SEEK", + "FFA" + ] + } + } + } + ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/test/enumQueryImplied" : { + "post" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "parameters" : [ + { + "name" : "s", + "in" : "query", + "schema" : { + "type" : "string" + } + }, + { + "name" : "type", + "in" : "query", + "schema" : { + "type" : "string", + "enum" : [ + "PROXY", + "HIDE_N_SEEK", + "FFA" + ] + } + } + ], + "responses" : { + "201" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/test/form" : { + "post" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "requestBody" : { + "content" : { + "application/x-www-form-urlencoded" : { + "schema" : { + "type" : "object", + "properties" : { + "name" : { + "type" : "string" + }, + "email" : { + "type" : "string" + }, + "url" : { + "type" : "string" + } + } + } + } + }, + "required" : true + }, + "responses" : { + "201" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/test/formBean" : { + "post" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "requestBody" : { + "content" : { + "application/x-www-form-urlencoded" : { + "schema" : { + "$ref" : "#/components/schemas/MyForm" + } + } + }, + "required" : true + }, + "responses" : { + "201" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/test/formMulti" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "requestBody" : { + "content" : { + "application/x-www-form-urlencoded" : { + "schema" : { + "type" : "object", + "properties" : { + "strings" : { + "type" : "array", + "items" : { + "type" : "string" + } + } + } + } + } + }, + "required" : true + }, + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/test/header" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "parameters" : [ + { + "name" : "head", + "in" : "header", + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/test/hey" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/test/int" : { + "put" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "integer", + "format" : "int32", + "nullable" : false + } + } + } + } + } + } + }, + "/test/long" : { + "put" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "integer", + "format" : "int64", + "nullable" : false + } + } + } + } + } + } + }, + "/test/person" : { + "post" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Person" + } + } + }, + "required" : true + }, + "responses" : { + "201" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Person" + } + } + } + } + } + } + }, + "/test/person/update" : { + "put" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "type" : "array", + "items" : { + "$ref" : "#/components/schemas/Person" + } + } + } + }, + "required" : true + }, + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/test/person/{name}" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "parameters" : [ + { + "name" : "name", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Person" + } + } + } + } + } + } + }, + "/test/person/{sortBy}/list" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "parameters" : [ + { + "name" : "sortBy", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "array", + "items" : { + "$ref" : "#/components/schemas/Person" + } + } + } + } + } + } + } + }, + "/test/person/{sortBy}/map" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "parameters" : [ + { + "name" : "sortBy", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "object", + "additionalProperties" : { + "$ref" : "#/components/schemas/Person" + } + } + } + } + } + } + } + }, + "/test/person/{sortBy}/set" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "parameters" : [ + { + "name" : "sortBy", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "array", + "items" : { + "$ref" : "#/components/schemas/Person" + } + } + } + } + } + } + } + }, + "/test/strBody" : { + "post" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "requestBody" : { + "content" : { + "application/text" : { + "schema" : { + "type" : "string" + } + } + }, + "required" : true + }, + "responses" : { + "201" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/test/withMatrixParam/{type-1_segment}/{range_segment}" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "parameters" : [ + { + "name" : "type", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "name" : "category", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "name" : "vendor", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "name" : "range", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "name" : "style", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "description" : "No content" + } + } + } + } + }, + "components" : { + "schemas" : { + "Bar" : { + "type" : "object", + "properties" : { + "id" : { + "type" : "integer", + "format" : "int64", + "nullable" : false + }, + "name" : { + "type" : "string" + } + } + }, + "Baz" : { + "type" : "object", + "properties" : { + "id" : { + "type" : "integer", + "format" : "int64" + }, + "name" : { + "type" : "string" + }, + "startDate" : { + "type" : "string", + "format" : "date" + } + } + }, + "ErrorResponse" : { + "type" : "object", + "properties" : { + "id" : { + "type" : "string" + }, + "text" : { + "type" : "string" + } + } + }, + "HelloDto" : { + "type" : "object", + "properties" : { + "id" : { + "type" : "integer", + "format" : "int32", + "nullable" : false + }, + "name" : { + "type" : "string", + "description" : "This is a comment" + }, + "otherParam" : { + "type" : "string", + "description" : "This is a comment" + }, + "gid" : { + "type" : "string", + "format" : "uuid" + }, + "whenAction" : { + "type" : "string", + "format" : "date-time" + } + } + }, + "HelloForm" : { + "required" : [ + "name" + ], + "type" : "object", + "properties" : { + "name" : { + "type" : "string", + "nullable" : false + }, + "email" : { + "type" : "string" + }, + "url" : { + "type" : "string" + }, + "startDate" : { + "type" : "string", + "format" : "date" + } + } + }, + "MyForm" : { + "type" : "object", + "properties" : { + "name" : { + "type" : "string" + }, + "email" : { + "type" : "string" + }, + "url" : { + "type" : "string" + } + } + }, + "Person" : { + "type" : "object", + "properties" : { + "id" : { + "type" : "integer", + "format" : "int64", + "nullable" : false + }, + "name" : { + "type" : "string" + } + } + } + }, + "securitySchemes" : { + "JWT" : { + "type" : "apiKey", + "description" : "JSON Web Tokens are an open, industry standard RFC 7519 method for representing claims securely between two parties.", + "name" : "access_token", + "in" : "query" + } + } + } +} \ No newline at end of file From 658c42c2a6ce16ad3e9456492d91125e4f9cc06d Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 3 Dec 2024 22:51:09 +1300 Subject: [PATCH 1193/1323] [Jex generation] Raw JSON String handling in generated code (#528) JSON response method that returns a Java String is deemed to be raw json (rather than json encoding the string content) --- .../generator/jex/ControllerMethodWriter.java | 12 ++++++---- .../java/org/example/web/HelloController.java | 6 +++++ .../src/main/resources/public/openapi.json | 23 ++++++++++++++++++- .../org/example/web/HelloControllerTest.java | 21 +++++++++++++++++ 4 files changed, 57 insertions(+), 5 deletions(-) diff --git a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java index e19729844..1b9cd1667 100644 --- a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java +++ b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java @@ -283,11 +283,15 @@ private void writeContextReturn(ResponseMode responseMode, String resultVariable } private void writeJsonReturn(String produces) { + if (produces == null) { + produces = MediaType.APPLICATION_JSON.getValue(); + } + var uType = UType.parse(method.returnType()); + if ("java.lang.String".equals(method.returnType().toString())) { + writer.append("ctx.contentType(\"%s\").write(result); // raw json", produces); + return; + } if (useJsonB) { - var uType = UType.parse(method.returnType()); - if (produces == null) { - produces = MediaType.APPLICATION_JSON.getValue(); - } writer.append( "%sJsonType.toJson(result, ctx.contentType(\"%s\").outputStream());", uType.shortName(), produces); diff --git a/tests/test-jex/src/main/java/org/example/web/HelloController.java b/tests/test-jex/src/main/java/org/example/web/HelloController.java index 9745b9e32..899acb8f3 100644 --- a/tests/test-jex/src/main/java/org/example/web/HelloController.java +++ b/tests/test-jex/src/main/java/org/example/web/HelloController.java @@ -61,8 +61,14 @@ void put(HelloDto dto) { dto.hashCode(); } + @Produces("text/plain") @Get("/bigInt/{val}") String testBigInt(BigInteger val) { return "hi|" + val; } + + @Get("rawJson") + String rawJsonString() { + return "{\"key\": 42 }"; + } } diff --git a/tests/test-jex/src/main/resources/public/openapi.json b/tests/test-jex/src/main/resources/public/openapi.json index 08606d29d..b747803d2 100644 --- a/tests/test-jex/src/main/resources/public/openapi.json +++ b/tests/test-jex/src/main/resources/public/openapi.json @@ -352,7 +352,7 @@ "200" : { "description" : "", "content" : { - "application/json" : { + "text/plain" : { "schema" : { "type" : "string" } @@ -985,6 +985,27 @@ } } }, + "/rawJson" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, "/security/first" : { "get" : { "tags" : [ diff --git a/tests/test-jex/src/test/java/org/example/web/HelloControllerTest.java b/tests/test-jex/src/test/java/org/example/web/HelloControllerTest.java index 2493abbf5..11da4f194 100644 --- a/tests/test-jex/src/test/java/org/example/web/HelloControllerTest.java +++ b/tests/test-jex/src/test/java/org/example/web/HelloControllerTest.java @@ -53,6 +53,27 @@ void splat2() { assertEquals("got name:one splat0:a/b splat1:x/y/z", client.request().path("splat2/one/a/b/other/x/y/z").GET().asString().body()); } + @Test + void plainText() { + final HttpResponse hres = client.request() + .path("bigInt/42") + .GET().asString(); + + assertThat(hres.statusCode()).isEqualTo(200); + assertThat(hres.body()).contains("hi|42"); + } + + @Test + void rawJson() { + final HttpResponse hres = client.request() + .path("rawJson") + .GET().asString(); + + assertThat(hres.statusCode()).isEqualTo(200); + assertThat(hres.headers().firstValue("Content-Type").orElseThrow()).isEqualTo("application/json"); + assertThat(hres.body()).contains("{\"key\": 42 }"); + } + @Test void validation() { HelloDto helloDto = new HelloDto(); From 5e44ea33b16c22d6bb746f63cf7cd7156b4117ee Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 3 Dec 2024 23:02:05 +1300 Subject: [PATCH 1194/1323] Version 2.9-RC4 --- htmx-api/pom.xml | 2 +- htmx-nima-jstache/pom.xml | 2 +- htmx-nima/pom.xml | 4 ++-- http-api-javalin/pom.xml | 2 +- http-api/pom.xml | 2 +- http-client-gson-adapter/pom.xml | 4 ++-- http-client-moshi-adapter/pom.xml | 4 ++-- http-client/pom.xml | 2 +- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 2 +- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-generator-sigma/pom.xml | 2 +- http-inject-plugin/pom.xml | 2 +- pom.xml | 4 ++-- tests/pom.xml | 2 +- tests/test-client-generation/pom.xml | 2 +- tests/test-client/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-htmx/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- tests/test-sigma/pom.xml | 2 +- 26 files changed, 30 insertions(+), 30 deletions(-) diff --git a/htmx-api/pom.xml b/htmx-api/pom.xml index 38a88d75f..36f6f1a43 100644 --- a/htmx-api/pom.xml +++ b/htmx-api/pom.xml @@ -6,7 +6,7 @@ io.avaje avaje-http-parent - 2.9-RC3 + 2.9-RC4 avaje-htmx-api diff --git a/htmx-nima-jstache/pom.xml b/htmx-nima-jstache/pom.xml index f58c100e3..69ab8c84c 100644 --- a/htmx-nima-jstache/pom.xml +++ b/htmx-nima-jstache/pom.xml @@ -6,7 +6,7 @@ io.avaje avaje-http-parent - 2.9-RC3 + 2.9-RC4 avaje-htmx-nima-jstache diff --git a/htmx-nima/pom.xml b/htmx-nima/pom.xml index 5c4866e9a..2b040cc2c 100644 --- a/htmx-nima/pom.xml +++ b/htmx-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje avaje-http-parent - 2.9-RC3 + 2.9-RC4 avaje-htmx-nima @@ -21,7 +21,7 @@ io.avaje avaje-htmx-api - 2.9-RC3 + 2.9-RC4 io.helidon.webserver diff --git a/http-api-javalin/pom.xml b/http-api-javalin/pom.xml index 722def0b0..6e17606ee 100644 --- a/http-api-javalin/pom.xml +++ b/http-api-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.9-RC3 + 2.9-RC4 .. diff --git a/http-api/pom.xml b/http-api/pom.xml index e30a3231b..9b3da2e2f 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.9-RC3 + 2.9-RC4 .. diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index 7def44ff4..161bf0202 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.9-RC3 + 2.9-RC4 avaje-http-client-gson @@ -20,7 +20,7 @@ io.avaje avaje-http-client - 2.9-RC3 + 2.9-RC4 provided diff --git a/http-client-moshi-adapter/pom.xml b/http-client-moshi-adapter/pom.xml index 065afcf0e..e7652f23b 100644 --- a/http-client-moshi-adapter/pom.xml +++ b/http-client-moshi-adapter/pom.xml @@ -3,7 +3,7 @@ io.avaje avaje-http-parent - 2.9-RC3 + 2.9-RC4 avaje-http-client-moshi @@ -19,7 +19,7 @@ io.avaje avaje-http-client - 2.9-RC3 + 2.9-RC4 provided diff --git a/http-client/pom.xml b/http-client/pom.xml index eaabae2a1..bbcae8588 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.9-RC3 + 2.9-RC4 avaje-http-client diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index e403993b8..400f6c001 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.9-RC3 + 2.9-RC4 avaje-http-client-generator diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 17bd0da48..3115baafd 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.9-RC3 + 2.9-RC4 avaje-http-generator-core diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index 3324680f2..8ba0a6e61 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.9-RC3 + 2.9-RC4 avaje-http-helidon-generator diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index 846c2199d..f78eb38d9 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.9-RC3 + 2.9-RC4 avaje-http-javalin-generator diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index faf50ff77..0b49de2ff 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.9-RC3 + 2.9-RC4 avaje-http-jex-generator diff --git a/http-generator-sigma/pom.xml b/http-generator-sigma/pom.xml index 0ea60125a..e9723960f 100644 --- a/http-generator-sigma/pom.xml +++ b/http-generator-sigma/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.9-RC3 + 2.9-RC4 avaje-http-sigma-generator diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index 10711fb82..a28578a1b 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.9-RC3 + 2.9-RC4 .. diff --git a/pom.xml b/pom.xml index 24adca20a..f993838dd 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-parent - 2.9-RC3 + 2.9-RC4 pom @@ -23,7 +23,7 @@ 2.14.2 3.0-RC7 1.35 - 2024-12-02T10:06:23Z + 2024-12-03T09:51:55Z ${project.build.directory}${file.separator}module-info.shade diff --git a/tests/pom.xml b/tests/pom.xml index a4a8917c4..bf7cef1ef 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.9-RC3 + 2.9-RC4 tests diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index d7b616d35..2919f84f2 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.9-RC3 + 2.9-RC4 test-client-generation diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index 285ca6c0f..566f9a291 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.9-RC3 + 2.9-RC4 test-client diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 67d99ec5c..734636a56 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 2.9-RC3 + 2.9-RC4 test-javalin-jsonb diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index ac3ad533e..db4022953 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.9-RC3 + 2.9-RC4 test-javalin diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 2b5084722..610b84182 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.9-RC3 + 2.9-RC4 test-jex diff --git a/tests/test-nima-htmx/pom.xml b/tests/test-nima-htmx/pom.xml index cdc3474a8..09ef419a6 100644 --- a/tests/test-nima-htmx/pom.xml +++ b/tests/test-nima-htmx/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.9-RC3 + 2.9-RC4 test-nima-htmx diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 6222cb1db..67786941c 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.9-RC3 + 2.9-RC4 test-nima-jsonb diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index 6c21e8edd..0224dc461 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.9-RC3 + 2.9-RC4 test-nima diff --git a/tests/test-sigma/pom.xml b/tests/test-sigma/pom.xml index 694599dee..0d4883f3b 100644 --- a/tests/test-sigma/pom.xml +++ b/tests/test-sigma/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 2.9-RC3 + 2.9-RC4 test-sigma From 8998f3b22dcdb347ce33e2dee981d527cb4e7bbf Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Thu, 5 Dec 2024 00:40:56 -0500 Subject: [PATCH 1195/1323] [Http-Client] Use virtual thread executor by default (#442) * use virtual thread executor by default * only try if > 21 * [Http client] #442 extract helper method for newVirtualThreadPerTaskExecutor --------- Co-authored-by: Rob Bygrave --- .../avaje/http/client/DHttpClientBuilder.java | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/http-client/src/main/java/io/avaje/http/client/DHttpClientBuilder.java b/http-client/src/main/java/io/avaje/http/client/DHttpClientBuilder.java index ecb898046..72e83fb1d 100644 --- a/http-client/src/main/java/io/avaje/http/client/DHttpClientBuilder.java +++ b/http-client/src/main/java/io/avaje/http/client/DHttpClientBuilder.java @@ -16,10 +16,15 @@ import java.util.List; import java.util.Optional; import java.util.concurrent.Executor; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; import java.util.function.Function; import static java.util.Objects.requireNonNull; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; + final class DHttpClientBuilder implements HttpClient.Builder, HttpClient.Builder.State { private java.net.http.HttpClient client; @@ -99,6 +104,8 @@ private java.net.http.HttpClient defaultClient() { } if (executor != null) { builder.executor(executor); + } else if (Integer.getInteger("java.specification.version") >= 21) { + builder.executor(virtualThreadExecutor()); } if (proxy != null) { builder.proxy(proxy); @@ -118,6 +125,17 @@ private java.net.http.HttpClient defaultClient() { return builder.build(); } + private static ExecutorService virtualThreadExecutor() { + try { + return (ExecutorService) + MethodHandles.lookup() + .findStatic(Executors.class, "newVirtualThreadPerTaskExecutor", MethodType.methodType(ExecutorService.class)) + .invokeExact(); + } catch (Throwable e) { + return null; + } + } + /** * Create a reasonable default BodyAdapter if avaje-jsonb or Jackson are present. */ From 0411281fe1b3403bb0b259ee68a4c58a91b725c4 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Fri, 6 Dec 2024 11:09:54 -0500 Subject: [PATCH 1196/1323] client --- .../main/java/io/avaje/http/client/BasicAuthIntercept.java | 2 +- .../main/java/io/avaje/http/client/DHttpClientContext.java | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/http-client/src/main/java/io/avaje/http/client/BasicAuthIntercept.java b/http-client/src/main/java/io/avaje/http/client/BasicAuthIntercept.java index 7220e2d8f..4c18a33ed 100644 --- a/http-client/src/main/java/io/avaje/http/client/BasicAuthIntercept.java +++ b/http-client/src/main/java/io/avaje/http/client/BasicAuthIntercept.java @@ -5,7 +5,7 @@ import java.util.Base64; /** Adds Basic Authorization header to requests. */ -public class BasicAuthIntercept implements RequestIntercept { +public final class BasicAuthIntercept implements RequestIntercept { private final String headerValue; diff --git a/http-client/src/main/java/io/avaje/http/client/DHttpClientContext.java b/http-client/src/main/java/io/avaje/http/client/DHttpClientContext.java index 987b2a43b..64d9e3a62 100644 --- a/http-client/src/main/java/io/avaje/http/client/DHttpClientContext.java +++ b/http-client/src/main/java/io/avaje/http/client/DHttpClientContext.java @@ -11,7 +11,6 @@ import java.util.List; import java.util.Map; import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutorService; import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.LongAccumulator; import java.util.concurrent.atomic.LongAdder; @@ -21,9 +20,6 @@ final class DHttpClientContext implements HttpClient, SpiHttpClient { - /** - * HTTP Authorization header. - */ static final String AUTHORIZATION = "Authorization"; private static final String BEARER = "Bearer "; From 87fb97120e9d449bd50e6ea8919bce4cf54398b0 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Fri, 6 Dec 2024 11:33:06 -0500 Subject: [PATCH 1197/1323] update role generation --- .../generator/jex/ControllerMethodWriter.java | 15 +++++++-------- tests/pom.xml | 2 +- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java index 1b9cd1667..c55586912 100644 --- a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java +++ b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java @@ -47,33 +47,32 @@ void writeRouting() { final String fullPath = segments.fullPath(); if (method.isErrorMethod()) { - writer.append(" routing.error(%s.class, this::_%s)", method.exceptionShortName(), method.simpleName()); + writer.append(" routing.error(%s.class, this::_%s", method.exceptionShortName(), method.simpleName()); } else if (isFilter) { - writer.append(" routing.filter(this::_%s)", method.simpleName()); + writer.append(" routing.filter(this::_%s", method.simpleName()); } else { writer.append(" routing.%s(\"%s\", ", webMethod.name().toLowerCase(), fullPath); var hxRequest = method.hxRequest(); if (hxRequest != null) { writeHxHandler(hxRequest); } else { - writer.append("this::_%s)", method.simpleName()); + writer.append("this::_%s", method.simpleName()); } } writeRoles(); - writer.append(";").eol(); + writer.append(");").eol(); } private void writeRoles() { List roles = method.roles(); - if (!roles.isEmpty()) { - writer.append(".withRoles("); + if (!roles.isEmpty() && !isFilter) { + writer.append(", "); for (int i = 0; i < roles.size(); i++) { if (i > 0) { writer.append(", "); } writer.append(Util.shortName(roles.get(i), true)); } - writer.append(")"); } } @@ -92,7 +91,7 @@ private void writeHxHandler(HxRequestPrism hxRequest) { } else if (hasValue(hxRequest.value())) { writer.append(".triggerName(\"%s\")", hxRequest.value()); } - writer.append(".build())"); + writer.append(".build()"); } private static boolean hasValue(String value) { diff --git a/tests/pom.xml b/tests/pom.xml index bf7cef1ef..244a0b4f9 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -15,7 +15,7 @@ 5.11.3 3.26.3 2.18.2 - 3.0-RC8 + 3.0-RC10 11.0 4.1.4 6.3.0 From 4b060908721d58a551aa4b20f60c86030ed7d782 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sat, 7 Dec 2024 23:45:45 -0500 Subject: [PATCH 1198/1323] Update JexAdapter.java --- .../main/java/io/avaje/http/generator/jex/JexAdapter.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/JexAdapter.java b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/JexAdapter.java index 3ed2e3df8..730fd52f6 100644 --- a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/JexAdapter.java +++ b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/JexAdapter.java @@ -7,6 +7,7 @@ import io.avaje.http.generator.core.ControllerReader; import io.avaje.http.generator.core.ParamType; import io.avaje.http.generator.core.PlatformAdapter; +import io.avaje.http.generator.core.ProcessingContext; import io.avaje.http.generator.core.UType; class JexAdapter implements PlatformAdapter { @@ -32,13 +33,14 @@ public boolean isBodyMethodParam() { public String bodyAsClass(UType type) { if ("java.io.InputStream".equals(type.full())) { - return "ctx.bodyInputStream()"; + return "ctx.bodyAsInputStream()"; } else if ("java.lang.String".equals(type.full())) { return "ctx.body()"; } else if ("byte[]".equals(type.full())) { return "ctx.bodyAsBytes()"; + } else if (ProcessingContext.useJsonb()) { + return type.shortName() + "JsonType.fromJson(ctx.bodyAsInputStream())"; } - return "ctx.bodyAsClass(" + type.mainType() + ".class)"; } From 082f3bd12473da71f26035f4188a65a29bce7ea5 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sat, 7 Dec 2024 23:54:35 -0500 Subject: [PATCH 1199/1323] specified roles override controller level --- .../java/io/avaje/http/generator/core/MethodReader.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java index d427b57b9..b51abc302 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java @@ -338,7 +338,9 @@ public void buildApiDocumentation() { public List roles() { final var roles = new ArrayList<>(methodRoles); - roles.addAll(bean.roles()); + if (roles.isEmpty()) { + roles.addAll(bean.roles()); + } return roles; } @@ -521,7 +523,7 @@ private List namedSegments() { private boolean allArgParamNames() { for (int i = 0; i < params.size(); i++) { - if (!params.get(i).name().equals("arg" + i)) { + if (!("arg" + i).equals(params.get(i).name())) { return false; } } From 926004c222ea21e3bc02baac1ef32de17fcc2ec1 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Mon, 9 Dec 2024 08:42:40 +1300 Subject: [PATCH 1200/1323] Bump prisms and jex dependency versions --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index f993838dd..28640c3cc 100644 --- a/pom.xml +++ b/pom.xml @@ -21,8 +21,8 @@ true 2.2.26 2.14.2 - 3.0-RC7 - 1.35 + 3.0-RC10 + 1.36 2024-12-03T09:51:55Z ${project.build.directory}${file.separator}module-info.shade From aea8623dd19acb3437dbcd7d9ebec2a3d95ccbd8 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Mon, 9 Dec 2024 08:57:13 +1300 Subject: [PATCH 1201/1323] Version 2.9-RC5 --- htmx-api/pom.xml | 2 +- htmx-nima-jstache/pom.xml | 2 +- htmx-nima/pom.xml | 4 ++-- http-api-javalin/pom.xml | 2 +- http-api/pom.xml | 2 +- http-client-gson-adapter/pom.xml | 4 ++-- http-client-moshi-adapter/pom.xml | 4 ++-- http-client/pom.xml | 2 +- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 2 +- http-generator-helidon/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-generator-sigma/pom.xml | 2 +- http-inject-plugin/pom.xml | 2 +- tests/test-client-generation/pom.xml | 2 +- tests/test-client/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-htmx/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- tests/test-sigma/pom.xml | 2 +- 22 files changed, 25 insertions(+), 25 deletions(-) diff --git a/htmx-api/pom.xml b/htmx-api/pom.xml index 36f6f1a43..b0c8cc966 100644 --- a/htmx-api/pom.xml +++ b/htmx-api/pom.xml @@ -6,7 +6,7 @@ io.avaje avaje-http-parent - 2.9-RC4 + 2.9-RC5 avaje-htmx-api diff --git a/htmx-nima-jstache/pom.xml b/htmx-nima-jstache/pom.xml index 69ab8c84c..7ff35f340 100644 --- a/htmx-nima-jstache/pom.xml +++ b/htmx-nima-jstache/pom.xml @@ -6,7 +6,7 @@ io.avaje avaje-http-parent - 2.9-RC4 + 2.9-RC5 avaje-htmx-nima-jstache diff --git a/htmx-nima/pom.xml b/htmx-nima/pom.xml index 2b040cc2c..09692656e 100644 --- a/htmx-nima/pom.xml +++ b/htmx-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje avaje-http-parent - 2.9-RC4 + 2.9-RC5 avaje-htmx-nima @@ -21,7 +21,7 @@ io.avaje avaje-htmx-api - 2.9-RC4 + 2.9-RC5 io.helidon.webserver diff --git a/http-api-javalin/pom.xml b/http-api-javalin/pom.xml index 6e17606ee..bac1ea82d 100644 --- a/http-api-javalin/pom.xml +++ b/http-api-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.9-RC4 + 2.9-RC5 .. diff --git a/http-api/pom.xml b/http-api/pom.xml index 9b3da2e2f..d6246751d 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.9-RC4 + 2.9-RC5 .. diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index 161bf0202..6e9da380d 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.9-RC4 + 2.9-RC5 avaje-http-client-gson @@ -20,7 +20,7 @@ io.avaje avaje-http-client - 2.9-RC4 + 2.9-RC5 provided diff --git a/http-client-moshi-adapter/pom.xml b/http-client-moshi-adapter/pom.xml index e7652f23b..cf94c07be 100644 --- a/http-client-moshi-adapter/pom.xml +++ b/http-client-moshi-adapter/pom.xml @@ -3,7 +3,7 @@ io.avaje avaje-http-parent - 2.9-RC4 + 2.9-RC5 avaje-http-client-moshi @@ -19,7 +19,7 @@ io.avaje avaje-http-client - 2.9-RC4 + 2.9-RC5 provided diff --git a/http-client/pom.xml b/http-client/pom.xml index bbcae8588..ba9701e32 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.9-RC4 + 2.9-RC5 avaje-http-client diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index 400f6c001..40190e360 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.9-RC4 + 2.9-RC5 avaje-http-client-generator diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 3115baafd..b570c92d9 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.9-RC4 + 2.9-RC5 avaje-http-generator-core diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index 8ba0a6e61..0f6cdd070 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.9-RC4 + 2.9-RC5 avaje-http-helidon-generator diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index 0b49de2ff..368222128 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.9-RC4 + 2.9-RC5 avaje-http-jex-generator diff --git a/http-generator-sigma/pom.xml b/http-generator-sigma/pom.xml index e9723960f..401adf3ed 100644 --- a/http-generator-sigma/pom.xml +++ b/http-generator-sigma/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.9-RC4 + 2.9-RC5 avaje-http-sigma-generator diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index a28578a1b..70efd8829 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.9-RC4 + 2.9-RC5 .. diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index 2919f84f2..5197fd97c 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.9-RC4 + 2.9-RC5 test-client-generation diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index 566f9a291..8548b4b1c 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.9-RC4 + 2.9-RC5 test-client diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 734636a56..ab92add44 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 2.9-RC4 + 2.9-RC5 test-javalin-jsonb diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index db4022953..9a6ae80b4 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.9-RC4 + 2.9-RC5 test-javalin diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 610b84182..639f3eae9 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.9-RC4 + 2.9-RC5 test-jex diff --git a/tests/test-nima-htmx/pom.xml b/tests/test-nima-htmx/pom.xml index 09ef419a6..cb671ef72 100644 --- a/tests/test-nima-htmx/pom.xml +++ b/tests/test-nima-htmx/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.9-RC4 + 2.9-RC5 test-nima-htmx diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index 0224dc461..f8be8e431 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.9-RC4 + 2.9-RC5 test-nima diff --git a/tests/test-sigma/pom.xml b/tests/test-sigma/pom.xml index 0d4883f3b..439b18cfa 100644 --- a/tests/test-sigma/pom.xml +++ b/tests/test-sigma/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 2.9-RC4 + 2.9-RC5 test-sigma From 19e54edabee559ea09aedd3ae40228766a7881e7 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Mon, 9 Dec 2024 08:57:47 +1300 Subject: [PATCH 1202/1323] Version 2.9-RC5 --- http-generator-javalin/pom.xml | 2 +- pom.xml | 4 ++-- tests/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index f78eb38d9..739d86774 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.9-RC4 + 2.9-RC5 avaje-http-javalin-generator diff --git a/pom.xml b/pom.xml index 28640c3cc..f2f342d93 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-parent - 2.9-RC4 + 2.9-RC5 pom @@ -23,7 +23,7 @@ 2.14.2 3.0-RC10 1.36 - 2024-12-03T09:51:55Z + 2024-12-08T19:46:23Z ${project.build.directory}${file.separator}module-info.shade diff --git a/tests/pom.xml b/tests/pom.xml index 244a0b4f9..f4ba33e42 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.9-RC4 + 2.9-RC5 tests diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 67786941c..a0a58c9ee 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.9-RC4 + 2.9-RC5 test-nima-jsonb From 7fd68329def3bed46c346126d4c26906652b6d5d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Dec 2024 19:10:59 +0000 Subject: [PATCH 1203/1323] Bump the dependencies group with 3 updates Bumps the dependencies group with 3 updates: [io.avaje:avaje-jsonb](https://github.com/avaje/avaje-jsonb), [com.squareup.moshi:moshi](https://github.com/square/moshi) and io.avaje:avaje-jsonb-generator. Updates `io.avaje:avaje-jsonb` from 2.3 to 2.4 - [Release notes](https://github.com/avaje/avaje-jsonb/releases) - [Commits](https://github.com/avaje/avaje-jsonb/compare/2.3...2.4) Updates `com.squareup.moshi:moshi` from 1.15.1 to 1.15.2 - [Changelog](https://github.com/square/moshi/blob/master/CHANGELOG.md) - [Commits](https://github.com/square/moshi/compare/1.15.1...1.15.2) Updates `io.avaje:avaje-jsonb-generator` from 2.3 to 2.4 --- updated-dependencies: - dependency-name: io.avaje:avaje-jsonb dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: com.squareup.moshi:moshi dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: io.avaje:avaje-jsonb-generator dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies ... Signed-off-by: dependabot[bot] --- http-client-moshi-adapter/pom.xml | 2 +- http-client/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 4 ++-- tests/test-jex/pom.xml | 4 ++-- tests/test-nima-htmx/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 4 ++-- tests/test-sigma/pom.xml | 4 ++-- 7 files changed, 11 insertions(+), 11 deletions(-) diff --git a/http-client-moshi-adapter/pom.xml b/http-client-moshi-adapter/pom.xml index cf94c07be..664c8a4c3 100644 --- a/http-client-moshi-adapter/pom.xml +++ b/http-client-moshi-adapter/pom.xml @@ -12,7 +12,7 @@ com.squareup.moshi moshi - 1.15.1 + 1.15.2 true diff --git a/http-client/pom.xml b/http-client/pom.xml index ba9701e32..df8186f80 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -36,7 +36,7 @@ io.avaje avaje-jsonb - 2.3 + 2.4 true diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index ab92add44..e778f2b69 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -74,13 +74,13 @@ io.avaje avaje-jsonb - 2.3 + 2.4 io.avaje avaje-jsonb-generator - 2.3 + 2.4 provided diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 639f3eae9..b12439f6d 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -74,7 +74,7 @@ io.avaje avaje-jsonb - 2.3 + 2.4 @@ -96,7 +96,7 @@ io.avaje avaje-jsonb-generator - 2.3 + 2.4 diff --git a/tests/test-nima-htmx/pom.xml b/tests/test-nima-htmx/pom.xml index cb671ef72..7a6770109 100644 --- a/tests/test-nima-htmx/pom.xml +++ b/tests/test-nima-htmx/pom.xml @@ -88,7 +88,7 @@ io.avaje avaje-jsonb-generator - 2.3 + 2.4 io.jstach diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index a0a58c9ee..7c5fdf27d 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -31,7 +31,7 @@ io.avaje avaje-jsonb - 2.3 + 2.4 io.helidon.webserver @@ -85,7 +85,7 @@ io.avaje avaje-jsonb-generator - 2.3 + 2.4 io.avaje diff --git a/tests/test-sigma/pom.xml b/tests/test-sigma/pom.xml index 439b18cfa..967ea384f 100644 --- a/tests/test-sigma/pom.xml +++ b/tests/test-sigma/pom.xml @@ -67,12 +67,12 @@ io.avaje avaje-jsonb - 2.3 + 2.4 io.avaje avaje-jsonb-generator - 2.3 + 2.4 provided From 5e2e491fb13b10454d41e8c919ab2d09d28d30da Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Thu, 12 Dec 2024 23:53:28 +1300 Subject: [PATCH 1204/1323] [helidon-generator] Support avaje-jsonb version 3 (#532) With the change of package for JsonOutput which is now in avaje-json-core --- .../helidon/nima/ControllerWriter.java | 20 ++++++++++--------- tests/test-jex/pom.xml | 4 ++-- tests/test-nima-jsonb/pom.xml | 4 ++-- 3 files changed, 15 insertions(+), 13 deletions(-) diff --git a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java index 63ee0eab7..4e5d61bd8 100644 --- a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java +++ b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java @@ -8,14 +8,7 @@ import java.util.Map; import java.util.Objects; -import io.avaje.http.generator.core.BaseControllerWriter; -import io.avaje.http.generator.core.Constants; -import io.avaje.http.generator.core.ControllerReader; -import io.avaje.http.generator.core.CoreWebMethod; -import io.avaje.http.generator.core.JsonBUtil; -import io.avaje.http.generator.core.MethodReader; -import io.avaje.http.generator.core.PrimitiveUtil; -import io.avaje.http.generator.core.UType; +import io.avaje.http.generator.core.*; /** * Write Helidon specific web route adapter (a Helidon Service). @@ -25,6 +18,9 @@ class ControllerWriter extends BaseControllerWriter { private static final String AT_GENERATED = "@Generated(\"avaje-helidon-generator\")"; private static final String IMPORT_HTTP_STATUS = "import static io.helidon.http.Status.*;"; + private static final String JSON_JsonOutput = "io.avaje.json.stream.JsonOutput"; + private static final String JSONB_JsonOutput = "io.avaje.jsonb.stream.JsonOutput"; + private final boolean useJsonB; private final Map jsonTypes; @@ -35,7 +31,7 @@ class ControllerWriter extends BaseControllerWriter { reader.addImportType("io.avaje.jsonb.Jsonb"); reader.addImportType("io.avaje.jsonb.JsonType"); reader.addImportType("io.avaje.jsonb.Types"); - reader.addImportType("io.avaje.jsonb.stream.JsonOutput"); + reader.addImportType(jsonOutputType()); this.jsonTypes = JsonBUtil.jsonTypes(reader); jsonTypes.values().stream() .map(UType::importTypes) @@ -76,6 +72,12 @@ class ControllerWriter extends BaseControllerWriter { } } + private static String jsonOutputType() { + return ProcessingContext.typeElement(JSON_JsonOutput) != null + ? JSON_JsonOutput + : JSONB_JsonOutput; + } + void write() { writePackage(); writeImports(); diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index b12439f6d..b1ef3d8ef 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -74,7 +74,7 @@ io.avaje avaje-jsonb - 2.4 + 3.0-RC2 @@ -96,7 +96,7 @@ io.avaje avaje-jsonb-generator - 2.4 + 3.0-RC2 diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 7c5fdf27d..81df5c9fc 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -31,7 +31,7 @@ io.avaje avaje-jsonb - 2.4 + 3.0-RC2 io.helidon.webserver @@ -85,7 +85,7 @@ io.avaje avaje-jsonb-generator - 2.4 + 3.0-RC2 io.avaje From 5d0852cfdbaf3b776cdd731319e539eb36d063dc Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Thu, 12 Dec 2024 23:58:26 +1300 Subject: [PATCH 1205/1323] Version 2.9-RC6 --- htmx-api/pom.xml | 2 +- htmx-nima-jstache/pom.xml | 2 +- htmx-nima/pom.xml | 4 ++-- http-api-javalin/pom.xml | 2 +- http-api/pom.xml | 2 +- http-client-gson-adapter/pom.xml | 4 ++-- http-client-moshi-adapter/pom.xml | 4 ++-- http-client/pom.xml | 2 +- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 2 +- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-generator-sigma/pom.xml | 2 +- http-inject-plugin/pom.xml | 2 +- pom.xml | 4 ++-- tests/pom.xml | 2 +- tests/test-client-generation/pom.xml | 2 +- tests/test-client/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-htmx/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- tests/test-sigma/pom.xml | 2 +- 26 files changed, 30 insertions(+), 30 deletions(-) diff --git a/htmx-api/pom.xml b/htmx-api/pom.xml index b0c8cc966..28863da66 100644 --- a/htmx-api/pom.xml +++ b/htmx-api/pom.xml @@ -6,7 +6,7 @@ io.avaje avaje-http-parent - 2.9-RC5 + 2.9-RC6 avaje-htmx-api diff --git a/htmx-nima-jstache/pom.xml b/htmx-nima-jstache/pom.xml index 7ff35f340..b7e64e637 100644 --- a/htmx-nima-jstache/pom.xml +++ b/htmx-nima-jstache/pom.xml @@ -6,7 +6,7 @@ io.avaje avaje-http-parent - 2.9-RC5 + 2.9-RC6 avaje-htmx-nima-jstache diff --git a/htmx-nima/pom.xml b/htmx-nima/pom.xml index 09692656e..1869a5cb1 100644 --- a/htmx-nima/pom.xml +++ b/htmx-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje avaje-http-parent - 2.9-RC5 + 2.9-RC6 avaje-htmx-nima @@ -21,7 +21,7 @@ io.avaje avaje-htmx-api - 2.9-RC5 + 2.9-RC6 io.helidon.webserver diff --git a/http-api-javalin/pom.xml b/http-api-javalin/pom.xml index bac1ea82d..f62c30502 100644 --- a/http-api-javalin/pom.xml +++ b/http-api-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.9-RC5 + 2.9-RC6 .. diff --git a/http-api/pom.xml b/http-api/pom.xml index d6246751d..14ccfa60d 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.9-RC5 + 2.9-RC6 .. diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index 6e9da380d..9d83c4a5c 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.9-RC5 + 2.9-RC6 avaje-http-client-gson @@ -20,7 +20,7 @@ io.avaje avaje-http-client - 2.9-RC5 + 2.9-RC6 provided diff --git a/http-client-moshi-adapter/pom.xml b/http-client-moshi-adapter/pom.xml index 664c8a4c3..11f5b9e0d 100644 --- a/http-client-moshi-adapter/pom.xml +++ b/http-client-moshi-adapter/pom.xml @@ -3,7 +3,7 @@ io.avaje avaje-http-parent - 2.9-RC5 + 2.9-RC6 avaje-http-client-moshi @@ -19,7 +19,7 @@ io.avaje avaje-http-client - 2.9-RC5 + 2.9-RC6 provided diff --git a/http-client/pom.xml b/http-client/pom.xml index df8186f80..4212265a8 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.9-RC5 + 2.9-RC6 avaje-http-client diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index 40190e360..a8801f169 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.9-RC5 + 2.9-RC6 avaje-http-client-generator diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index b570c92d9..1c46e2216 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.9-RC5 + 2.9-RC6 avaje-http-generator-core diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index 0f6cdd070..6be7faf82 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.9-RC5 + 2.9-RC6 avaje-http-helidon-generator diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index 739d86774..5f6f48220 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.9-RC5 + 2.9-RC6 avaje-http-javalin-generator diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index 368222128..5f0990cbf 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.9-RC5 + 2.9-RC6 avaje-http-jex-generator diff --git a/http-generator-sigma/pom.xml b/http-generator-sigma/pom.xml index 401adf3ed..d76d91d09 100644 --- a/http-generator-sigma/pom.xml +++ b/http-generator-sigma/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.9-RC5 + 2.9-RC6 avaje-http-sigma-generator diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index 70efd8829..4f397f125 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.9-RC5 + 2.9-RC6 .. diff --git a/pom.xml b/pom.xml index f2f342d93..72466f160 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-parent - 2.9-RC5 + 2.9-RC6 pom @@ -23,7 +23,7 @@ 2.14.2 3.0-RC10 1.36 - 2024-12-08T19:46:23Z + 2024-12-12T10:53:55Z ${project.build.directory}${file.separator}module-info.shade diff --git a/tests/pom.xml b/tests/pom.xml index f4ba33e42..8c4a6ee21 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.9-RC5 + 2.9-RC6 tests diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index 5197fd97c..a9517cdc9 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.9-RC5 + 2.9-RC6 test-client-generation diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index 8548b4b1c..86e12dbe3 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.9-RC5 + 2.9-RC6 test-client diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index e778f2b69..92fa0639c 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 2.9-RC5 + 2.9-RC6 test-javalin-jsonb diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 9a6ae80b4..7078a973f 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.9-RC5 + 2.9-RC6 test-javalin diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index b1ef3d8ef..cf3b57cf2 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.9-RC5 + 2.9-RC6 test-jex diff --git a/tests/test-nima-htmx/pom.xml b/tests/test-nima-htmx/pom.xml index 7a6770109..560745021 100644 --- a/tests/test-nima-htmx/pom.xml +++ b/tests/test-nima-htmx/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.9-RC5 + 2.9-RC6 test-nima-htmx diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 81df5c9fc..0b64b179a 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.9-RC5 + 2.9-RC6 test-nima-jsonb diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index f8be8e431..a857cbc42 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.9-RC5 + 2.9-RC6 test-nima diff --git a/tests/test-sigma/pom.xml b/tests/test-sigma/pom.xml index 967ea384f..b4770599a 100644 --- a/tests/test-sigma/pom.xml +++ b/tests/test-sigma/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 2.9-RC5 + 2.9-RC6 test-sigma From 97fe4b6df2bb4e84d757d399818a82110e671ff3 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 17 Dec 2024 08:05:36 +1300 Subject: [PATCH 1206/1323] [http-client] Add SingleBodyAdapter for client API with only a single body type (#533) This provides a way to minimise the dependencies of an HttpClient that only has a single body type to support. --- http-client/pom.xml | 9 +- .../io/avaje/http/client/DSingleAdapter.java | 97 +++++++++++++++++++ .../avaje/http/client/SingleBodyAdapter.java | 54 +++++++++++ .../io/avaje/http/client/BaseWebTest.java | 12 ++- .../http/client/HelloControllerTest.java | 26 +++++ .../io/avaje/http/client/HelloDtoAdapter.java | 47 +++++++++ .../org/example/github/RepoJsonAdapter.java | 12 +-- 7 files changed, 246 insertions(+), 11 deletions(-) create mode 100644 http-client/src/main/java/io/avaje/http/client/DSingleAdapter.java create mode 100644 http-client/src/main/java/io/avaje/http/client/SingleBodyAdapter.java create mode 100644 http-client/src/test/java/io/avaje/http/client/HelloDtoAdapter.java diff --git a/http-client/pom.xml b/http-client/pom.xml index 4212265a8..d6bf7e326 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -36,10 +36,17 @@ io.avaje avaje-jsonb - 2.4 + 3.0-RC5 true + + io.avaje + avaje-json-node + 3.0-RC5 + test + + io.avaje avaje-inject diff --git a/http-client/src/main/java/io/avaje/http/client/DSingleAdapter.java b/http-client/src/main/java/io/avaje/http/client/DSingleAdapter.java new file mode 100644 index 000000000..8d9e80478 --- /dev/null +++ b/http-client/src/main/java/io/avaje/http/client/DSingleAdapter.java @@ -0,0 +1,97 @@ +package io.avaje.http.client; + +import io.avaje.http.client.SingleBodyAdapter.JsonBodyAdapter; +import io.avaje.json.simple.SimpleMapper; + +import java.util.List; + +@SuppressWarnings("unchecked") +final class DSingleAdapter implements BodyAdapter { + + private final ReaderWriter adapter; + + static BodyAdapter of(SimpleMapper.Type jsonType) { + return new DSingleAdapter(toAdapter(jsonType)); + } + + static BodyAdapter of(JsonBodyAdapter source) { + return new DSingleAdapter(source); + } + + private DSingleAdapter(JsonBodyAdapter source) { + this.adapter = new ReaderWriter<>(source); + } + + private static JsonBodyAdapter toAdapter(SimpleMapper.Type jsonType) { + return new SimpleJsonAdapter<>(jsonType); + } + + @Override + public BodyWriter beanWriter(Class aClass) { + return (BodyWriter) adapter; + } + + @Override + public BodyReader beanReader(Class aClass) { + return (BodyReader) adapter; + } + + @Override + public BodyReader> listReader(Class aClass) { + return (BodyReader>) adapter; + } + + private static final class ReaderWriter implements BodyReader, BodyWriter { + + private final JsonBodyAdapter adapter; + + ReaderWriter(JsonBodyAdapter adapter) { + this.adapter = adapter; + } + + @Override + public T readBody(String content) { + return adapter.fromJsonString(content); + } + + @Override + public T read(BodyContent bodyContent) { + return adapter.fromJsonBytes(bodyContent.content()); + } + + @Override + public BodyContent write(T bean, String contentType) { + return BodyContent.asJson(adapter.toJsonBytes(bean)); + } + + @Override + public BodyContent write(T bean) { + return BodyContent.asJson(adapter.toJsonBytes(bean)); + } + } + + private static final class SimpleJsonAdapter implements JsonBodyAdapter { + + private final SimpleMapper.Type jsonType; + + public SimpleJsonAdapter(SimpleMapper.Type jsonType) { + this.jsonType = jsonType; + } + + @Override + public T fromJsonString(String json) { + return jsonType.fromJson(json); + } + + @Override + public T fromJsonBytes(byte[] bytes) { + return jsonType.fromJson(bytes); + } + + @Override + public byte[] toJsonBytes(T bean) { + return jsonType.toJsonBytes(bean); + } + } +} + diff --git a/http-client/src/main/java/io/avaje/http/client/SingleBodyAdapter.java b/http-client/src/main/java/io/avaje/http/client/SingleBodyAdapter.java new file mode 100644 index 000000000..7aafb5f11 --- /dev/null +++ b/http-client/src/main/java/io/avaje/http/client/SingleBodyAdapter.java @@ -0,0 +1,54 @@ +package io.avaje.http.client; + +import io.avaje.json.simple.SimpleMapper; + +/** + * A BodyAdapter that supports converting the request/response body to a single type. + *

    + * Useful for an endpoint that only returns a single JSON response type. + */ +public interface SingleBodyAdapter extends BodyAdapter { + + /** + * Create with an json content adapter for a single java type. + * + * @param jsonAdapter The adapter to use to read and write the body content. + * @return The BodyAdapter that the HttpClient can use. + */ + static BodyAdapter create(JsonBodyAdapter jsonAdapter) { + return DSingleAdapter.of(jsonAdapter); + } + + /** + * Create using an avaje-json-core simple mapper type. + * + * @param jsonType The only type supported to read or write the body content. + * @return The BodyAdapter that the HttpClient can use. + */ + static BodyAdapter create(SimpleMapper.Type jsonType) { + return DSingleAdapter.of(jsonType); + } + + /** + * Json body reading and writing for a single type. + * + * @param The Java type of the request or response body. + */ + interface JsonBodyAdapter { + + /** + * Read the raw content String and return the java type. + */ + T fromJsonString(String json); + + /** + * Read the raw content bytes and return the java type. + */ + T fromJsonBytes(byte[] bytes); + + /** + * Write the java type to bytes. + */ + byte[] toJsonBytes(T bean); + } +} diff --git a/http-client/src/test/java/io/avaje/http/client/BaseWebTest.java b/http-client/src/test/java/io/avaje/http/client/BaseWebTest.java index cc3f4ebde..4c75e72f4 100644 --- a/http-client/src/test/java/io/avaje/http/client/BaseWebTest.java +++ b/http-client/src/test/java/io/avaje/http/client/BaseWebTest.java @@ -25,12 +25,16 @@ public static void shutdown() { webServer.stop(); } - public static HttpClient client() { + public static HttpClient client(BodyAdapter bodyAdapter) { return HttpClient.builder() .baseUrl(baseUrl) - .connectionTimeout(Duration.ofSeconds(1)) - .requestTimeout(Duration.ofSeconds(1)) - .bodyAdapter(new JacksonBodyAdapter(new ObjectMapper())) + .connectionTimeout(Duration.ofSeconds(10)) + .requestTimeout(Duration.ofSeconds(10)) + .bodyAdapter(bodyAdapter) .build(); } + + public static HttpClient client() { + return client(new JacksonBodyAdapter(new ObjectMapper())); + } } diff --git a/http-client/src/test/java/io/avaje/http/client/HelloControllerTest.java b/http-client/src/test/java/io/avaje/http/client/HelloControllerTest.java index 9004d865b..04da68cc1 100644 --- a/http-client/src/test/java/io/avaje/http/client/HelloControllerTest.java +++ b/http-client/src/test/java/io/avaje/http/client/HelloControllerTest.java @@ -1,6 +1,7 @@ package io.avaje.http.client; import com.fasterxml.jackson.databind.ObjectMapper; +import io.avaje.json.simple.SimpleMapper; import org.example.webserver.ErrorResponse; import org.example.webserver.HelloDto; import org.junit.jupiter.api.Test; @@ -818,6 +819,31 @@ void get_bean_404() { } } + @Test + void singleBodyAdapter_returningBean() { + var simpleMapper = SimpleMapper.builder().build(); + + SimpleMapper.Type type = simpleMapper.type(new HelloDtoAdapter()); + BodyAdapter bodyAdapter = SingleBodyAdapter.create(type); + HttpClient client = client(bodyAdapter); + + final var str = client.request() + .path("hello/43/2020-03-05").queryParam("otherParam", "other").queryParam("foo", (Object) null) + .GET() + .asString(); + + System.out.println(str.body()); + + final HelloDto dto = client.request() + .path("hello/43/2020-03-05").queryParam("otherParam", "other").queryParam("foo", (Object) null) + .GET() + .bean(HelloDto.class); + + assertThat(dto.id).isEqualTo(43L); + assertThat(dto.name).isEqualTo("2020-03-05"); + assertThat(dto.otherParam).isEqualTo("other"); + } + @Test void get_withPathParamAndQueryParam_returningBean() { diff --git a/http-client/src/test/java/io/avaje/http/client/HelloDtoAdapter.java b/http-client/src/test/java/io/avaje/http/client/HelloDtoAdapter.java new file mode 100644 index 000000000..52c7eeb1d --- /dev/null +++ b/http-client/src/test/java/io/avaje/http/client/HelloDtoAdapter.java @@ -0,0 +1,47 @@ +package io.avaje.http.client; + +import io.avaje.json.JsonAdapter; +import io.avaje.json.JsonReader; +import io.avaje.json.JsonWriter; +import io.avaje.json.node.JsonNodeMapper; +import io.avaje.json.node.JsonObject; +import org.example.webserver.HelloDto; + +import java.time.Instant; +import java.util.Optional; +import java.util.UUID; + +final class HelloDtoAdapter implements JsonAdapter { + + private final JsonNodeMapper nodeMapper; + + HelloDtoAdapter() { + nodeMapper = JsonNodeMapper.builder().build(); + } + + @Override + public void toJson(JsonWriter writer, HelloDto value) { + throw new UnsupportedOperationException(); + } + + @Override + public HelloDto fromJson(JsonReader reader) { + JsonObject jsonObject = nodeMapper.objectMapper().fromJson(reader); + + int id = jsonObject.extract("id", 0); + String name = jsonObject.extract("name", ""); + String otherParam = jsonObject.extract("otherParam", ""); + + var hello = new HelloDto(id, name, otherParam); + UUID gid = jsonObject.extractOrEmpty("gid") + .map(UUID::fromString) + .orElse(null); + hello.setGid(gid); + + String when = jsonObject.extract("whenAction", (String) null); + if (when != null) { + hello.setWhenAction(Instant.parse(when)); + } + return hello; + } +} diff --git a/http-client/src/test/java/org/example/github/RepoJsonAdapter.java b/http-client/src/test/java/org/example/github/RepoJsonAdapter.java index 788b9e752..33afbfad2 100644 --- a/http-client/src/test/java/org/example/github/RepoJsonAdapter.java +++ b/http-client/src/test/java/org/example/github/RepoJsonAdapter.java @@ -1,12 +1,12 @@ package org.example.github; -import io.avaje.jsonb.JsonAdapter; -import io.avaje.jsonb.JsonReader; -import io.avaje.jsonb.JsonWriter; +import io.avaje.json.JsonAdapter; +import io.avaje.json.JsonReader; +import io.avaje.json.JsonWriter; import io.avaje.jsonb.Jsonb; -import io.avaje.jsonb.spi.PropertyNames; -import io.avaje.jsonb.spi.ViewBuilder; -import io.avaje.jsonb.spi.ViewBuilderAware; +import io.avaje.json.PropertyNames; +import io.avaje.json.view.ViewBuilder; +import io.avaje.json.view.ViewBuilderAware; import java.lang.invoke.MethodHandle; From 30d33ca95df428e4300726422dab490052f74b96 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 17 Dec 2024 08:11:49 +1300 Subject: [PATCH 1207/1323] [http-client] Add BasicAuthIntercept.header() helper method (#534) Provided as a helper method for code that wants the header value to then apply it explicitly [typically as a http Authorization header] rather than using this as a request intercept. --- .../avaje/http/client/BasicAuthIntercept.java | 29 ++++++++++++++++--- .../http/client/BasicAuthInterceptTest.java | 6 ++++ 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/http-client/src/main/java/io/avaje/http/client/BasicAuthIntercept.java b/http-client/src/main/java/io/avaje/http/client/BasicAuthIntercept.java index 4c18a33ed..5c5076a36 100644 --- a/http-client/src/main/java/io/avaje/http/client/BasicAuthIntercept.java +++ b/http-client/src/main/java/io/avaje/http/client/BasicAuthIntercept.java @@ -4,17 +4,38 @@ import java.util.Base64; -/** Adds Basic Authorization header to requests. */ +/** + * Adds Basic Authorization header to requests. + */ public final class BasicAuthIntercept implements RequestIntercept { private final String headerValue; - /** Construct with the username and password. */ + /** + * Construct with the username and password. + */ public BasicAuthIntercept(String username, String password) { - this.headerValue = "Basic " + encode(username, password); + this.headerValue = header(username, password); } - /** Return Base64 encoding of {@literal username:password} */ + /** + * Return the Basic header value with the encoding of {@literal username:password} + *

    + * Provided as a helper method for code that wants the header value to then + * apply explicitly rather than using this as a request intercept. + * + * @return {@code "Basic " + encode(username, password)} + */ + public static String header(String username, String password) { + return "Basic " + encode(username, password); + } + + /** + * Return Base64 encoding of {@literal username:password} + *

    + * Provided as a helper method for code that wants to encode the username + * password pair and use that explicitly rather than using this as a request intercept. + */ public static String encode(String username, String password) { return Base64.getEncoder().encodeToString((username + ":" + password).getBytes(UTF_8)); } diff --git a/http-client/src/test/java/io/avaje/http/client/BasicAuthInterceptTest.java b/http-client/src/test/java/io/avaje/http/client/BasicAuthInterceptTest.java index 74d7755be..6f374acd7 100644 --- a/http-client/src/test/java/io/avaje/http/client/BasicAuthInterceptTest.java +++ b/http-client/src/test/java/io/avaje/http/client/BasicAuthInterceptTest.java @@ -14,6 +14,12 @@ void encode() { assertThat(encode).isEqualTo("QWxhZGRpbjpvcGVuIHNlc2FtZQ=="); } + @Test + void header() { + final String encode = BasicAuthIntercept.header("Aladdin", "open sesame"); + assertThat(encode).isEqualTo("Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ=="); + } + @Test void beforeRequest() { // setup From 36bfcff576cf90fb59f7d087e13ed0fdee921972 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 17 Dec 2024 08:12:39 +1300 Subject: [PATCH 1208/1323] Version 2.9-RC7 --- htmx-api/pom.xml | 2 +- htmx-nima-jstache/pom.xml | 2 +- htmx-nima/pom.xml | 4 ++-- http-api-javalin/pom.xml | 2 +- http-api/pom.xml | 2 +- http-client-gson-adapter/pom.xml | 4 ++-- http-client-moshi-adapter/pom.xml | 4 ++-- http-client/pom.xml | 2 +- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 2 +- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-generator-sigma/pom.xml | 2 +- http-inject-plugin/pom.xml | 2 +- pom.xml | 4 ++-- tests/pom.xml | 2 +- tests/test-client-generation/pom.xml | 2 +- tests/test-client/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-htmx/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- tests/test-sigma/pom.xml | 2 +- 26 files changed, 30 insertions(+), 30 deletions(-) diff --git a/htmx-api/pom.xml b/htmx-api/pom.xml index 28863da66..6036c051c 100644 --- a/htmx-api/pom.xml +++ b/htmx-api/pom.xml @@ -6,7 +6,7 @@ io.avaje avaje-http-parent - 2.9-RC6 + 2.9-RC7 avaje-htmx-api diff --git a/htmx-nima-jstache/pom.xml b/htmx-nima-jstache/pom.xml index b7e64e637..1b159fae0 100644 --- a/htmx-nima-jstache/pom.xml +++ b/htmx-nima-jstache/pom.xml @@ -6,7 +6,7 @@ io.avaje avaje-http-parent - 2.9-RC6 + 2.9-RC7 avaje-htmx-nima-jstache diff --git a/htmx-nima/pom.xml b/htmx-nima/pom.xml index 1869a5cb1..23a20cc76 100644 --- a/htmx-nima/pom.xml +++ b/htmx-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje avaje-http-parent - 2.9-RC6 + 2.9-RC7 avaje-htmx-nima @@ -21,7 +21,7 @@ io.avaje avaje-htmx-api - 2.9-RC6 + 2.9-RC7 io.helidon.webserver diff --git a/http-api-javalin/pom.xml b/http-api-javalin/pom.xml index f62c30502..660440702 100644 --- a/http-api-javalin/pom.xml +++ b/http-api-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.9-RC6 + 2.9-RC7 .. diff --git a/http-api/pom.xml b/http-api/pom.xml index 14ccfa60d..e2672b7e3 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.9-RC6 + 2.9-RC7 .. diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index 9d83c4a5c..ee8114667 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.9-RC6 + 2.9-RC7 avaje-http-client-gson @@ -20,7 +20,7 @@ io.avaje avaje-http-client - 2.9-RC6 + 2.9-RC7 provided diff --git a/http-client-moshi-adapter/pom.xml b/http-client-moshi-adapter/pom.xml index 11f5b9e0d..22a0ceaca 100644 --- a/http-client-moshi-adapter/pom.xml +++ b/http-client-moshi-adapter/pom.xml @@ -3,7 +3,7 @@ io.avaje avaje-http-parent - 2.9-RC6 + 2.9-RC7 avaje-http-client-moshi @@ -19,7 +19,7 @@ io.avaje avaje-http-client - 2.9-RC6 + 2.9-RC7 provided diff --git a/http-client/pom.xml b/http-client/pom.xml index d6bf7e326..7fa1af335 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.9-RC6 + 2.9-RC7 avaje-http-client diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index a8801f169..ad8b28d65 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.9-RC6 + 2.9-RC7 avaje-http-client-generator diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 1c46e2216..7afa5e4f5 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.9-RC6 + 2.9-RC7 avaje-http-generator-core diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index 6be7faf82..375ecd511 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.9-RC6 + 2.9-RC7 avaje-http-helidon-generator diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index 5f6f48220..cd9c7de4d 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.9-RC6 + 2.9-RC7 avaje-http-javalin-generator diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index 5f0990cbf..dff8320a6 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.9-RC6 + 2.9-RC7 avaje-http-jex-generator diff --git a/http-generator-sigma/pom.xml b/http-generator-sigma/pom.xml index d76d91d09..eea06c4b3 100644 --- a/http-generator-sigma/pom.xml +++ b/http-generator-sigma/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.9-RC6 + 2.9-RC7 avaje-http-sigma-generator diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index 4f397f125..d93b382b4 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.9-RC6 + 2.9-RC7 .. diff --git a/pom.xml b/pom.xml index 72466f160..917ba04ce 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-parent - 2.9-RC6 + 2.9-RC7 pom @@ -23,7 +23,7 @@ 2.14.2 3.0-RC10 1.36 - 2024-12-12T10:53:55Z + 2024-12-16T19:12:09Z ${project.build.directory}${file.separator}module-info.shade diff --git a/tests/pom.xml b/tests/pom.xml index 8c4a6ee21..4e423dbf3 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.9-RC6 + 2.9-RC7 tests diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index a9517cdc9..a3c5447c2 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.9-RC6 + 2.9-RC7 test-client-generation diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index 86e12dbe3..18909553a 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.9-RC6 + 2.9-RC7 test-client diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 92fa0639c..b33299465 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 2.9-RC6 + 2.9-RC7 test-javalin-jsonb diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 7078a973f..f2d663969 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.9-RC6 + 2.9-RC7 test-javalin diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index cf3b57cf2..5bfb4b844 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.9-RC6 + 2.9-RC7 test-jex diff --git a/tests/test-nima-htmx/pom.xml b/tests/test-nima-htmx/pom.xml index 560745021..edbfc3427 100644 --- a/tests/test-nima-htmx/pom.xml +++ b/tests/test-nima-htmx/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.9-RC6 + 2.9-RC7 test-nima-htmx diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 0b64b179a..ef3b1f3bb 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.9-RC6 + 2.9-RC7 test-nima-jsonb diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index a857cbc42..80f3d8c1d 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.9-RC6 + 2.9-RC7 test-nima diff --git a/tests/test-sigma/pom.xml b/tests/test-sigma/pom.xml index b4770599a..56ac0def7 100644 --- a/tests/test-sigma/pom.xml +++ b/tests/test-sigma/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 2.9-RC6 + 2.9-RC7 test-sigma From 461bcac1613a555ced22aba61190349a2447b91a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Dec 2024 19:55:06 +0000 Subject: [PATCH 1209/1323] Bump the dependencies group with 14 updates Bumps the dependencies group with 14 updates: | Package | From | To | | --- | --- | --- | | io.swagger.core.v3:swagger-models | `2.2.26` | `2.2.27` | | io.swagger.core.v3:swagger-annotations | `2.2.26` | `2.2.27` | | [io.avaje:avaje-validator](https://github.com/avaje/avaje-validator) | `2.3` | `2.4` | | io.avaje:avaje-validator-constraints | `2.3` | `2.4` | | io.avaje:avaje-validator-generator | `2.3` | `2.4` | | io.helidon.webserver:helidon-webserver | `4.1.4` | `4.1.5` | | io.helidon.webserver:helidon-webserver-security | `4.1.4` | `4.1.5` | | io.helidon.http.media:helidon-http-media-jsonb | `4.1.4` | `4.1.5` | | [io.avaje:avaje-jex](https://github.com/avaje/avaje-jex) | `3.0-RC10` | `3.0-RC11` | | io.avaje:avaje-jex-htmx | `3.0-RC10` | `3.0-RC11` | | io.avaje:avaje-nima | `1.0` | `1.1` | | io.avaje:avaje-nima-test | `1.0` | `1.1` | | [org.junit.jupiter:junit-jupiter-api](https://github.com/junit-team/junit5) | `5.11.3` | `5.11.4` | | [org.junit.jupiter:junit-jupiter-engine](https://github.com/junit-team/junit5) | `5.11.3` | `5.11.4` | Updates `io.swagger.core.v3:swagger-models` from 2.2.26 to 2.2.27 Updates `io.swagger.core.v3:swagger-annotations` from 2.2.26 to 2.2.27 Updates `io.swagger.core.v3:swagger-annotations` from 2.2.26 to 2.2.27 Updates `io.avaje:avaje-validator` from 2.3 to 2.4 - [Release notes](https://github.com/avaje/avaje-validator/releases) - [Commits](https://github.com/avaje/avaje-validator/compare/2.3...2.4) Updates `io.avaje:avaje-validator-constraints` from 2.3 to 2.4 Updates `io.avaje:avaje-validator-generator` from 2.3 to 2.4 Updates `io.helidon.webserver:helidon-webserver` from 4.1.4 to 4.1.5 Updates `io.helidon.webserver:helidon-webserver-security` from 4.1.4 to 4.1.5 Updates `io.helidon.http.media:helidon-http-media-jsonb` from 4.1.4 to 4.1.5 Updates `io.helidon.webserver:helidon-webserver-security` from 4.1.4 to 4.1.5 Updates `io.helidon.http.media:helidon-http-media-jsonb` from 4.1.4 to 4.1.5 Updates `io.avaje:avaje-jex` from 3.0-RC10 to 3.0-RC11 - [Release notes](https://github.com/avaje/avaje-jex/releases) - [Commits](https://github.com/avaje/avaje-jex/commits) Updates `io.avaje:avaje-jex-htmx` from 3.0-RC10 to 3.0-RC11 Updates `io.avaje:avaje-jex-htmx` from 3.0-RC10 to 3.0-RC11 Updates `io.avaje:avaje-nima` from 1.0 to 1.1 Updates `io.avaje:avaje-nima-test` from 1.0 to 1.1 Updates `org.junit.jupiter:junit-jupiter-api` from 5.11.3 to 5.11.4 - [Release notes](https://github.com/junit-team/junit5/releases) - [Commits](https://github.com/junit-team/junit5/compare/r5.11.3...r5.11.4) Updates `org.junit.jupiter:junit-jupiter-engine` from 5.11.3 to 5.11.4 - [Release notes](https://github.com/junit-team/junit5/releases) - [Commits](https://github.com/junit-team/junit5/compare/r5.11.3...r5.11.4) Updates `org.junit.jupiter:junit-jupiter-engine` from 5.11.3 to 5.11.4 - [Release notes](https://github.com/junit-team/junit5/releases) - [Commits](https://github.com/junit-team/junit5/compare/r5.11.3...r5.11.4) --- updated-dependencies: - dependency-name: io.swagger.core.v3:swagger-models dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: io.swagger.core.v3:swagger-annotations dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: io.swagger.core.v3:swagger-annotations dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: io.avaje:avaje-validator dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.avaje:avaje-validator-constraints dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.avaje:avaje-validator-generator dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.helidon.webserver:helidon-webserver dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: io.helidon.webserver:helidon-webserver-security dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: io.helidon.http.media:helidon-http-media-jsonb dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: io.helidon.webserver:helidon-webserver-security dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: io.helidon.http.media:helidon-http-media-jsonb dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: io.avaje:avaje-jex dependency-type: direct:production dependency-group: dependencies - dependency-name: io.avaje:avaje-jex-htmx dependency-type: direct:production dependency-group: dependencies - dependency-name: io.avaje:avaje-jex-htmx dependency-type: direct:production dependency-group: dependencies - dependency-name: io.avaje:avaje-nima dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.avaje:avaje-nima-test dependency-type: direct:development update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: org.junit.jupiter:junit-jupiter-api dependency-type: direct:development update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: org.junit.jupiter:junit-jupiter-engine dependency-type: direct:development update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: org.junit.jupiter:junit-jupiter-engine dependency-type: direct:development update-type: version-update:semver-patch dependency-group: dependencies ... Signed-off-by: dependabot[bot] --- htmx-nima/pom.xml | 2 +- pom.xml | 2 +- tests/pom.xml | 12 ++++++------ tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 4 ++-- tests/test-jex/pom.xml | 2 +- tests/test-nima-htmx/pom.xml | 4 ++-- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-sigma/pom.xml | 2 +- 9 files changed, 16 insertions(+), 16 deletions(-) diff --git a/htmx-nima/pom.xml b/htmx-nima/pom.xml index 23a20cc76..0bc859cfe 100644 --- a/htmx-nima/pom.xml +++ b/htmx-nima/pom.xml @@ -26,7 +26,7 @@ io.helidon.webserver helidon-webserver - 4.1.4 + 4.1.5 diff --git a/pom.xml b/pom.xml index 917ba04ce..018e68b54 100644 --- a/pom.xml +++ b/pom.xml @@ -19,7 +19,7 @@ true - 2.2.26 + 2.2.27 2.14.2 3.0-RC10 1.36 diff --git a/tests/pom.xml b/tests/pom.xml index 4e423dbf3..9015a222b 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -12,12 +12,12 @@ true - 5.11.3 + 5.11.4 3.26.3 2.18.2 - 3.0-RC10 + 3.0-RC11 11.0 - 4.1.4 + 4.1.5 6.3.0 @@ -48,19 +48,19 @@ io.avaje avaje-validator - 2.3 + 2.4 io.avaje avaje-validator-constraints - 2.3 + 2.4 io.avaje avaje-validator-generator - 2.3 + 2.4 diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index b33299465..0983c75a5 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -13,7 +13,7 @@ true org.example.myapp.Main - 2.2.26 + 2.2.27 1.3.71 diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index f2d663969..b807e2357 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -12,7 +12,7 @@ true org.example.myapp.Main - 2.2.26 + 2.2.27 1.3.71 @@ -57,7 +57,7 @@ io.avaje avaje-validator - 2.3 + 2.4 diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 5bfb4b844..6c692a14b 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -12,7 +12,7 @@ 21 true org.example.myapp.Main - 2.2.26 + 2.2.27 diff --git a/tests/test-nima-htmx/pom.xml b/tests/test-nima-htmx/pom.xml index edbfc3427..355bdeead 100644 --- a/tests/test-nima-htmx/pom.xml +++ b/tests/test-nima-htmx/pom.xml @@ -47,7 +47,7 @@ io.avaje avaje-nima - 1.0 + 1.1 @@ -60,7 +60,7 @@ io.avaje avaje-nima-test - 1.0 + 1.1 test diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index ef3b1f3bb..94aa469fc 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -90,7 +90,7 @@ io.avaje avaje-validator-generator - 2.3 + 2.4 diff --git a/tests/test-sigma/pom.xml b/tests/test-sigma/pom.xml index 56ac0def7..af9278929 100644 --- a/tests/test-sigma/pom.xml +++ b/tests/test-sigma/pom.xml @@ -13,7 +13,7 @@ 17 true - 2.2.26 + 2.2.27 1.3.71 From 4a390b7f6553a834fb17fcb60c53e8dc65ebbbd1 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Mon, 16 Dec 2024 15:30:14 -0500 Subject: [PATCH 1210/1323] versions --- htmx-nima-jstache/pom.xml | 2 +- http-client/pom.xml | 2 +- http-inject-plugin/pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/htmx-nima-jstache/pom.xml b/htmx-nima-jstache/pom.xml index 1b159fae0..017950570 100644 --- a/htmx-nima-jstache/pom.xml +++ b/htmx-nima-jstache/pom.xml @@ -39,7 +39,7 @@ io.avaje avaje-inject - 11.0 + 11.1-RC1 provided true diff --git a/http-client/pom.xml b/http-client/pom.xml index 7fa1af335..06222fc6d 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -50,7 +50,7 @@ io.avaje avaje-inject - 11.0 + 11.1-RC1 true diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index d93b382b4..ab557d36c 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -19,7 +19,7 @@ io.avaje avaje-inject - 11.0 + 11.1-RC1 provided true From db613aec38458bb5e6828f1962e4b4727a09e932 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Mon, 16 Dec 2024 15:32:06 -0500 Subject: [PATCH 1211/1323] bump jsonb versions --- tests/test-javalin-jsonb/pom.xml | 4 ++-- tests/test-jex/pom.xml | 4 ++-- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-sigma/pom.xml | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 0983c75a5..d067839dc 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -74,13 +74,13 @@ io.avaje avaje-jsonb - 2.4 + 3.0-RC5 io.avaje avaje-jsonb-generator - 2.4 + 3.0-RC5 provided diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 6c692a14b..22a091d59 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -74,7 +74,7 @@ io.avaje avaje-jsonb - 3.0-RC2 + 3.0-RC5 @@ -96,7 +96,7 @@ io.avaje avaje-jsonb-generator - 3.0-RC2 + 3.0-RC5 diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 94aa469fc..a42102826 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -31,7 +31,7 @@ io.avaje avaje-jsonb - 3.0-RC2 + 3.0-RC5 io.helidon.webserver diff --git a/tests/test-sigma/pom.xml b/tests/test-sigma/pom.xml index af9278929..d03256fba 100644 --- a/tests/test-sigma/pom.xml +++ b/tests/test-sigma/pom.xml @@ -67,12 +67,12 @@ io.avaje avaje-jsonb - 2.4 + 3.0-RC5 io.avaje avaje-jsonb-generator - 2.4 + 3.0-RC5 provided From 5ee2cb432c304bfa9dc76e930b81b60f1dd80dec Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Mon, 16 Dec 2024 15:44:27 -0500 Subject: [PATCH 1212/1323] Update HelloControllerTest.java --- .../org/example/web/HelloControllerTest.java | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/tests/test-jex/src/test/java/org/example/web/HelloControllerTest.java b/tests/test-jex/src/test/java/org/example/web/HelloControllerTest.java index 11da4f194..28b2ab993 100644 --- a/tests/test-jex/src/test/java/org/example/web/HelloControllerTest.java +++ b/tests/test-jex/src/test/java/org/example/web/HelloControllerTest.java @@ -1,15 +1,19 @@ package org.example.web; -import io.avaje.http.client.HttpClient; -import io.avaje.http.client.HttpException; -import org.junit.jupiter.api.Test; - -import java.net.http.HttpResponse; - import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; +import java.net.http.HttpResponse; + +import org.junit.jupiter.api.Test; + +import io.avaje.http.api.ValidationException.Violation; +import io.avaje.http.client.HttpClient; +import io.avaje.http.client.HttpException; +import io.avaje.jsonb.Json.Import; + +@Import(Violation.class) class HelloControllerTest extends BaseWebTest { final static HttpClient client = client(); From 91d8e8a3c1e830aa692b50f7159da9e007f3522d Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Wed, 18 Dec 2024 09:39:13 +1300 Subject: [PATCH 1213/1323] Add AWS CognitoAuthTokenProvider module (#536) * Add AWS CognitoAuthTokenProvider module An HttpClient AuthTokenProvider for AWS Cognito * Packaging pom on aws-cognito * Release aws-cognito/http-client-authtoken independently --- aws-cognito/http-client-authtoken/pom.xml | 45 +++++++++ .../cognito/AmzCognitoAuthTokenProvider.java | 93 +++++++++++++++++++ .../cognito/CognitoAuthTokenProvider.java | 65 +++++++++++++ .../src/main/java/module-info.java | 7 ++ .../cognito/CognitoAuthTokenProviderTest.java | 49 ++++++++++ aws-cognito/pom.xml | 15 +++ pom.xml | 2 + 7 files changed, 276 insertions(+) create mode 100644 aws-cognito/http-client-authtoken/pom.xml create mode 100644 aws-cognito/http-client-authtoken/src/main/java/io/avaje/aws/client/cognito/AmzCognitoAuthTokenProvider.java create mode 100644 aws-cognito/http-client-authtoken/src/main/java/io/avaje/aws/client/cognito/CognitoAuthTokenProvider.java create mode 100644 aws-cognito/http-client-authtoken/src/main/java/module-info.java create mode 100644 aws-cognito/http-client-authtoken/src/test/java/io/avaje/aws/client/cognito/CognitoAuthTokenProviderTest.java create mode 100644 aws-cognito/pom.xml diff --git a/aws-cognito/http-client-authtoken/pom.xml b/aws-cognito/http-client-authtoken/pom.xml new file mode 100644 index 000000000..897acf4ed --- /dev/null +++ b/aws-cognito/http-client-authtoken/pom.xml @@ -0,0 +1,45 @@ + + + 4.0.0 + + org.avaje + java11-oss + 4.5 + + + io.avaje.aws + avaje-cognito-client-token + 1.0-RC1 + + + + io.avaje + avaje-http-client + 2.8 + + + + io.avaje + avaje-json-core + 3.0-RC5 + + + + + io.avaje + avaje-json-node + 3.0-RC5 + test + + + + io.avaje + junit + 1.5 + test + + + + diff --git a/aws-cognito/http-client-authtoken/src/main/java/io/avaje/aws/client/cognito/AmzCognitoAuthTokenProvider.java b/aws-cognito/http-client-authtoken/src/main/java/io/avaje/aws/client/cognito/AmzCognitoAuthTokenProvider.java new file mode 100644 index 000000000..359fbfcae --- /dev/null +++ b/aws-cognito/http-client-authtoken/src/main/java/io/avaje/aws/client/cognito/AmzCognitoAuthTokenProvider.java @@ -0,0 +1,93 @@ +package io.avaje.aws.client.cognito; + +import io.avaje.http.client.AuthToken; +import io.avaje.http.client.AuthTokenProvider; +import io.avaje.http.client.BasicAuthIntercept; +import io.avaje.http.client.HttpClientRequest; +import io.avaje.json.simple.SimpleMapper; + +import java.net.http.HttpResponse; +import java.time.Instant; + +final class AmzCognitoAuthTokenProvider implements CognitoAuthTokenProvider.Builder { + + private String url; + private String clientId; + private String clientSecret; + private String scope; + + @Override + public CognitoAuthTokenProvider.Builder url(String url) { + this.url = url; + return this; + } + + @Override + public CognitoAuthTokenProvider.Builder clientId(String clientId) { + this.clientId = clientId; + return this; + } + + @Override + public CognitoAuthTokenProvider.Builder clientSecret(String clientSecret) { + this.clientSecret = clientSecret; + return this; + } + + @Override + public CognitoAuthTokenProvider.Builder scope(String scope) { + this.scope = scope; + return this; + } + + @Override + public AuthTokenProvider build() { + return new Provider(url, clientId, clientSecret, scope); + } + + private static final class Provider implements AuthTokenProvider { + + private static final SimpleMapper MAPPER = SimpleMapper.builder().build(); + + private final String url; + private final String clientId; + private final String scope; + private final String authHeader; + + public Provider(String url, String clientId, String clientSecret, String scope) { + this.url = url; + this.clientId = clientId; + this.scope = scope; + this.authHeader = "Basic " + BasicAuthIntercept.encode(clientId, clientSecret); + } + + @Override + public AuthToken obtainToken(HttpClientRequest request) { + HttpResponse res = request + .url(url) + .header("Authorization", authHeader) + .formParam("grant_type", "client_credentials") + .formParam("client_id", clientId) + .formParam("scope", scope) + .POST() + .asString(); + + if (res.statusCode() != 200) { + throw new IllegalStateException("Error response getting access token statusCode:" + res.statusCode() + " res:" + res); + } + return decodeAuthToken(res.body()); + } + + private AuthToken decodeAuthToken(String responseBody) { + final var responseMap = MAPPER.fromJsonObject(responseBody); + final var accessToken = (String) responseMap.get("access_token"); + final var expiresIn = (Long) responseMap.get("expires_in"); + + var validUntil = Instant.now() + .plusSeconds(expiresIn) + .minusSeconds(60); + + return AuthToken.of(accessToken, validUntil); + } + } +} diff --git a/aws-cognito/http-client-authtoken/src/main/java/io/avaje/aws/client/cognito/CognitoAuthTokenProvider.java b/aws-cognito/http-client-authtoken/src/main/java/io/avaje/aws/client/cognito/CognitoAuthTokenProvider.java new file mode 100644 index 000000000..e0f37c107 --- /dev/null +++ b/aws-cognito/http-client-authtoken/src/main/java/io/avaje/aws/client/cognito/CognitoAuthTokenProvider.java @@ -0,0 +1,65 @@ +package io.avaje.aws.client.cognito; + +import io.avaje.http.client.AuthTokenProvider; + +/** + * AuthTokenProvider for AWS Cognito providing Bearer access tokens. + * + *

    {@code
    + *
    + *     AuthTokenProvider authTokenProvider = CognitoAuthTokenProvider.builder()
    + *       .url("https://foo.amazoncognito.com/oauth2/token")
    + *       .clientId("")
    + *       .clientSecret("")
    + *       .scope("default/default")
    + *       .build();
    + *
    + *     // specify the authTokenProvider on the HttpClient ...
    + *
    + *     HttpClient client = HttpClient.builder()
    + *       .authTokenProvider(authTokenProvider)
    + *       .baseUrl(myApplicationUrl)
    + *       .build();
    + *
    + * }
    + */ +public interface CognitoAuthTokenProvider extends AuthTokenProvider { + + /** + * Return a builder for the CognitoAuthTokenProvider. + */ + static Builder builder() { + return new AmzCognitoAuthTokenProvider(); + } + + /** + * The builder for the AWS Cognito AuthTokenProvider. + */ + interface Builder { + + /** + * Set the url used to obtain access tokens. + */ + Builder url(String url); + + /** + * Set the clientId. + */ + Builder clientId(String clientId); + + /** + * Set the clientSecret. + */ + Builder clientSecret(String clientSecret); + + /** + * Set the scope. + */ + Builder scope(String scope); + + /** + * Build and return the AuthTokenProvider. + */ + AuthTokenProvider build(); + } +} diff --git a/aws-cognito/http-client-authtoken/src/main/java/module-info.java b/aws-cognito/http-client-authtoken/src/main/java/module-info.java new file mode 100644 index 000000000..12a416801 --- /dev/null +++ b/aws-cognito/http-client-authtoken/src/main/java/module-info.java @@ -0,0 +1,7 @@ +module io.avaje.aws.client.cognito { + + exports io.avaje.aws.client.cognito; + + requires transitive io.avaje.http.client; + requires transitive io.avaje.json; +} diff --git a/aws-cognito/http-client-authtoken/src/test/java/io/avaje/aws/client/cognito/CognitoAuthTokenProviderTest.java b/aws-cognito/http-client-authtoken/src/test/java/io/avaje/aws/client/cognito/CognitoAuthTokenProviderTest.java new file mode 100644 index 000000000..6658d8344 --- /dev/null +++ b/aws-cognito/http-client-authtoken/src/test/java/io/avaje/aws/client/cognito/CognitoAuthTokenProviderTest.java @@ -0,0 +1,49 @@ +package io.avaje.aws.client.cognito; + +import io.avaje.http.client.AuthTokenProvider; +import io.avaje.http.client.HttpClientRequest; +import io.avaje.http.client.HttpClientResponse; +import org.junit.jupiter.api.Test; + +import java.net.http.HttpResponse; + +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.*; + +@SuppressWarnings("unchecked") +class CognitoAuthTokenProviderTest { + + @Test + void obtainToken() { + final String url = "https://.amazoncognito.com/oauth2/token"; + final String clientId = ""; + final String clientSecret = ""; + + AuthTokenProvider authTokenProvider = CognitoAuthTokenProvider.builder() + .url(url) + .clientId(clientId) + .clientSecret(clientSecret) + .scope("default/default") + .build(); + + HttpResponse httpResponse = mock(HttpResponse.class); + when(httpResponse.statusCode()).thenReturn(200); + when(httpResponse.body()).thenReturn("{\"access_token\":\"1234\",\"expires_in\":3600}"); + + HttpClientResponse clientResponse = mock(HttpClientResponse.class); + when(clientResponse.asString()).thenReturn(httpResponse); + + HttpClientRequest httpClientRequest = mock(HttpClientRequest.class); + when(httpClientRequest.url(anyString())).thenReturn(httpClientRequest); + + when(httpClientRequest.header(anyString(), anyString())).thenReturn(httpClientRequest); + when(httpClientRequest.formParam(anyString(), anyString())).thenReturn(httpClientRequest); + when(httpClientRequest.POST()).thenReturn(clientResponse); + + // act + authTokenProvider.obtainToken(httpClientRequest); + + // verify the Authorization header has been obtained and set + verify(httpClientRequest).header("Authorization", "Basic PHNvbWV0aGluZz46PHNvbWV0aGluZz4="); + } +} diff --git a/aws-cognito/pom.xml b/aws-cognito/pom.xml new file mode 100644 index 000000000..466964dc6 --- /dev/null +++ b/aws-cognito/pom.xml @@ -0,0 +1,15 @@ + + + 4.0.0 + + org.avaje + java11-oss + 4.5 + + + aws-cognito + pom + + diff --git a/pom.xml b/pom.xml index 018e68b54..f0b2a7d1f 100644 --- a/pom.xml +++ b/pom.xml @@ -75,6 +75,8 @@ test21 + + aws-cognito/http-client-authtoken htmx-nima htmx-nima-jstache http-generator-helidon From 2e0ac3f5c90cacab0ac69e601c32794c4fd1fef2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 23 Dec 2024 19:26:24 +0000 Subject: [PATCH 1214/1323] Bump the dependencies group with 10 updates Bumps the dependencies group with 10 updates: | Package | From | To | | --- | --- | --- | | [io.javalin:javalin](https://github.com/javalin/javalin) | `6.3.0` | `6.4.0` | | io.avaje:avaje-spi-service | `2.8` | `2.9` | | [io.avaje:avaje-prisms](https://github.com/avaje/avaje-prisms) | `1.36` | `1.37` | | io.helidon.webserver:helidon-webserver | `4.1.5` | `4.1.6` | | io.helidon.webserver:helidon-webserver-security | `4.1.5` | `4.1.6` | | io.helidon.http.media:helidon-http-media-jsonb | `4.1.5` | `4.1.6` | | [io.avaje:avaje-jex](https://github.com/avaje/avaje-jex) | `3.0-RC11` | `3.0-RC12` | | io.avaje:avaje-jex-htmx | `3.0-RC11` | `3.0-RC12` | | [ch.qos.logback:logback-classic](https://github.com/qos-ch/logback) | `1.5.12` | `1.5.15` | | [org.assertj:assertj-core](https://github.com/assertj/assertj) | `3.26.3` | `3.27.0` | Updates `io.javalin:javalin` from 6.3.0 to 6.4.0 - [Release notes](https://github.com/javalin/javalin/releases) - [Commits](https://github.com/javalin/javalin/compare/javalin-parent-6.3.0...javalin-parent-6.4.0) Updates `io.avaje:avaje-spi-service` from 2.8 to 2.9 Updates `io.avaje:avaje-prisms` from 1.36 to 1.37 - [Release notes](https://github.com/avaje/avaje-prisms/releases) - [Commits](https://github.com/avaje/avaje-prisms/compare/1.36...1.37) Updates `io.helidon.webserver:helidon-webserver` from 4.1.5 to 4.1.6 Updates `io.helidon.webserver:helidon-webserver-security` from 4.1.5 to 4.1.6 Updates `io.helidon.http.media:helidon-http-media-jsonb` from 4.1.5 to 4.1.6 Updates `io.helidon.webserver:helidon-webserver-security` from 4.1.5 to 4.1.6 Updates `io.helidon.http.media:helidon-http-media-jsonb` from 4.1.5 to 4.1.6 Updates `io.avaje:avaje-jex` from 3.0-RC11 to 3.0-RC12 - [Release notes](https://github.com/avaje/avaje-jex/releases) - [Commits](https://github.com/avaje/avaje-jex/commits) Updates `io.avaje:avaje-jex-htmx` from 3.0-RC11 to 3.0-RC12 Updates `io.avaje:avaje-jex-htmx` from 3.0-RC11 to 3.0-RC12 Updates `ch.qos.logback:logback-classic` from 1.5.12 to 1.5.15 - [Commits](https://github.com/qos-ch/logback/compare/v_1.5.12...v_1.5.15) Updates `org.assertj:assertj-core` from 3.26.3 to 3.27.0 - [Release notes](https://github.com/assertj/assertj/releases) - [Commits](https://github.com/assertj/assertj/compare/assertj-build-3.26.3...assertj-build-3.27.0) --- updated-dependencies: - dependency-name: io.javalin:javalin dependency-type: direct:development update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.avaje:avaje-spi-service dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.avaje:avaje-prisms dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.helidon.webserver:helidon-webserver dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: io.helidon.webserver:helidon-webserver-security dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: io.helidon.http.media:helidon-http-media-jsonb dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: io.helidon.webserver:helidon-webserver-security dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: io.helidon.http.media:helidon-http-media-jsonb dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: io.avaje:avaje-jex dependency-type: direct:production dependency-group: dependencies - dependency-name: io.avaje:avaje-jex-htmx dependency-type: direct:production dependency-group: dependencies - dependency-name: io.avaje:avaje-jex-htmx dependency-type: direct:production dependency-group: dependencies - dependency-name: ch.qos.logback:logback-classic dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: org.assertj:assertj-core dependency-type: direct:development update-type: version-update:semver-minor dependency-group: dependencies ... Signed-off-by: dependabot[bot] --- htmx-nima-jstache/pom.xml | 2 +- htmx-nima/pom.xml | 2 +- http-api/pom.xml | 2 +- http-client/pom.xml | 2 +- http-inject-plugin/pom.xml | 2 +- pom.xml | 2 +- tests/pom.xml | 8 ++++---- tests/test-client-generation/pom.xml | 2 +- 8 files changed, 11 insertions(+), 11 deletions(-) diff --git a/htmx-nima-jstache/pom.xml b/htmx-nima-jstache/pom.xml index 017950570..6d49feea9 100644 --- a/htmx-nima-jstache/pom.xml +++ b/htmx-nima-jstache/pom.xml @@ -46,7 +46,7 @@ io.avaje avaje-spi-service - 2.8 + 2.9 provided true diff --git a/htmx-nima/pom.xml b/htmx-nima/pom.xml index 0bc859cfe..ec4cb50bb 100644 --- a/htmx-nima/pom.xml +++ b/htmx-nima/pom.xml @@ -26,7 +26,7 @@ io.helidon.webserver helidon-webserver - 4.1.5 + 4.1.6
    diff --git a/http-api/pom.xml b/http-api/pom.xml index e2672b7e3..bd0a64588 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -24,7 +24,7 @@ io.javalin javalin - 6.3.0 + 6.4.0 provided true diff --git a/http-client/pom.xml b/http-client/pom.xml index 06222fc6d..6a617be16 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -66,7 +66,7 @@ io.javalin javalin - 6.3.0 + 6.4.0 test diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index ab557d36c..22519c5c1 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -33,7 +33,7 @@ io.avaje avaje-spi-service - 2.8 + 2.9 provided true diff --git a/pom.xml b/pom.xml index f0b2a7d1f..a1fc58a5a 100644 --- a/pom.xml +++ b/pom.xml @@ -22,7 +22,7 @@ 2.2.27 2.14.2 3.0-RC10 - 1.36 + 1.37 2024-12-16T19:12:09Z ${project.build.directory}${file.separator}module-info.shade diff --git a/tests/pom.xml b/tests/pom.xml index 9015a222b..fc43e6801 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -13,12 +13,12 @@ true 5.11.4 - 3.26.3 + 3.27.0 2.18.2 - 3.0-RC11 + 3.0-RC12 11.0 - 4.1.5 - 6.3.0 + 4.1.6 + 6.4.0 diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index a3c5447c2..95256b081 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -26,7 +26,7 @@ ch.qos.logback logback-classic - 1.5.12 + 1.5.15 From 0bc2fc3d54facb26bf0077f0ae9e731f58dcf96d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Jan 2025 19:59:45 +0000 Subject: [PATCH 1215/1323] Bump the dependencies group with 4 updates Bumps the dependencies group with 4 updates: [io.avaje:avaje-jex](https://github.com/avaje/avaje-jex), io.avaje:avaje-jex-htmx, [ch.qos.logback:logback-classic](https://github.com/qos-ch/logback) and [org.assertj:assertj-core](https://github.com/assertj/assertj). Updates `io.avaje:avaje-jex` from 3.0-RC12 to 3.0-RC13 - [Release notes](https://github.com/avaje/avaje-jex/releases) - [Commits](https://github.com/avaje/avaje-jex/commits) Updates `io.avaje:avaje-jex-htmx` from 3.0-RC12 to 3.0-RC13 Updates `io.avaje:avaje-jex-htmx` from 3.0-RC12 to 3.0-RC13 Updates `ch.qos.logback:logback-classic` from 1.5.15 to 1.5.16 - [Commits](https://github.com/qos-ch/logback/compare/v_1.5.15...v_1.5.16) Updates `org.assertj:assertj-core` from 3.27.0 to 3.27.2 - [Release notes](https://github.com/assertj/assertj/releases) - [Commits](https://github.com/assertj/assertj/compare/assertj-build-3.27.0...assertj-build-3.27.2) --- updated-dependencies: - dependency-name: io.avaje:avaje-jex dependency-type: direct:production dependency-group: dependencies - dependency-name: io.avaje:avaje-jex-htmx dependency-type: direct:production dependency-group: dependencies - dependency-name: io.avaje:avaje-jex-htmx dependency-type: direct:production dependency-group: dependencies - dependency-name: ch.qos.logback:logback-classic dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: org.assertj:assertj-core dependency-type: direct:development update-type: version-update:semver-patch dependency-group: dependencies ... Signed-off-by: dependabot[bot] --- tests/pom.xml | 4 ++-- tests/test-client-generation/pom.xml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/pom.xml b/tests/pom.xml index fc43e6801..0392c65e2 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -13,9 +13,9 @@ true 5.11.4 - 3.27.0 + 3.27.2 2.18.2 - 3.0-RC12 + 3.0-RC13 11.0 4.1.6 6.4.0 diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index 95256b081..8bf9b1a81 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -26,7 +26,7 @@ ch.qos.logback logback-classic - 1.5.15 + 1.5.16 From 34257d6199fcd2fd6a3b37280ce78d5d2cebc084 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sun, 12 Jan 2025 14:10:44 -0500 Subject: [PATCH 1216/1323] Merge pull request #543 from SentryMan/genericIssue Fix JsonB generic generation errors --- .../io/avaje/http/generator/core/Append.java | 13 ++++++ .../avaje/http/generator/core/JsonBUtil.java | 8 ++-- .../io/avaje/http/generator/core/UType.java | 17 ++++++- .../http/generator/core/JsonBUtilTest.java | 46 +++++++++++++++++++ .../myapp/web/test/GenericController.java | 27 +++++++++++ 5 files changed, 107 insertions(+), 4 deletions(-) create mode 100644 http-generator-core/src/test/java/io/avaje/http/generator/core/JsonBUtilTest.java create mode 100644 tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/GenericController.java diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/Append.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/Append.java index 90f89beca..0210f5ec9 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/Append.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/Append.java @@ -8,7 +8,10 @@ */ public class Append { + private static final boolean DEBUG = Boolean.getBoolean("append.debug"); + private final Writer writer; + private final StringBuilder stringBuilder = new StringBuilder(); public Append(Writer writer) { this.writer = writer; @@ -17,6 +20,9 @@ public Append(Writer writer) { public Append append(String content) { try { writer.append(content); + if (DEBUG) { + stringBuilder.append(content); + } return this; } catch (IOException e) { throw new RuntimeException(e); @@ -35,6 +41,9 @@ public void close() { public Append eol() { try { writer.append("\n"); + if (DEBUG) { + stringBuilder.append("\n"); + } return this; } catch (IOException e) { throw new RuntimeException(e); @@ -48,4 +57,8 @@ public Append append(String format, Object... args) { return append(String.format(format, args)); } + @Override + public String toString() { + return stringBuilder.toString(); + } } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java index 212600c96..2a33c04a9 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java @@ -86,12 +86,14 @@ public static void writeJsonbType(UType type, Append writer) { static void writeType(UType type, Append writer) { if (type.isGeneric()) { final var params = - type.importTypes().stream() - .skip(1) + type.params().stream() .map(Util::shortName) + .map(s -> "?".equals(s) ? "Object" : s) .collect(Collectors.joining(".class, ")); - writer.append("Types.newParameterizedType(%s.class, %s.class))", Util.shortName(type.mainType()), params); + writer.append( + "Types.newParameterizedType(%s.class, %s.class))", + Util.shortName(type.mainType()), params); } else { writer.append("%s.class)", Util.shortName(type.mainType())); } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java index 24738fdb3..460a3bcc2 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java @@ -1,6 +1,9 @@ package io.avaje.http.generator.core; import javax.lang.model.type.TypeMirror; + +import static java.util.stream.Collectors.toList; + import java.util.*; public interface UType { @@ -69,6 +72,13 @@ default UType paramRaw() { return null; } + /** + * Return the first generic parameter. + */ + default List params() { + return List.of(); + } + /** * Return the raw type. */ @@ -275,7 +285,7 @@ public String shortType() { @Override public String shortName() { - return shortName.replace(".", "$"); + return shortName.replace(".", "$").replace("?", "Object"); } @Override @@ -293,6 +303,11 @@ public String param1() { return allTypes.size() < 3 ? null : allTypes.get(2); } + @Override + public List params() { + return allTypes.stream().skip(1).collect(toList()); + } + @Override public UType paramRaw() { return rawParamType; diff --git a/http-generator-core/src/test/java/io/avaje/http/generator/core/JsonBUtilTest.java b/http-generator-core/src/test/java/io/avaje/http/generator/core/JsonBUtilTest.java new file mode 100644 index 000000000..838e20313 --- /dev/null +++ b/http-generator-core/src/test/java/io/avaje/http/generator/core/JsonBUtilTest.java @@ -0,0 +1,46 @@ +package io.avaje.http.generator.core; + +import org.junit.jupiter.api.Test; + +import java.io.StringWriter; + +import static org.assertj.core.api.Assertions.assertThat; + +class JsonBUtilTest { + + @Test + void writeType() { + UType uType = UType.parse("my.pack.Foo"); + var sw = new StringWriter(); + JsonBUtil.writeType(uType, new Append(sw)); + + assertThat(sw.toString()).isEqualTo("Foo.class)"); + } + + @Test + void writeType_generic() { + UType uType = UType.parse("my.pack.Some"); + var sw = new StringWriter(); + JsonBUtil.writeType(uType, new Append(sw)); + + assertThat(sw.toString()).isEqualTo("Types.newParameterizedType(Some.class, String.class))"); + } + + @Test + void writeType_genericWithWildcard() { + UType uType = UType.parse("my.pack.Some"); + var sw = new StringWriter(); + JsonBUtil.writeType(uType, new Append(sw)); + + assertThat(sw.toString()).isEqualTo("Types.newParameterizedType(Some.class, String.class, Object.class))"); + } + + @Test + void writeType_genericWithMultiple() { + UType uType = UType.parse("my.pack.Some"); + var sw = new StringWriter(); + JsonBUtil.writeType(uType, new Append(sw)); + + assertThat(sw.toString()).isEqualTo("Types.newParameterizedType(Some.class, String.class, Foo.class))"); + } +} diff --git a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/GenericController.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/GenericController.java new file mode 100644 index 000000000..08f8c7669 --- /dev/null +++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/GenericController.java @@ -0,0 +1,27 @@ +package org.example.myapp.web.test; + +import io.avaje.http.api.Controller; +import io.avaje.http.api.Get; +import io.avaje.http.api.Path; +import io.avaje.jsonb.Json; + +@Path("/jsonbGeneric") +@Controller +public class GenericController { + + @Json + public static class Data {} + + @Json + public static class Data2 {} + + @Get("single") + Data getData() { + return null; + } + + @Get("double") + Data2 getData2() { + return null; + } +} From d7e0b405bd8a92b7f44b7ebdf863e4ff5753a68e Mon Sep 17 00:00:00 2001 From: Daniel Ferrazoli Date: Sun, 12 Jan 2025 16:11:43 -0300 Subject: [PATCH 1217/1323] Add Bearer authentication intercept (#544) Currently, the documentation provides instructions on how to build a bearer token provider, which assumes that tokens are short-lived and must be refreshed after some time. However, some REST APIs offer a bearer token authentication mechanism that relies on the API key/secret instead of short-lived tokens. Since this is a somewhat common use case, I feel like it makes sense to have this implementation offered out of the box. --- .../http/client/BearerTokenIntercept.java | 19 ++++++++++++++ .../http/client/BearerTokenInterceptTest.java | 25 +++++++++++++++++++ 2 files changed, 44 insertions(+) create mode 100644 http-client/src/main/java/io/avaje/http/client/BearerTokenIntercept.java create mode 100644 http-client/src/test/java/io/avaje/http/client/BearerTokenInterceptTest.java diff --git a/http-client/src/main/java/io/avaje/http/client/BearerTokenIntercept.java b/http-client/src/main/java/io/avaje/http/client/BearerTokenIntercept.java new file mode 100644 index 000000000..3d35824a8 --- /dev/null +++ b/http-client/src/main/java/io/avaje/http/client/BearerTokenIntercept.java @@ -0,0 +1,19 @@ +package io.avaje.http.client; + +/** + * Adds a Bearer authentication Authorization header to requests. + */ +public final class BearerTokenIntercept implements RequestIntercept { + + private final String headerValue; + + public BearerTokenIntercept(String token) { + this.headerValue = "Bearer " + token; + } + + @Override + public void beforeRequest(HttpClientRequest request) { + request.header("Authorization", headerValue); + } + +} diff --git a/http-client/src/test/java/io/avaje/http/client/BearerTokenInterceptTest.java b/http-client/src/test/java/io/avaje/http/client/BearerTokenInterceptTest.java new file mode 100644 index 000000000..30949b3fc --- /dev/null +++ b/http-client/src/test/java/io/avaje/http/client/BearerTokenInterceptTest.java @@ -0,0 +1,25 @@ +package io.avaje.http.client; + +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +class BearerTokenInterceptTest { + + @Test + void beforeRequest() { + // setup + final var intercept = new BearerTokenIntercept("api_key"); + final var ctx = HttpClient.builder().baseUrl("junk").build(); + + // act + final HttpClientRequest request = ctx.request(); + intercept.beforeRequest(request); + + final List values = request.header("Authorization"); + assertThat(values).containsExactly("Bearer api_key"); + } + +} From 04005831c47280cd267bf8c557388c1cd0c0116b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 Jan 2025 19:22:04 +0000 Subject: [PATCH 1218/1323] Bump the dependencies group with 6 updates Bumps the dependencies group with 6 updates: | Package | From | To | | --- | --- | --- | | [io.avaje:avaje-jsonb](https://github.com/avaje/avaje-jsonb) | `3.0-RC5` | `3.0-RC6` | | io.avaje:avaje-json-node | `3.0-RC5` | `3.0-RC6` | | [io.avaje:avaje-inject](https://github.com/avaje/avaje-inject) | `11.0` | `11.1` | | io.avaje:avaje-inject-generator | `11.0` | `11.1` | | io.avaje:avaje-inject-maven-plugin | `11.0` | `11.1` | | io.avaje:avaje-json-core | `3.0-RC5` | `3.0-RC6` | Updates `io.avaje:avaje-jsonb` from 3.0-RC5 to 3.0-RC6 - [Release notes](https://github.com/avaje/avaje-jsonb/releases) - [Commits](https://github.com/avaje/avaje-jsonb/commits) Updates `io.avaje:avaje-json-node` from 3.0-RC5 to 3.0-RC6 Updates `io.avaje:avaje-inject` from 11.0 to 11.1 - [Release notes](https://github.com/avaje/avaje-inject/releases) - [Commits](https://github.com/avaje/avaje-inject/compare/11.0...11.1) Updates `io.avaje:avaje-inject-generator` from 11.0 to 11.1 Updates `io.avaje:avaje-inject-generator` from 11.0 to 11.1 Updates `io.avaje:avaje-inject-maven-plugin` from 11.0 to 11.1 Updates `io.avaje:avaje-json-core` from 3.0-RC5 to 3.0-RC6 --- updated-dependencies: - dependency-name: io.avaje:avaje-jsonb dependency-type: direct:production dependency-group: dependencies - dependency-name: io.avaje:avaje-json-node dependency-type: direct:production dependency-group: dependencies - dependency-name: io.avaje:avaje-inject dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.avaje:avaje-inject-generator dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.avaje:avaje-inject-generator dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.avaje:avaje-inject-maven-plugin dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.avaje:avaje-json-core dependency-type: direct:production dependency-group: dependencies ... Signed-off-by: dependabot[bot] --- aws-cognito/http-client-authtoken/pom.xml | 4 ++-- htmx-nima-jstache/pom.xml | 2 +- http-client/pom.xml | 8 ++++---- http-inject-plugin/pom.xml | 2 +- tests/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 4 ++-- tests/test-sigma/pom.xml | 2 +- 9 files changed, 14 insertions(+), 14 deletions(-) diff --git a/aws-cognito/http-client-authtoken/pom.xml b/aws-cognito/http-client-authtoken/pom.xml index 897acf4ed..efbab1311 100644 --- a/aws-cognito/http-client-authtoken/pom.xml +++ b/aws-cognito/http-client-authtoken/pom.xml @@ -23,14 +23,14 @@ io.avaje avaje-json-core - 3.0-RC5 + 3.0-RC6 io.avaje avaje-json-node - 3.0-RC5 + 3.0-RC6 test diff --git a/htmx-nima-jstache/pom.xml b/htmx-nima-jstache/pom.xml index 6d49feea9..f09ca9030 100644 --- a/htmx-nima-jstache/pom.xml +++ b/htmx-nima-jstache/pom.xml @@ -39,7 +39,7 @@ io.avaje avaje-inject - 11.1-RC1 + 11.1 provided true diff --git a/http-client/pom.xml b/http-client/pom.xml index 6a617be16..704363d4a 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -36,21 +36,21 @@ io.avaje avaje-jsonb - 3.0-RC5 + 3.0-RC6 true io.avaje avaje-json-node - 3.0-RC5 + 3.0-RC6 test io.avaje avaje-inject - 11.1-RC1 + 11.1 true @@ -106,7 +106,7 @@ io.avaje avaje-inject-generator - 11.0 + 11.1 diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index 22519c5c1..87ffdce4b 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -19,7 +19,7 @@ io.avaje avaje-inject - 11.1-RC1 + 11.1 provided true diff --git a/tests/pom.xml b/tests/pom.xml index 0392c65e2..ffb8d5a30 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -16,7 +16,7 @@ 3.27.2 2.18.2 3.0-RC13 - 11.0 + 11.1 4.1.6 6.4.0 diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index d067839dc..b0d0b1be1 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -74,7 +74,7 @@ io.avaje avaje-jsonb - 3.0-RC5 + 3.0-RC6 diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 22a091d59..23ca2a4b0 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -74,7 +74,7 @@ io.avaje avaje-jsonb - 3.0-RC5 + 3.0-RC6 diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index a42102826..89d99529c 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -31,7 +31,7 @@ io.avaje avaje-jsonb - 3.0-RC5 + 3.0-RC6 io.helidon.webserver @@ -109,7 +109,7 @@ io.avaje avaje-inject-maven-plugin - 11.0 + 11.1 process-sources diff --git a/tests/test-sigma/pom.xml b/tests/test-sigma/pom.xml index d03256fba..edd8bd6cd 100644 --- a/tests/test-sigma/pom.xml +++ b/tests/test-sigma/pom.xml @@ -67,7 +67,7 @@ io.avaje avaje-jsonb - 3.0-RC5 + 3.0-RC6 io.avaje From c5e24ed2dddb4fa73dd129e21c6e80ab51f7cb23 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Tue, 14 Jan 2025 21:28:28 -0500 Subject: [PATCH 1219/1323] [client] write clients to the same package also make then final --- .../java/io/avaje/http/generator/client/ClientWriter.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientWriter.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientWriter.java index 1291a06eb..b26e02d31 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientWriter.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientWriter.java @@ -37,7 +37,7 @@ final class ClientWriter extends BaseControllerWriter { @Override protected String initPackageName(String originName) { // put the generated Http client into a sub-package - return super.initPackageName(originName) + ".httpclient"; + return super.initPackageName(originName); } private void readMethods() { @@ -73,7 +73,7 @@ private void writeClassStart() { writer.append(AT_GENERATED).eol(); AnnotationUtil.writeAnnotations(writer, reader.beanType()); - writer.append("public class %s%s implements %s, AutoCloseable {", shortName, suffix, shortName).eol().eol(); + writer.append("public final class %s%s implements %s, AutoCloseable {", shortName, suffix, shortName).eol().eol(); writer.append(" private final HttpClient client;").eol().eol(); From 2dfdeca974e1fc15460c51d573a46919fc98843e Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Tue, 14 Jan 2025 21:35:51 -0500 Subject: [PATCH 1220/1323] Update DHttpClientRequestTest.java --- .../test/java/io/avaje/http/client/DHttpClientRequestTest.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/http-client/src/test/java/io/avaje/http/client/DHttpClientRequestTest.java b/http-client/src/test/java/io/avaje/http/client/DHttpClientRequestTest.java index ea25b2535..eea319067 100644 --- a/http-client/src/test/java/io/avaje/http/client/DHttpClientRequestTest.java +++ b/http-client/src/test/java/io/avaje/http/client/DHttpClientRequestTest.java @@ -5,6 +5,7 @@ import java.time.Duration; import java.util.List; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; class DHttpClientRequestTest { @@ -35,6 +36,7 @@ void assertHeader() { } @Test + @Disabled void assertQuery() { final var client = HttpClient.builder().baseUrl("https://ap7i.github.com").build(); From f7bb02ce59eec213b0dae895c54003b754b0743a Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Tue, 14 Jan 2025 21:45:14 -0500 Subject: [PATCH 1221/1323] handle import --- .../java/io/avaje/http/generator/client/ClientWriter.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientWriter.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientWriter.java index b26e02d31..f50b8c162 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientWriter.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientWriter.java @@ -2,6 +2,7 @@ import io.avaje.http.generator.core.APContext; import io.avaje.http.generator.core.BaseControllerWriter; +import io.avaje.http.generator.core.ClientPrism; import io.avaje.http.generator.core.ControllerReader; import io.avaje.http.generator.core.MethodReader; @@ -37,7 +38,9 @@ final class ClientWriter extends BaseControllerWriter { @Override protected String initPackageName(String originName) { // put the generated Http client into a sub-package - return super.initPackageName(originName); + return ClientPrism.isPresent(reader.beanType()) + ? super.initPackageName(originName) + : super.initPackageName(originName)+".httpclient"; } private void readMethods() { From 6b851ac5e0021a1f384467512a21f9d989166e29 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Thu, 16 Jan 2025 12:06:59 +1300 Subject: [PATCH 1222/1323] [client] Generate classes as final (#547) --- .../test/java/io/avaje/http/client/DHttpClientRequestTest.java | 2 ++ .../main/java/io/avaje/http/generator/client/ClientWriter.java | 2 +- .../io/avaje/http/generator/client/SimpleComponentWriter.java | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/http-client/src/test/java/io/avaje/http/client/DHttpClientRequestTest.java b/http-client/src/test/java/io/avaje/http/client/DHttpClientRequestTest.java index ea25b2535..ac7e20619 100644 --- a/http-client/src/test/java/io/avaje/http/client/DHttpClientRequestTest.java +++ b/http-client/src/test/java/io/avaje/http/client/DHttpClientRequestTest.java @@ -5,6 +5,7 @@ import java.time.Duration; import java.util.List; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; class DHttpClientRequestTest { @@ -34,6 +35,7 @@ void assertHeader() { assertThat(headers).asList().contains("application/json", "application/json2"); } + @Disabled @Test void assertQuery() { final var client = HttpClient.builder().baseUrl("https://ap7i.github.com").build(); diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientWriter.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientWriter.java index 1291a06eb..1e6db9124 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientWriter.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientWriter.java @@ -73,7 +73,7 @@ private void writeClassStart() { writer.append(AT_GENERATED).eol(); AnnotationUtil.writeAnnotations(writer, reader.beanType()); - writer.append("public class %s%s implements %s, AutoCloseable {", shortName, suffix, shortName).eol().eol(); + writer.append("public final class %s%s implements %s, AutoCloseable {", shortName, suffix, shortName).eol().eol(); writer.append(" private final HttpClient client;").eol().eol(); diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/SimpleComponentWriter.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/SimpleComponentWriter.java index 28197d3cd..9a5f05809 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/SimpleComponentWriter.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/SimpleComponentWriter.java @@ -81,7 +81,7 @@ private void writeClassStart() { final List all = metaData.all(); writeMetaDataEntry(all); writer.append("})").eol(); - writer.append("public class %s implements HttpClient.GeneratedComponent {", shortName).eol().eol(); + writer.append("public final class %s implements HttpClient.GeneratedComponent {", shortName).eol().eol(); } private void writeMetaDataEntry(List entries) { From 611af3969f78c9968c2ab9a7750fd0fe86adcbed Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Wed, 15 Jan 2025 18:09:54 -0500 Subject: [PATCH 1223/1323] Update DHttpClientRequestTest.java --- .../test/java/io/avaje/http/client/DHttpClientRequestTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/http-client/src/test/java/io/avaje/http/client/DHttpClientRequestTest.java b/http-client/src/test/java/io/avaje/http/client/DHttpClientRequestTest.java index 7432da455..ac7e20619 100644 --- a/http-client/src/test/java/io/avaje/http/client/DHttpClientRequestTest.java +++ b/http-client/src/test/java/io/avaje/http/client/DHttpClientRequestTest.java @@ -37,7 +37,6 @@ void assertHeader() { @Disabled @Test - @Disabled void assertQuery() { final var client = HttpClient.builder().baseUrl("https://ap7i.github.com").build(); From 95bd3d2ded4c2975945db62c9681ec0aaf3b6c28 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Wed, 15 Jan 2025 23:46:26 -0500 Subject: [PATCH 1224/1323] respect visibility choice --- .../java/io/avaje/http/generator/client/ClientWriter.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientWriter.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientWriter.java index f50b8c162..643525135 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientWriter.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientWriter.java @@ -12,6 +12,8 @@ import java.util.List; import java.util.Set; +import javax.lang.model.element.Modifier; + /** * Write Http client adapter. */ @@ -38,9 +40,11 @@ final class ClientWriter extends BaseControllerWriter { @Override protected String initPackageName(String originName) { // put the generated Http client into a sub-package - return ClientPrism.isPresent(reader.beanType()) + final var beanType = reader.beanType(); + + return !beanType.getModifiers().contains(Modifier.PUBLIC) && ClientPrism.isPresent(beanType) ? super.initPackageName(originName) - : super.initPackageName(originName)+".httpclient"; + : super.initPackageName(originName) + ".httpclient"; } private void readMethods() { From 3ffb9c1f5c4ad68048d3c7857ad73b4fa4e0f5f9 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Thu, 16 Jan 2025 17:57:02 +1300 Subject: [PATCH 1225/1323] [client] Followup #546 - put GeneratedHttpComponent into top package Don't always put GeneratedHttpComponent into .httpclient as the client interface might NOT be public now with 546 --- .../java/io/avaje/http/generator/client/ComponentMetaData.java | 3 --- .../src/main/java/org/example/JunkApi.java | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ComponentMetaData.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ComponentMetaData.java index ebd963150..ac0866394 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ComponentMetaData.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ComponentMetaData.java @@ -28,9 +28,6 @@ void setFullName(String fullName) { String fullName() { if (fullName == null) { String topPackage = TopPackage.of(generatedClients); - if (!topPackage.endsWith(".httpclient")) { - topPackage += ".httpclient"; - } fullName = topPackage + ".GeneratedHttpComponent"; } return fullName; diff --git a/tests/test-client-generation/src/main/java/org/example/JunkApi.java b/tests/test-client-generation/src/main/java/org/example/JunkApi.java index a446a8c78..bf4da6b3c 100644 --- a/tests/test-client-generation/src/main/java/org/example/JunkApi.java +++ b/tests/test-client-generation/src/main/java/org/example/JunkApi.java @@ -13,7 +13,7 @@ import java.util.stream.Stream; @Client -public interface JunkApi { +interface JunkApi { @Post void asVoid(); From cb3a04b5756dd3b85268eee0e204b67f3187c5e9 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Thu, 16 Jan 2025 18:00:08 +1300 Subject: [PATCH 1226/1323] Tidy test poms with auto included avaje-inject-maven-plugin --- tests/test-client-generation/pom.xml | 14 ++++++ .../src/main/resources/public/openapi.json | 48 +++++++++++++++++++ tests/test-nima-htmx/pom.xml | 14 ++++++ tests/test-nima/pom.xml | 14 ++++++ 4 files changed, 90 insertions(+) diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index 8bf9b1a81..e6ab951ee 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -137,6 +137,20 @@ + + + io.avaje + avaje-inject-maven-plugin + 11.1 + + + process-sources + + provides + + + +
    diff --git a/tests/test-javalin-jsonb/src/main/resources/public/openapi.json b/tests/test-javalin-jsonb/src/main/resources/public/openapi.json index 00d934e26..4ce0e1d13 100644 --- a/tests/test-javalin-jsonb/src/main/resources/public/openapi.json +++ b/tests/test-javalin-jsonb/src/main/resources/public/openapi.json @@ -928,6 +928,48 @@ } } }, + "/jsonbGeneric/double" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/String,?>" + } + } + } + } + } + } + }, + "/jsonbGeneric/single" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/String>" + } + } + } + } + } + } + }, "/openapi/get" : { "get" : { "tags" : [ @@ -2188,6 +2230,12 @@ "type" : "string" } } + }, + "String,?>" : { + "type" : "object" + }, + "String>" : { + "type" : "object" } }, "securitySchemes" : { diff --git a/tests/test-nima-htmx/pom.xml b/tests/test-nima-htmx/pom.xml index 355bdeead..0d22ede74 100644 --- a/tests/test-nima-htmx/pom.xml +++ b/tests/test-nima-htmx/pom.xml @@ -99,6 +99,20 @@
    + + + io.avaje + avaje-inject-maven-plugin + 11.1 + + + process-sources + + provides + + + +
    diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index 80f3d8c1d..72b47255a 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -86,6 +86,20 @@ + + + io.avaje + avaje-inject-maven-plugin + 11.1 + + + process-sources + + provides + + + + From 25d13baa6599b1fba13bdb9cc6854b1a45580a11 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Thu, 16 Jan 2025 18:17:44 +1300 Subject: [PATCH 1227/1323] Version 2.9-RC8 --- htmx-api/pom.xml | 2 +- htmx-nima-jstache/pom.xml | 2 +- htmx-nima/pom.xml | 4 ++-- http-api-javalin/pom.xml | 2 +- http-api/pom.xml | 2 +- http-client-gson-adapter/pom.xml | 4 ++-- http-client-moshi-adapter/pom.xml | 4 ++-- http-client/pom.xml | 2 +- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 2 +- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-generator-sigma/pom.xml | 2 +- http-inject-plugin/pom.xml | 2 +- pom.xml | 4 ++-- tests/pom.xml | 2 +- tests/test-client-generation/pom.xml | 2 +- tests/test-client/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-htmx/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- tests/test-sigma/pom.xml | 2 +- 26 files changed, 30 insertions(+), 30 deletions(-) diff --git a/htmx-api/pom.xml b/htmx-api/pom.xml index 6036c051c..c38b1230a 100644 --- a/htmx-api/pom.xml +++ b/htmx-api/pom.xml @@ -6,7 +6,7 @@ io.avaje avaje-http-parent - 2.9-RC7 + 2.9-RC8 avaje-htmx-api diff --git a/htmx-nima-jstache/pom.xml b/htmx-nima-jstache/pom.xml index f09ca9030..988f879e4 100644 --- a/htmx-nima-jstache/pom.xml +++ b/htmx-nima-jstache/pom.xml @@ -6,7 +6,7 @@ io.avaje avaje-http-parent - 2.9-RC7 + 2.9-RC8 avaje-htmx-nima-jstache diff --git a/htmx-nima/pom.xml b/htmx-nima/pom.xml index ec4cb50bb..1669c9244 100644 --- a/htmx-nima/pom.xml +++ b/htmx-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje avaje-http-parent - 2.9-RC7 + 2.9-RC8 avaje-htmx-nima @@ -21,7 +21,7 @@ io.avaje avaje-htmx-api - 2.9-RC7 + 2.9-RC8 io.helidon.webserver diff --git a/http-api-javalin/pom.xml b/http-api-javalin/pom.xml index 660440702..3f03ac99d 100644 --- a/http-api-javalin/pom.xml +++ b/http-api-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.9-RC7 + 2.9-RC8 .. diff --git a/http-api/pom.xml b/http-api/pom.xml index bd0a64588..0c2623694 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.9-RC7 + 2.9-RC8 .. diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index ee8114667..79ae60e5a 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.9-RC7 + 2.9-RC8 avaje-http-client-gson @@ -20,7 +20,7 @@ io.avaje avaje-http-client - 2.9-RC7 + 2.9-RC8 provided diff --git a/http-client-moshi-adapter/pom.xml b/http-client-moshi-adapter/pom.xml index 22a0ceaca..ca2219f16 100644 --- a/http-client-moshi-adapter/pom.xml +++ b/http-client-moshi-adapter/pom.xml @@ -3,7 +3,7 @@ io.avaje avaje-http-parent - 2.9-RC7 + 2.9-RC8 avaje-http-client-moshi @@ -19,7 +19,7 @@ io.avaje avaje-http-client - 2.9-RC7 + 2.9-RC8 provided diff --git a/http-client/pom.xml b/http-client/pom.xml index 704363d4a..6909b1bc7 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.9-RC7 + 2.9-RC8 avaje-http-client diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index ad8b28d65..2db339d1a 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.9-RC7 + 2.9-RC8 avaje-http-client-generator diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 7afa5e4f5..f922da9f7 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.9-RC7 + 2.9-RC8 avaje-http-generator-core diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index 375ecd511..9d217834f 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.9-RC7 + 2.9-RC8 avaje-http-helidon-generator diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index cd9c7de4d..a6612e388 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.9-RC7 + 2.9-RC8 avaje-http-javalin-generator diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index dff8320a6..493cfefb5 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.9-RC7 + 2.9-RC8 avaje-http-jex-generator diff --git a/http-generator-sigma/pom.xml b/http-generator-sigma/pom.xml index eea06c4b3..c2b88c543 100644 --- a/http-generator-sigma/pom.xml +++ b/http-generator-sigma/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.9-RC7 + 2.9-RC8 avaje-http-sigma-generator diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index 87ffdce4b..f832d5efc 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.9-RC7 + 2.9-RC8 .. diff --git a/pom.xml b/pom.xml index a1fc58a5a..0880e88b9 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-parent - 2.9-RC7 + 2.9-RC8 pom @@ -23,7 +23,7 @@ 2.14.2 3.0-RC10 1.37 - 2024-12-16T19:12:09Z + 2025-01-16T05:02:23Z ${project.build.directory}${file.separator}module-info.shade diff --git a/tests/pom.xml b/tests/pom.xml index ffb8d5a30..a701a972e 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.9-RC7 + 2.9-RC8 tests diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index e6ab951ee..b52189471 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.9-RC7 + 2.9-RC8 test-client-generation diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index 18909553a..0c40e2560 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.9-RC7 + 2.9-RC8 test-client diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index b0d0b1be1..7335d45da 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 2.9-RC7 + 2.9-RC8 test-javalin-jsonb diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index b807e2357..91d0ffa20 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.9-RC7 + 2.9-RC8 test-javalin diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 23ca2a4b0..9ed3afb59 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.9-RC7 + 2.9-RC8 test-jex diff --git a/tests/test-nima-htmx/pom.xml b/tests/test-nima-htmx/pom.xml index 0d22ede74..451cf39cf 100644 --- a/tests/test-nima-htmx/pom.xml +++ b/tests/test-nima-htmx/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.9-RC7 + 2.9-RC8 test-nima-htmx diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 89d99529c..90df6c9a1 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.9-RC7 + 2.9-RC8 test-nima-jsonb diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index 72b47255a..0cd4babff 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.9-RC7 + 2.9-RC8 test-nima diff --git a/tests/test-sigma/pom.xml b/tests/test-sigma/pom.xml index edd8bd6cd..62b784609 100644 --- a/tests/test-sigma/pom.xml +++ b/tests/test-sigma/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 2.9-RC7 + 2.9-RC8 test-sigma From 8e70331f4c3ae87546af9b6f5ce453b81a6f2f6b Mon Sep 17 00:00:00 2001 From: Lukas Determann Date: Sat, 18 Jan 2025 17:55:23 +0100 Subject: [PATCH 1228/1323] added support for Optional Request Parameters --- .../io/avaje/http/api/PathTypeConversion.java | 5 ++ .../http/generator/core/ElementReader.java | 13 ++-- .../io/avaje/http/generator/core/TypeMap.java | 63 +++++++++++++++++++ .../io/avaje/http/generator/core/UType.java | 3 +- .../org/example/web/myapp/WebController.java | 19 ++++++ 5 files changed, 98 insertions(+), 5 deletions(-) diff --git a/http-api/src/main/java/io/avaje/http/api/PathTypeConversion.java b/http-api/src/main/java/io/avaje/http/api/PathTypeConversion.java index 9bd7568cc..40a72f5f9 100644 --- a/http-api/src/main/java/io/avaje/http/api/PathTypeConversion.java +++ b/http-api/src/main/java/io/avaje/http/api/PathTypeConversion.java @@ -4,6 +4,7 @@ import java.time.*; import java.math.BigInteger; import java.util.List; +import java.util.Optional; import java.util.Set; import java.util.UUID; import java.util.function.Function; @@ -60,6 +61,10 @@ public static Set set(Function func, List params) { return params.stream().map(func).collect(Collectors.toSet()); } + public static Optional optional(Function func, String value) { + return Optional.ofNullable(func.apply(value)); + } + /** Convert to int. */ public static int asInt(String value) { checkNull(value); diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java index 358a8d85b..d030763d1 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java @@ -119,18 +119,23 @@ TypeHandler initTypeHandler() { final var isMap = !isCollection && typeOp.filter(t -> t.mainType().startsWith("java.util.Map")).isPresent(); + final var isOptional = typeOp.filter(t -> t.mainType().startsWith("java.util.Optional")).isPresent(); + if (mainTypeEnum) { return TypeMap.enumParamHandler(typeOp.orElseThrow()); - } else if (isCollection) { - this.isParamCollection = true; - final var isEnumCollection = + } else if (isCollection || isOptional) { + final var isEnumContainer = typeOp .flatMap(t -> Optional.ofNullable(typeElement(t.param0()))) .map(TypeElement::getKind) .filter(ElementKind.ENUM::equals) .isPresent(); - return TypeMap.collectionHandler(typeOp.orElseThrow(), isEnumCollection); + if (isOptional) {//Needs to be checked first, as 'isCollection' is too broad + return TypeMap.optionalHandler(typeOp.orElseThrow(), isEnumContainer); + } + this.isParamCollection = true; + return TypeMap.collectionHandler(typeOp.orElseThrow(), isEnumContainer); } else if (isMap) { this.isParamMap = true; return new TypeMap.StringHandler(); diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/TypeMap.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/TypeMap.java index 037b69507..a77c02f06 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/TypeMap.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/TypeMap.java @@ -62,6 +62,21 @@ static TypeHandler collectionHandler(UType type, boolean isEnum) { isEnum)); } + static TypeHandler optionalHandler(UType type, boolean isEnum) { + final var handler = types.get(type.param0()); + + if (!isEnum && handler == null) { + return null; + } + + return types.computeIfAbsent( + type.full(), + k -> + new OptionalHandler( + isEnum ? enumParamHandler(type.paramRaw()) : handler, + isEnum)); + } + static TypeHandler enumParamHandler(UType type) { return new EnumHandler(type); } @@ -374,6 +389,54 @@ public String toMethod() { } } + static class OptionalHandler implements TypeHandler { + + private final List importTypes; + private final String shortName; + private String toMethod; + + OptionalHandler(TypeHandler handler, boolean isEnum) { + + this.importTypes = new ArrayList<>(handler.importTypes()); + importTypes.add("io.avaje.http.api.PathTypeConversion"); + this.shortName = handler.shortName(); + this.toMethod = + "optional(" + + (isEnum + ? "qp -> " + handler.toMethod() + " qp)" + : "PathTypeConversion::as" + shortName) + + ", "; + + this.toMethod = toMethod.replace("PathTypeConversion::asString", "Object::toString"); + } + + @Override + public boolean isPrimitive() { + return false; + } + + @Override + public List importTypes() { + + return importTypes; + } + + @Override + public String shortName() { + return shortName; + } + + @Override + public String asMethod() { + return null; + } + + @Override + public String toMethod() { + return toMethod; + } + } + abstract static class ObjectHandler implements TypeHandler { private final String importType; diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java index 460a3bcc2..5f6951279 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/UType.java @@ -66,7 +66,7 @@ default String param1() { } /** - * Return the raw generic parameter if this UType is a Collection. + * Return the raw generic parameter if this UType is a Collection or an Optional. */ default UType paramRaw() { return null; @@ -212,6 +212,7 @@ private String extractRawParam() { switch (mainType()) { case "java.util.Set": case "java.util.List": + case "java.util.Optional": case "java.util.stream.Stream": case "java.net.http.HttpResponse": case "java.util.concurrent.CompletableFuture": diff --git a/tests/test-jex/src/main/java/org/example/web/myapp/WebController.java b/tests/test-jex/src/main/java/org/example/web/myapp/WebController.java index ae51b7e8f..81c9601eb 100644 --- a/tests/test-jex/src/main/java/org/example/web/myapp/WebController.java +++ b/tests/test-jex/src/main/java/org/example/web/myapp/WebController.java @@ -5,6 +5,7 @@ import java.time.LocalDate; import java.util.ArrayList; import java.util.List; +import java.util.Optional; import java.util.concurrent.CompletableFuture; import java.util.concurrent.Executors; @@ -176,4 +177,22 @@ String controlStatusCode(Context ctx) { String takesNestedEnum(Foo.NestedEnum myEnum) { return "takesNestedEnum-" + myEnum; } + + @Produces(value = "text/plain") + @Get("takesOptional{myOptional}") + String takesOptional(@QueryParam("myOptional") Optional myOptional) { + return "takesOptional-" + myOptional; + } + + @Produces(value = "text/plain") + @Get("takesOptionalEnum{myOptional}") + String takesOptionalEnum(@QueryParam("myOptional") Optional myOptional) { + return "takesOptionalEnum-" + myOptional; + } + + @Produces(value = "text/plain") + @Get("takesOptionalEnum{myOptional}") + String takesOptionalString(@QueryParam("myOptional") Optional myOptional) { + return "takesOptionalString-" + myOptional; + } } From 8d6696385fa6859eadbeb933d2034c767bb49e9b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 20 Jan 2025 19:50:38 +0000 Subject: [PATCH 1229/1323] Bump the dependencies group with 5 updates Bumps the dependencies group with 5 updates: | Package | From | To | | --- | --- | --- | | io.swagger.core.v3:swagger-models | `2.2.27` | `2.2.28` | | io.swagger.core.v3:swagger-annotations | `2.2.27` | `2.2.28` | | [io.avaje:avaje-jex](https://github.com/avaje/avaje-jex) | `3.0-RC13` | `3.0-RC14` | | io.avaje:avaje-jex-htmx | `3.0-RC13` | `3.0-RC14` | | [org.assertj:assertj-core](https://github.com/assertj/assertj) | `3.27.2` | `3.27.3` | Updates `io.swagger.core.v3:swagger-models` from 2.2.27 to 2.2.28 Updates `io.swagger.core.v3:swagger-annotations` from 2.2.27 to 2.2.28 Updates `io.swagger.core.v3:swagger-annotations` from 2.2.27 to 2.2.28 Updates `io.avaje:avaje-jex` from 3.0-RC13 to 3.0-RC14 - [Release notes](https://github.com/avaje/avaje-jex/releases) - [Commits](https://github.com/avaje/avaje-jex/commits) Updates `io.avaje:avaje-jex-htmx` from 3.0-RC13 to 3.0-RC14 Updates `io.avaje:avaje-jex-htmx` from 3.0-RC13 to 3.0-RC14 Updates `org.assertj:assertj-core` from 3.27.2 to 3.27.3 - [Release notes](https://github.com/assertj/assertj/releases) - [Commits](https://github.com/assertj/assertj/compare/assertj-build-3.27.2...assertj-build-3.27.3) --- updated-dependencies: - dependency-name: io.swagger.core.v3:swagger-models dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: io.swagger.core.v3:swagger-annotations dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: io.swagger.core.v3:swagger-annotations dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: io.avaje:avaje-jex dependency-type: direct:production dependency-group: dependencies - dependency-name: io.avaje:avaje-jex-htmx dependency-type: direct:production dependency-group: dependencies - dependency-name: io.avaje:avaje-jex-htmx dependency-type: direct:production dependency-group: dependencies - dependency-name: org.assertj:assertj-core dependency-type: direct:development update-type: version-update:semver-patch dependency-group: dependencies ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- tests/pom.xml | 4 ++-- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-sigma/pom.xml | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/pom.xml b/pom.xml index 0880e88b9..20f78eb6a 100644 --- a/pom.xml +++ b/pom.xml @@ -19,7 +19,7 @@ true - 2.2.27 + 2.2.28 2.14.2 3.0-RC10 1.37 diff --git a/tests/pom.xml b/tests/pom.xml index a701a972e..9dc38791c 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -13,9 +13,9 @@ true 5.11.4 - 3.27.2 + 3.27.3 2.18.2 - 3.0-RC13 + 3.0-RC14 11.1 4.1.6 6.4.0 diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 7335d45da..5ce8b8a23 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -13,7 +13,7 @@ true org.example.myapp.Main - 2.2.27 + 2.2.28 1.3.71 diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 91d0ffa20..8fdd0a68a 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -12,7 +12,7 @@ true org.example.myapp.Main - 2.2.27 + 2.2.28 1.3.71 diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 9ed3afb59..066a881a4 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -12,7 +12,7 @@ 21 true org.example.myapp.Main - 2.2.27 + 2.2.28 diff --git a/tests/test-sigma/pom.xml b/tests/test-sigma/pom.xml index 62b784609..8cd6000c4 100644 --- a/tests/test-sigma/pom.xml +++ b/tests/test-sigma/pom.xml @@ -13,7 +13,7 @@ 17 true - 2.2.27 + 2.2.28 1.3.71 From 62218b4cd25ab23e838c64885fc3aa9493715ffe Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Sun, 26 Jan 2025 16:54:44 +1300 Subject: [PATCH 1230/1323] Fix PR #550 Optional type wrapping of query parameters (#555) - Adds tests that were missing in HelloControllerTest that actually exercises the feature - Fixes the controller URLs removing incorrect {myOptional} from urls - Fixes PathTypeConversion to handle null values - Adds missing javadoc on new public methods of PathTypeConversion - Adds some useful unit tests for TypeMap.OptionalHandler --- .../io/avaje/http/api/PathTypeConversion.java | 48 ++++++++++--- .../io/avaje/http/generator/core/TypeMap.java | 28 ++++---- .../http/generator/core/TypeMapTest.java | 21 ++++++ .../org/example/web/myapp/WebController.java | 13 ++-- .../org/example/web/HelloControllerTest.java | 70 +++++++++++++++++++ 5 files changed, 152 insertions(+), 28 deletions(-) diff --git a/http-api/src/main/java/io/avaje/http/api/PathTypeConversion.java b/http-api/src/main/java/io/avaje/http/api/PathTypeConversion.java index 40a72f5f9..55706c0b1 100644 --- a/http-api/src/main/java/io/avaje/http/api/PathTypeConversion.java +++ b/http-api/src/main/java/io/avaje/http/api/PathTypeConversion.java @@ -53,19 +53,42 @@ private static void checkNull(String value) { } } - public static List list(Function func, List params) { - return params.stream().map(func).collect(Collectors.toList()); + /** + * Return the list of parameters using a type conversion function. + */ + public static List list(Function typeConversion, List params) { + return params.stream().map(typeConversion).collect(Collectors.toList()); } - public static Set set(Function func, List params) { - return params.stream().map(func).collect(Collectors.toSet()); + /** + * Return the parameters as a Set using a type conversion function. + */ + public static Set set(Function typeConversion, List params) { + return params.stream().map(typeConversion).collect(Collectors.toSet()); } - public static Optional optional(Function func, String value) { - return Optional.ofNullable(func.apply(value)); + /** + * Return an Optional taking a type conversion function and string value. + * + * @param typeConversion The type conversion function + * @param value The nullable value + * @param The ty + * @return The Optional typed value + */ + public static Optional optional(Function typeConversion, String value) { + return value == null ? Optional.empty() : Optional.ofNullable(typeConversion.apply(value)); } - /** Convert to int. */ + /** + * Return an Optional for a nullable String value. + */ + public static Optional optional(String value) { + return Optional.ofNullable(value); + } + + /** + * Convert to int. + */ public static int asInt(String value) { checkNull(value); try { @@ -75,7 +98,9 @@ public static int asInt(String value) { } } - /** Convert to enum. */ + /** + * Convert to enum. + */ @SuppressWarnings({"rawtypes"}) public static Enum asEnum(Class clazz, String value) { checkNull(value); @@ -86,6 +111,9 @@ public static Enum asEnum(Class clazz, String value) { } } + /** + * Convert to an Enum of the given type. + */ @SuppressWarnings({"unchecked", "rawtypes"}) public static Enum convertEnum(Class clazz, String value) { try { @@ -260,7 +288,9 @@ public static Integer asInteger(String value) { } } - /** Convert to enum. */ + /** + * Convert to enum of the given type. + */ @SuppressWarnings({"rawtypes"}) public static Enum toEnum(Class clazz, String value) { if (isNullOrEmpty(value)) { diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/TypeMap.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/TypeMap.java index a77c02f06..9a5d6d455 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/TypeMap.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/TypeMap.java @@ -347,9 +347,8 @@ static class CollectionHandler implements TypeHandler { private String toMethod; CollectionHandler(TypeHandler handler, boolean set, boolean isEnum) { - this.importTypes = new ArrayList<>(handler.importTypes()); - importTypes.add("io.avaje.http.api.PathTypeConversion"); + this.importTypes.add("io.avaje.http.api.PathTypeConversion"); this.shortName = handler.shortName(); this.toMethod = (set ? "set" : "list") @@ -369,7 +368,6 @@ public boolean isPrimitive() { @Override public List importTypes() { - return importTypes; } @@ -393,21 +391,24 @@ static class OptionalHandler implements TypeHandler { private final List importTypes; private final String shortName; - private String toMethod; + private final String toMethod; OptionalHandler(TypeHandler handler, boolean isEnum) { - this.importTypes = new ArrayList<>(handler.importTypes()); - importTypes.add("io.avaje.http.api.PathTypeConversion"); + this.importTypes.add("io.avaje.http.api.PathTypeConversion"); this.shortName = handler.shortName(); - this.toMethod = - "optional(" - + (isEnum - ? "qp -> " + handler.toMethod() + " qp)" - : "PathTypeConversion::as" + shortName) - + ", "; + this.toMethod = buildToMethod(handler, isEnum); + } - this.toMethod = toMethod.replace("PathTypeConversion::asString", "Object::toString"); + static String buildToMethod(TypeHandler handler, boolean isEnum) { + if (isEnum) { + return "optional(qp -> " + handler.toMethod() + " qp), "; + } + if ("String".equals(handler.shortName())) { + return "optional("; + } else { + return "optional(PathTypeConversion::as" + handler.shortName() + ", "; + } } @Override @@ -417,7 +418,6 @@ public boolean isPrimitive() { @Override public List importTypes() { - return importTypes; } diff --git a/http-generator-core/src/test/java/io/avaje/http/generator/core/TypeMapTest.java b/http-generator-core/src/test/java/io/avaje/http/generator/core/TypeMapTest.java index ead716fd3..b91cad8e3 100644 --- a/http-generator-core/src/test/java/io/avaje/http/generator/core/TypeMapTest.java +++ b/http-generator-core/src/test/java/io/avaje/http/generator/core/TypeMapTest.java @@ -69,4 +69,25 @@ void get_BigInt() { assertThat(handler.asMethod()).isEqualTo("asBigInteger("); assertFalse(handler.isPrimitive()); } + + @Test + void get_OptionalInteger() { + TypeHandler handler = TypeMap.get("java.lang.Integer"); + TypeMap.OptionalHandler optionalHandler = new TypeMap.OptionalHandler(handler, false); + assertThat(optionalHandler.toMethod()).isEqualTo("optional(PathTypeConversion::asInteger, "); + } + + @Test + void get_OptionalString() { + TypeHandler handler = TypeMap.get("java.lang.String"); + TypeMap.OptionalHandler optionalHandler = new TypeMap.OptionalHandler(handler, false); + assertThat(optionalHandler.toMethod()).isEqualTo("optional("); + } + + @Test + void get_OptionalEnum() { + TypeHandler handler = TypeMap.enumParamHandler(UType.parse("org.my.MyEnum")); + TypeMap.OptionalHandler optionalHandler = new TypeMap.OptionalHandler(handler, true); + assertThat(optionalHandler.toMethod()).isEqualTo("optional(qp -> (MyEnum) toEnum(MyEnum.class, qp), "); + } } diff --git a/tests/test-jex/src/main/java/org/example/web/myapp/WebController.java b/tests/test-jex/src/main/java/org/example/web/myapp/WebController.java index 81c9601eb..ca73d0542 100644 --- a/tests/test-jex/src/main/java/org/example/web/myapp/WebController.java +++ b/tests/test-jex/src/main/java/org/example/web/myapp/WebController.java @@ -178,21 +178,24 @@ String takesNestedEnum(Foo.NestedEnum myEnum) { return "takesNestedEnum-" + myEnum; } + @SuppressWarnings("OptionalUsedAsFieldOrParameterType") @Produces(value = "text/plain") - @Get("takesOptional{myOptional}") - String takesOptional(@QueryParam("myOptional") Optional myOptional) { + @Get("takesOptional") + String takesOptional(Optional myOptional) { return "takesOptional-" + myOptional; } + @SuppressWarnings("OptionalUsedAsFieldOrParameterType") @Produces(value = "text/plain") - @Get("takesOptionalEnum{myOptional}") + @Get("takesOptionalEnum") String takesOptionalEnum(@QueryParam("myOptional") Optional myOptional) { return "takesOptionalEnum-" + myOptional; } + @SuppressWarnings("OptionalUsedAsFieldOrParameterType") @Produces(value = "text/plain") - @Get("takesOptionalEnum{myOptional}") - String takesOptionalString(@QueryParam("myOptional") Optional myOptional) { + @Get("takesOptionalString") + String takesOptionalString(@QueryParam Optional myOptional) { return "takesOptionalString-" + myOptional; } } diff --git a/tests/test-jex/src/test/java/org/example/web/HelloControllerTest.java b/tests/test-jex/src/test/java/org/example/web/HelloControllerTest.java index 28b2ab993..499e6c1c5 100644 --- a/tests/test-jex/src/test/java/org/example/web/HelloControllerTest.java +++ b/tests/test-jex/src/test/java/org/example/web/HelloControllerTest.java @@ -106,4 +106,74 @@ void validation_expect_HttpException() { final ErrorResponse errBean = ex.bean(ErrorResponse.class); assertThat(errBean.get("name")).isEqualTo("must not be null"); } + + @Test + void optionalQueryParamLong() { + HttpResponse res = client.request() + .path("hello/takesOptional") + .GET() + .asString(); + + assertThat(res.statusCode()).isEqualTo(200); + assertThat(res.body()).isEqualTo("takesOptional-Optional.empty"); + } + + @Test + void optionalQueryParamLong_withValue() { + HttpResponse res = client.request() + .path("hello/takesOptional") + .queryParam("myOptional","42") + .GET() + .asString(); + + assertThat(res.statusCode()).isEqualTo(200); + assertThat(res.body()).isEqualTo("takesOptional-Optional[42]"); + } + + @Test + void optionalQueryParamEnum() { + HttpResponse res = client.request() + .path("hello/takesOptionalEnum") + .GET() + .asString(); + + assertThat(res.statusCode()).isEqualTo(200); + assertThat(res.body()).isEqualTo("takesOptionalEnum-Optional.empty"); + } + + @Test + void optionalQueryParamEnum_withValue() { + HttpResponse res = client.request() + .path("hello/takesOptionalEnum") + .queryParam("myOptional","B") + .GET() + .asString(); + + assertThat(res.statusCode()).isEqualTo(200); + assertThat(res.body()).isEqualTo("takesOptionalEnum-Optional[B]"); + } + + @Test + void optionalQueryParamString() { + HttpResponse res = client.request() + .path("hello/takesOptionalString") + .GET() + .asString(); + + assertThat(res.statusCode()).isEqualTo(200); + assertThat(res.body()).isEqualTo("takesOptionalString-Optional.empty"); + } + + @Test + void optionalQueryParamString_withValue() { + HttpResponse res = client.request() + .path("hello/takesOptionalString") + .queryParam("myOptional","foo") + .GET() + .asString(); + + assertThat(res.statusCode()).isEqualTo(200); + assertThat(res.body()).isEqualTo("takesOptionalString-Optional[foo]"); + } + } From c8b75e961abcdab0d619af191d86bed8f7470e8f Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Sun, 26 Jan 2025 18:10:17 +1300 Subject: [PATCH 1231/1323] Tidy generator-core TypeMap with final modifiers and add unit tests (#556) --- .../io/avaje/http/generator/core/TypeMap.java | 102 +++++++++--------- .../http/generator/core/TypeMapTest.java | 63 +++++++++-- 2 files changed, 106 insertions(+), 59 deletions(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/TypeMap.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/TypeMap.java index 9a5d6d455..8b6452f5b 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/TypeMap.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/TypeMap.java @@ -10,7 +10,7 @@ *

    * These types convert from String to types on controller methods. */ -class TypeMap { +final class TypeMap { private static final Map types = new HashMap<>(); @@ -48,40 +48,25 @@ static TypeHandler get(String type) { static TypeHandler collectionHandler(UType type, boolean isEnum) { final var handler = types.get(type.param0()); - if (!isEnum && handler == null) { return null; } - - return types.computeIfAbsent( - type.full(), - k -> - new CollectionHandler( - isEnum ? enumParamHandler(type.paramRaw()) : handler, - type.mainType().startsWith("java.util.Set"), - isEnum)); + return types.computeIfAbsent(type.full(), k -> CollectionHandler.of(type, isEnum, handler)); } static TypeHandler optionalHandler(UType type, boolean isEnum) { final var handler = types.get(type.param0()); - if (!isEnum && handler == null) { return null; } - - return types.computeIfAbsent( - type.full(), - k -> - new OptionalHandler( - isEnum ? enumParamHandler(type.paramRaw()) : handler, - isEnum)); + return types.computeIfAbsent(type.full(), k -> OptionalHandler.of(type, isEnum, handler)); } static TypeHandler enumParamHandler(UType type) { return new EnumHandler(type); } - static class StringHandler extends JavaLangType { + static final class StringHandler extends JavaLangType { StringHandler() { super("String"); } @@ -97,7 +82,7 @@ public String toMethod() { } } - static class IntegerHandler extends JavaLangType { + static final class IntegerHandler extends JavaLangType { IntegerHandler() { super("Integer"); } @@ -113,13 +98,13 @@ public String toMethod() { } } - static class IntHandler extends Primitive { + static final class IntHandler extends Primitive { IntHandler() { super("Int"); } } - static class LongHandler extends JavaLangType { + static final class LongHandler extends JavaLangType { LongHandler() { super("Long"); } @@ -135,13 +120,13 @@ public String toMethod() { } } - static class PLongHandler extends Primitive { + static final class PLongHandler extends Primitive { PLongHandler() { super("Long"); } } - static class FloatHandler extends JavaLangType { + static final class FloatHandler extends JavaLangType { FloatHandler() { super("Float"); } @@ -157,13 +142,13 @@ public String toMethod() { } } - static class PFloatHandler extends Primitive { + static final class PFloatHandler extends Primitive { PFloatHandler() { super("Float"); } } - static class DoubleHandler extends JavaLangType { + static final class DoubleHandler extends JavaLangType { DoubleHandler() { super("Double"); } @@ -179,13 +164,13 @@ public String toMethod() { } } - static class PDoubleHandler extends Primitive { + static final class PDoubleHandler extends Primitive { PDoubleHandler() { super("Double"); } } - static class BooleanHandler extends JavaLangType { + static final class BooleanHandler extends JavaLangType { BooleanHandler() { super("Boolean"); } @@ -201,7 +186,7 @@ public String toMethod() { } } - static class BoolHandler extends Primitive { + static final class BoolHandler extends Primitive { BoolHandler() { super("asBool(", "boolean"); } @@ -231,7 +216,7 @@ public List importTypes() { } } - abstract static class Primitive implements TypeHandler { + static abstract class Primitive implements TypeHandler { private final String type; @@ -273,55 +258,55 @@ public List importTypes() { } } - static class UuidHandler extends ObjectHandler { + static final class UuidHandler extends ObjectHandler { UuidHandler() { super("java.util.UUID", "UUID"); } } - static class BigDecimalHandler extends ObjectHandler { + static final class BigDecimalHandler extends ObjectHandler { BigDecimalHandler() { super("java.math.BigDecimal", "BigDecimal"); } } - static class BigIntegerHandler extends ObjectHandler { + static final class BigIntegerHandler extends ObjectHandler { BigIntegerHandler() { super("java.math.BigInteger", "BigInteger"); } } - static class LocalDateHandler extends ObjectHandler { + static final class LocalDateHandler extends ObjectHandler { LocalDateHandler() { super("java.time.LocalDate", "LocalDate"); } } - static class InstantHandler extends ObjectHandler { + static final class InstantHandler extends ObjectHandler { InstantHandler() { super("java.time.Instant", "Instant"); } } - static class OffsetDateTimeHandler extends ObjectHandler { + static final class OffsetDateTimeHandler extends ObjectHandler { OffsetDateTimeHandler() { super("java.time.OffsetDateTime", "OffsetDateTime"); } } - static class LocalTimeHandler extends ObjectHandler { + static final class LocalTimeHandler extends ObjectHandler { LocalTimeHandler() { super("java.time.LocalTime", "LocalTime"); } } - static class LocalDateTimeHandler extends ObjectHandler { + static final class LocalDateTimeHandler extends ObjectHandler { LocalDateTimeHandler() { super("java.time.LocalDateTime", "LocalDateTime"); } } - static class EnumHandler extends ObjectHandler { + static final class EnumHandler extends ObjectHandler { private final UType type; EnumHandler(UType type) { @@ -340,25 +325,31 @@ public String asMethod() { } } - static class CollectionHandler implements TypeHandler { + static final class CollectionHandler implements TypeHandler { private final List importTypes; private final String shortName; - private String toMethod; + private final String toMethod; - CollectionHandler(TypeHandler handler, boolean set, boolean isEnum) { + private static CollectionHandler of(UType type, boolean isEnum, TypeHandler sourceHandler) { + final var handler = isEnum ? enumParamHandler(type.paramRaw()) : sourceHandler; + final var isSet = type.mainType().startsWith("java.util.Set"); + return new CollectionHandler(handler, isSet, isEnum); + } + + private CollectionHandler(TypeHandler handler, boolean set, boolean isEnum) { this.importTypes = new ArrayList<>(handler.importTypes()); this.importTypes.add("io.avaje.http.api.PathTypeConversion"); this.shortName = handler.shortName(); - this.toMethod = - (set ? "set" : "list") - + "(" - + (isEnum - ? "qp -> " + handler.toMethod() + " qp)" - : "PathTypeConversion::as" + shortName) - + ", "; + String _toMethod = + (set ? "set" : "list") + + "(" + + (isEnum + ? "qp -> " + handler.toMethod() + " qp)" + : "PathTypeConversion::as" + shortName) + + ", "; - this.toMethod = toMethod.replace("PathTypeConversion::asString", "Object::toString"); + this.toMethod = _toMethod.replace("PathTypeConversion::asString", "Object::toString"); } @Override @@ -387,13 +378,18 @@ public String toMethod() { } } - static class OptionalHandler implements TypeHandler { + static final class OptionalHandler implements TypeHandler { private final List importTypes; private final String shortName; private final String toMethod; - OptionalHandler(TypeHandler handler, boolean isEnum) { + private static OptionalHandler of(UType type, boolean isEnum, TypeHandler sourceHandler) { + final var handler = isEnum ? enumParamHandler(type.paramRaw()) : sourceHandler; + return new OptionalHandler(handler, isEnum); + } + + private OptionalHandler(TypeHandler handler, boolean isEnum) { this.importTypes = new ArrayList<>(handler.importTypes()); this.importTypes.add("io.avaje.http.api.PathTypeConversion"); this.shortName = handler.shortName(); @@ -437,7 +433,7 @@ public String toMethod() { } } - abstract static class ObjectHandler implements TypeHandler { + static abstract class ObjectHandler implements TypeHandler { private final String importType; private final String shortName; diff --git a/http-generator-core/src/test/java/io/avaje/http/generator/core/TypeMapTest.java b/http-generator-core/src/test/java/io/avaje/http/generator/core/TypeMapTest.java index b91cad8e3..c5dfdc7bf 100644 --- a/http-generator-core/src/test/java/io/avaje/http/generator/core/TypeMapTest.java +++ b/http-generator-core/src/test/java/io/avaje/http/generator/core/TypeMapTest.java @@ -72,22 +72,73 @@ void get_BigInt() { @Test void get_OptionalInteger() { - TypeHandler handler = TypeMap.get("java.lang.Integer"); - TypeMap.OptionalHandler optionalHandler = new TypeMap.OptionalHandler(handler, false); + UType uType = UType.parse("java.util.Optional"); + TypeHandler optionalHandler = TypeMap.optionalHandler(uType, false); + assertThat(optionalHandler).isNotNull(); assertThat(optionalHandler.toMethod()).isEqualTo("optional(PathTypeConversion::asInteger, "); } @Test void get_OptionalString() { - TypeHandler handler = TypeMap.get("java.lang.String"); - TypeMap.OptionalHandler optionalHandler = new TypeMap.OptionalHandler(handler, false); + UType uType = UType.parse("java.util.Optional"); + TypeHandler optionalHandler = TypeMap.optionalHandler(uType, false); + assertThat(optionalHandler).isNotNull(); assertThat(optionalHandler.toMethod()).isEqualTo("optional("); } @Test void get_OptionalEnum() { - TypeHandler handler = TypeMap.enumParamHandler(UType.parse("org.my.MyEnum")); - TypeMap.OptionalHandler optionalHandler = new TypeMap.OptionalHandler(handler, true); + UType uType = UType.parse("java.util.Optional"); + TypeHandler optionalHandler = TypeMap.optionalHandler(uType, true); + assertThat(optionalHandler).isNotNull(); assertThat(optionalHandler.toMethod()).isEqualTo("optional(qp -> (MyEnum) toEnum(MyEnum.class, qp), "); } + + @Test + void get_ListInteger() { + UType uType = UType.parse("java.util.List"); + TypeHandler handler = TypeMap.collectionHandler(uType, false); + assertThat(handler).isNotNull(); + assertThat(handler.toMethod()).isEqualTo("list(PathTypeConversion::asInteger, "); + } + + @Test + void get_SetInteger() { + UType uType = UType.parse("java.util.Set"); + TypeHandler handler = TypeMap.collectionHandler(uType, false); + assertThat(handler).isNotNull(); + assertThat(handler.toMethod()).isEqualTo("set(PathTypeConversion::asInteger, "); + } + + @Test + void get_ListString() { + UType uType = UType.parse("java.util.List"); + TypeHandler handler = TypeMap.collectionHandler(uType, false); + assertThat(handler).isNotNull(); + assertThat(handler.toMethod()).isEqualTo("list(Object::toString, "); + } + + @Test + void get_SetString() { + UType uType = UType.parse("java.util.Set"); + TypeHandler handler = TypeMap.collectionHandler(uType, false); + assertThat(handler).isNotNull(); + assertThat(handler.toMethod()).isEqualTo("set(Object::toString, "); + } + + @Test + void get_ListEnum() { + UType uType = UType.parse("java.util.List"); + TypeHandler handler = TypeMap.collectionHandler(uType, true); + assertThat(handler).isNotNull(); + assertThat(handler.toMethod()).isEqualTo("list(qp -> (MyEnum) toEnum(MyEnum.class, qp), "); + } + + @Test + void get_SetEnum() { + UType uType = UType.parse("java.util.Set"); + TypeHandler handler = TypeMap.collectionHandler(uType, true); + assertThat(handler).isNotNull(); + assertThat(handler.toMethod()).isEqualTo("set(qp -> (MyEnum) toEnum(MyEnum.class, qp), "); + } } From 3025c935f56d3835faf79bd7cb0ea8a49519d931 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sun, 26 Jan 2025 00:39:46 -0500 Subject: [PATCH 1232/1323] [client] support generics with jackson (#553) --- .../avaje/http/client/JacksonBodyAdapter.java | 64 ++++++++-- .../generator/client/ClientMethodWriter.java | 31 +++-- .../generator/client/ClientProcessor.java | 5 +- .../http/generator/client/ClientWriter.java | 7 +- tests/pom.xml | 2 +- tests/test-client/pom.xml | 14 +++ .../src/main/java/example/github/Generic.java | 15 +++ .../main/java/example/github/GenericData.java | 13 ++ .../src/main/java/example/github/Repo.java | 22 +++- .../src/main/java/example/github/Simple.java | 13 +- .../httpclient/GeneratedHttpComponent.java | 15 --- .../github/httpclient/Simple$HttpClient.java | 31 ----- .../src/main/java/module-info.java | 1 + .../io.avaje.http.client.HttpApiProvider | 1 - ....http.client.HttpClient$GeneratedComponent | 1 + .../test/java/example/github/GithubTest.java | 86 +++++++++++-- .../src/main/resources/public/openapi.json | 117 ++++++++++++++++++ 17 files changed, 340 insertions(+), 98 deletions(-) create mode 100644 tests/test-client/src/main/java/example/github/Generic.java create mode 100644 tests/test-client/src/main/java/example/github/GenericData.java delete mode 100644 tests/test-client/src/main/java/example/github/httpclient/GeneratedHttpComponent.java delete mode 100644 tests/test-client/src/main/java/example/github/httpclient/Simple$HttpClient.java delete mode 100644 tests/test-client/src/main/resources/META-INF/services/io.avaje.http.client.HttpApiProvider create mode 100644 tests/test-client/src/main/resources/META-INF/services/io.avaje.http.client.HttpClient$GeneratedComponent diff --git a/http-client/src/main/java/io/avaje/http/client/JacksonBodyAdapter.java b/http-client/src/main/java/io/avaje/http/client/JacksonBodyAdapter.java index 269eec9e5..a28c97a3c 100644 --- a/http-client/src/main/java/io/avaje/http/client/JacksonBodyAdapter.java +++ b/http-client/src/main/java/io/avaje/http/client/JacksonBodyAdapter.java @@ -1,15 +1,20 @@ package io.avaje.http.client; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.*; -import com.fasterxml.jackson.databind.type.CollectionType; - import java.io.IOException; import java.io.UncheckedIOException; +import java.lang.reflect.Type; import java.util.List; import java.util.concurrent.ConcurrentHashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.ObjectReader; +import com.fasterxml.jackson.databind.ObjectWriter; +import com.fasterxml.jackson.databind.SerializationFeature; +import com.fasterxml.jackson.databind.type.CollectionType; + /** * Jackson BodyAdapter to read and write beans as JSON. * @@ -26,9 +31,9 @@ public final class JacksonBodyAdapter implements BodyAdapter { private final ObjectMapper mapper; - private final ConcurrentHashMap, BodyWriter> beanWriterCache = new ConcurrentHashMap<>(); - private final ConcurrentHashMap, BodyReader> beanReaderCache = new ConcurrentHashMap<>(); - private final ConcurrentHashMap, BodyReader> listReaderCache = new ConcurrentHashMap<>(); + private final ConcurrentHashMap> beanWriterCache = new ConcurrentHashMap<>(); + private final ConcurrentHashMap> beanReaderCache = new ConcurrentHashMap<>(); + private final ConcurrentHashMap> listReaderCache = new ConcurrentHashMap<>(); /** * Create passing the ObjectMapper to use. @@ -72,6 +77,30 @@ public BodyReader beanReader(Class cls) { }); } + @SuppressWarnings("unchecked") + @Override + public BodyWriter beanWriter(Type cls) { + return (BodyWriter) beanWriterCache.computeIfAbsent(cls, aClass -> { + try { + return new JWriter<>(mapper.writerFor(mapper.getTypeFactory().constructType(cls))); + } catch (Exception e) { + throw new RuntimeException(e); + } + }); + } + + @SuppressWarnings("unchecked") + @Override + public BodyReader beanReader(Type cls) { + return (BodyReader) beanReaderCache.computeIfAbsent(cls, aClass -> { + try { + return new JReader<>(mapper.readerFor(mapper.getTypeFactory().constructType(cls))); + } catch (Exception e) { + throw new RuntimeException(e); + } + }); + } + @SuppressWarnings("unchecked") @Override public BodyReader> listReader(Class cls) { @@ -86,7 +115,22 @@ public BodyReader> listReader(Class cls) { }); } - private static class JReader implements BodyReader { + @SuppressWarnings("unchecked") + @Override + public BodyReader> listReader(Type type) { + return (BodyReader>) listReaderCache.computeIfAbsent(type, aType -> { + try { + var javaType = mapper.getTypeFactory().constructType(aType); + final CollectionType collectionType = mapper.getTypeFactory().constructCollectionType(List.class, javaType); + final ObjectReader reader = mapper.readerFor(collectionType); + return new JReader<>(reader); + } catch (Exception e) { + throw new RuntimeException(e); + } + }); + } + + private static final class JReader implements BodyReader { private final ObjectReader reader; @@ -113,7 +157,7 @@ public T read(BodyContent bodyContent) { } } - private static class JWriter implements BodyWriter { + private static final class JWriter implements BodyWriter { private final ObjectWriter writer; diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java index fd07d316d..6d193dedc 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java @@ -21,7 +21,6 @@ * Write code to register Web route for a given controller method. */ final class ClientMethodWriter { - private static final KnownResponse KNOWN_RESPONSE = new KnownResponse(); private static final String BODY_HANDLER = "java.net.http.HttpResponse.BodyHandler"; private static final String COMPLETABLE_FUTURE = "java.util.concurrent.CompletableFuture"; @@ -33,19 +32,21 @@ final class ClientMethodWriter { private final UType returnType; private MethodParam bodyHandlerParam; private String methodGenericParams = ""; - private final boolean useJsonb; + private static final boolean useJsonb = APContext.typeElement("io.avaje.jsonb.Types") != null; + private static final boolean useJackson = APContext.typeElement("com.fasterxml.jackson.core.type.TypeReference") != null; + private static final boolean useInject = APContext.typeElement("io.avaje.inject.spi.GenericType") != null; + private final Optional timeout; private final boolean useConfig; private final Map segmentPropertyMap; private final Set propertyConstants; private final List> presetHeaders; - ClientMethodWriter(MethodReader method, Append writer, boolean useJsonb, Set propertyConstants) { + ClientMethodWriter(MethodReader method, Append writer, Set propertyConstants) { this.method = method; this.writer = writer; this.webMethod = method.webMethod(); this.returnType = Util.parseType(method.returnType()); - this.useJsonb = useJsonb; this.timeout = method.timeout(); this.useConfig = ProcessingContext.typeElement("io.avaje.config.Config") != null; @@ -73,6 +74,13 @@ final class ClientMethodWriter { } void addImportTypes(ControllerReader reader) { + if (useJsonb) { + reader.addImportType("io.avaje.jsonb.Types"); + } else if (useJackson) { + reader.addImportType("com.fasterxml.jackson.core.type.TypeReference"); + } else if (useInject) { + reader.addImportType("io.avaje.inject.spi.GenericType"); + } reader.addImportTypes(returnType.importTypes()); method.throwsList().stream() .map(UType::parse) @@ -240,13 +248,18 @@ private void writeResponse(UType type) { } void writeGeneric(UType type) { - if (useJsonb && type.isGeneric()) { - final var params = type.importTypes().stream() - .skip(1) - .map(Util::shortName) - .collect(Collectors.joining(".class, ")); + if (type.isGeneric() && useJsonb) { + final var params = + type.importTypes().stream() + .skip(1) + .map(Util::shortName) + .collect(Collectors.joining(".class, ")); writer.append("Types.newParameterizedType(%s.class, %s.class)", Util.shortName(type.mainType()), params); + } else if (type.isGeneric() && useJackson) { + writer.append("new TypeReference<%s>() {}.getType()", type.shortType()); + } else if (type.isGeneric() && useInject) { + writer.append("new GenericType<%s>() {}.getType()", type.shortType()); } else { writer.append("%s.class", Util.shortName(type.mainType())); } diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java index 2ba487244..cc7cd5f44 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java @@ -30,8 +30,6 @@ public class ClientProcessor extends AbstractProcessor { private final ComponentMetaData metaData = new ComponentMetaData(); - private boolean useJsonB; - private SimpleComponentWriter componentWriter; private boolean readModuleInfo; @@ -48,7 +46,6 @@ public synchronized void init(ProcessingEnvironment processingEnv) { APContext.init(processingEnv); ProcessingContext.init(processingEnv, new ClientPlatformAdapter(), false); this.componentWriter = new SimpleComponentWriter(metaData); - useJsonB = ProcessingContext.useJsonb(); } @Override @@ -103,7 +100,7 @@ private void writeClient(Element controller) { protected String writeClientAdapter(ControllerReader reader) throws IOException { var suffix = ClientSuffix.fromInterface(reader.beanType().getQualifiedName().toString()); - return new ClientWriter(reader, suffix, useJsonB).write(); + return new ClientWriter(reader, suffix).write(); } private void initialiseComponent() { diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientWriter.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientWriter.java index 643525135..115b69395 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientWriter.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientWriter.java @@ -24,17 +24,14 @@ final class ClientWriter extends BaseControllerWriter { private static final String AT_GENERATED = "@Generated(\"avaje-http-client-generator\")"; private final List methodList = new ArrayList<>(); - private final boolean useJsonb; private final Set propertyConstants = new HashSet<>(); private final String suffix; - ClientWriter(ControllerReader reader, String suffix, boolean useJsonB) throws IOException { + ClientWriter(ControllerReader reader, String suffix) throws IOException { super(reader, suffix); this.suffix = suffix; reader.addImportType(HTTP_CLIENT); - this.useJsonb = useJsonB; readMethods(); - if (useJsonB) reader.addImportType("io.avaje.jsonb.Types"); } @Override @@ -50,7 +47,7 @@ protected String initPackageName(String originName) { private void readMethods() { for (final MethodReader method : reader.methods()) { if (method.isWebMethod()) { - final var methodWriter = new ClientMethodWriter(method, writer, useJsonb, propertyConstants); + final var methodWriter = new ClientMethodWriter(method, writer, propertyConstants); methodWriter.addImportTypes(reader); methodList.add(methodWriter); } diff --git a/tests/pom.xml b/tests/pom.xml index 9dc38791c..16ab60bab 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -24,7 +24,6 @@ test-javalin test-javalin-jsonb - test-client test-sigma @@ -35,6 +34,7 @@ [21,) + test-client test-nima test-jex test-nima-jsonb diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index 0c40e2560..46855762f 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -12,6 +12,7 @@ test-client + 21 UTF-8 @@ -54,6 +55,19 @@ 1.0 + + io.avaje + avaje-jex + 3.0-RC14 + test + + + + io.avaje + avaje-http-client-generator + ${project.version} + + diff --git a/tests/test-client/src/main/java/example/github/Generic.java b/tests/test-client/src/main/java/example/github/Generic.java new file mode 100644 index 000000000..c3478759c --- /dev/null +++ b/tests/test-client/src/main/java/example/github/Generic.java @@ -0,0 +1,15 @@ +package example.github; + +import java.util.List; + +import io.avaje.http.api.Client; +import io.avaje.http.api.Post; +import io.avaje.http.client.HttpException; + +@Client +public interface Generic { + + @Post("/generic") + List> post(GenericData repo) throws HttpException; + +} diff --git a/tests/test-client/src/main/java/example/github/GenericData.java b/tests/test-client/src/main/java/example/github/GenericData.java new file mode 100644 index 000000000..065018a3f --- /dev/null +++ b/tests/test-client/src/main/java/example/github/GenericData.java @@ -0,0 +1,13 @@ +package example.github; + +public class GenericData { + private T data; + + public T getData() { + return data; + } + + public void setData(T data) { + this.data = data; + } +} diff --git a/tests/test-client/src/main/java/example/github/Repo.java b/tests/test-client/src/main/java/example/github/Repo.java index 73564f763..1ee812999 100644 --- a/tests/test-client/src/main/java/example/github/Repo.java +++ b/tests/test-client/src/main/java/example/github/Repo.java @@ -1,6 +1,24 @@ package example.github; +import com.fasterxml.jackson.annotation.JsonCreator; + public class Repo { - public long id; - public String name; + private long id; + private String name; + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } } diff --git a/tests/test-client/src/main/java/example/github/Simple.java b/tests/test-client/src/main/java/example/github/Simple.java index f39f9638c..ad1a1667a 100644 --- a/tests/test-client/src/main/java/example/github/Simple.java +++ b/tests/test-client/src/main/java/example/github/Simple.java @@ -1,15 +1,14 @@ package example.github; -//import io.avaje.http.api.Get; -//import io.avaje.http.api.Path; -import io.avaje.http.client.HttpException; - import java.util.List; -//@Path("/") +import io.avaje.http.api.Client; +import io.avaje.http.api.Get; +import io.avaje.http.client.HttpException; + +@Client public interface Simple { - //@Get("users/{user}/repos") + @Get("users/{user}/repos") List listRepos(String user, String other) throws HttpException; - } diff --git a/tests/test-client/src/main/java/example/github/httpclient/GeneratedHttpComponent.java b/tests/test-client/src/main/java/example/github/httpclient/GeneratedHttpComponent.java deleted file mode 100644 index b7517518e..000000000 --- a/tests/test-client/src/main/java/example/github/httpclient/GeneratedHttpComponent.java +++ /dev/null @@ -1,15 +0,0 @@ -package example.github.httpclient; - -import java.util.Map; - -import example.github.Simple; -import io.avaje.http.client.HttpApiProvider; -import io.avaje.http.client.HttpClient; - -public class GeneratedHttpComponent implements HttpClient.GeneratedComponent { - - @Override - public void register(Map, HttpApiProvider> providerMap) { - providerMap.put(Simple.class, Simple$HttpClient::new); - } -} diff --git a/tests/test-client/src/main/java/example/github/httpclient/Simple$HttpClient.java b/tests/test-client/src/main/java/example/github/httpclient/Simple$HttpClient.java deleted file mode 100644 index 1a8a351a0..000000000 --- a/tests/test-client/src/main/java/example/github/httpclient/Simple$HttpClient.java +++ /dev/null @@ -1,31 +0,0 @@ -package example.github.httpclient; - -import java.util.List; - -import example.github.Repo; -import example.github.Simple; -import io.avaje.http.client.HttpClient; -import io.avaje.http.client.HttpException; - -/** This code could be generated from the interface definition. */ -public class Simple$HttpClient implements Simple { - - private final HttpClient context; - - public Simple$HttpClient(HttpClient context) { - this.context = context; - } - - // @Get("users/{user}/repos") - @Override - public List listRepos(String user, String other) throws HttpException { - return context - .request() - .path("users") - .path(user) - .path("repos") - .queryParam("other", other) - .GET() - .list(Repo.class); - } -} diff --git a/tests/test-client/src/main/java/module-info.java b/tests/test-client/src/main/java/module-info.java index f8165faa3..a925d770c 100644 --- a/tests/test-client/src/main/java/module-info.java +++ b/tests/test-client/src/main/java/module-info.java @@ -1,6 +1,7 @@ open module test { requires io.avaje.http.client; + requires io.avaje.http.api; requires com.fasterxml.jackson.databind; requires com.google.gson; diff --git a/tests/test-client/src/main/resources/META-INF/services/io.avaje.http.client.HttpApiProvider b/tests/test-client/src/main/resources/META-INF/services/io.avaje.http.client.HttpApiProvider deleted file mode 100644 index e15a847cf..000000000 --- a/tests/test-client/src/main/resources/META-INF/services/io.avaje.http.client.HttpApiProvider +++ /dev/null @@ -1 +0,0 @@ -example.github.SimpleHttpClient diff --git a/tests/test-client/src/main/resources/META-INF/services/io.avaje.http.client.HttpClient$GeneratedComponent b/tests/test-client/src/main/resources/META-INF/services/io.avaje.http.client.HttpClient$GeneratedComponent new file mode 100644 index 000000000..d419efe24 --- /dev/null +++ b/tests/test-client/src/main/resources/META-INF/services/io.avaje.http.client.HttpClient$GeneratedComponent @@ -0,0 +1 @@ +example.github.httpclient.GeneratedHttpComponent \ No newline at end of file diff --git a/tests/test-client/src/test/java/example/github/GithubTest.java b/tests/test-client/src/test/java/example/github/GithubTest.java index 36e501f15..2099c8497 100644 --- a/tests/test-client/src/test/java/example/github/GithubTest.java +++ b/tests/test-client/src/test/java/example/github/GithubTest.java @@ -1,18 +1,57 @@ package example.github; +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.List; + +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + import com.google.gson.Gson; + import io.avaje.http.client.BodyAdapter; import io.avaje.http.client.HttpClient; import io.avaje.http.client.JacksonBodyAdapter; import io.avaje.http.client.gson.GsonBodyAdapter; -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.Test; +import io.avaje.jex.Jex; -import java.util.List; +class GithubTest { -import static org.assertj.core.api.Assertions.assertThat; + static Jex.Server server = null; + String url = "http://localhost:" + server.port(); -class GithubTest { + @BeforeAll + static void startServer() { + server = + Jex.create() + .get( + "/users/{user}/repos", + ctx -> { + var repo = new Repo(); + repo.setId(1); + repo.setName("something"); + ctx.json(List.of(new Repo())); + }) + .post( + "/generic", + ctx -> { + var repo = new Repo(); + repo.setId(1); + repo.setName("something"); + var data = new GenericData(); + data.setData(repo); + + ctx.json(List.>of(data)); + }) + .port(0) + .start(); + } + + @AfterAll + static void stop() { + server.shutdown(); + } @Test void test_create() { @@ -22,25 +61,27 @@ void test_create() { assertThat(simple).isNotNull(); } - @Disabled @Test void test_with_jackson() { assertListRepos(jacksonBodyAdapter()); } - @Disabled + @Test + void testGeneric_with_jackson() { + assertGeneric(jacksonBodyAdapter()); + } + @Test void test_with_gson() { assertListRepos(gsonBodyAdapter()); } private void assertListRepos(BodyAdapter bodyAdapter) { - final HttpClient client = HttpClient.builder() - .baseUrl("https://api.github.com") - .bodyAdapter(bodyAdapter) -// .requestLogging(false) -// .requestListener(new RequestLogger()) - .build(); + final HttpClient client = + HttpClient.builder() + .baseUrl(url) + .bodyAdapter(bodyAdapter) + .build(); final Simple simple = client.create(Simple.class); @@ -48,6 +89,25 @@ private void assertListRepos(BodyAdapter bodyAdapter) { assertThat(repos).isNotEmpty(); } + private void assertGeneric(BodyAdapter bodyAdapter) { + final HttpClient client = + HttpClient.builder() + .baseUrl(url) + .bodyAdapter(bodyAdapter) + .build(); + + final var generic = client.create(Generic.class); + + var repo = new Repo(); + repo.setId(1); + repo.setName("something"); + var data = new GenericData(); + data.setData(repo); + + final var repos = generic.post(data); + assertThat(repos).isNotEmpty(); + } + private BodyAdapter jacksonBodyAdapter() { return new JacksonBodyAdapter(); } diff --git a/tests/test-jex/src/main/resources/public/openapi.json b/tests/test-jex/src/main/resources/public/openapi.json index b747803d2..e4b99b6d6 100644 --- a/tests/test-jex/src/main/resources/public/openapi.json +++ b/tests/test-jex/src/main/resources/public/openapi.json @@ -720,6 +720,96 @@ } } }, + "/hello/takesOptional" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "parameters" : [ + { + "name" : "myOptional", + "in" : "query", + "schema" : { + "$ref" : "#/components/schemas/Long>" + } + } + ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/hello/takesOptionalEnum" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "parameters" : [ + { + "name" : "myOptional", + "in" : "query", + "schema" : { + "$ref" : "#/components/schemas/NestedEnum>" + } + } + ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/hello/takesOptionalString" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "parameters" : [ + { + "name" : "myOptional", + "in" : "query", + "schema" : { + "$ref" : "#/components/schemas/String>" + } + } + ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, "/hello/withMatrix/{year_segment}/{other}" : { "get" : { "tags" : [ @@ -1426,6 +1516,33 @@ } } }, + "Long>" : { + "type" : "object", + "properties" : { + "value" : { + "$ref" : "#/components/schemas/T" + } + } + }, + "NestedEnum>" : { + "type" : "object", + "properties" : { + "value" : { + "$ref" : "#/components/schemas/T" + } + } + }, + "String>" : { + "type" : "object", + "properties" : { + "value" : { + "$ref" : "#/components/schemas/T" + } + } + }, + "T" : { + "type" : "object" + }, "ViewHome" : { "type" : "object", "properties" : { From 19acb3cf755950ae39eb2a60163da5a7be682c10 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sun, 26 Jan 2025 04:42:09 -0500 Subject: [PATCH 1233/1323] [client] Fully support package private (#551) * fully support package private will now generate separate HttpComponents for package-private client interfaces * Create PrivateClient.java --- .../generator/client/ClientProcessor.java | 72 +++++++++++++------ .../http/generator/client/ClientWriter.java | 12 ++-- .../generator/client/ComponentMetaData.java | 44 +++++++++--- .../generator/client/ComponentReader.java | 57 ++++++++------- .../client/SimpleComponentWriter.java | 10 --- .../client/ComponentMetaDataTest.java | 18 +++++ .../client/clients/PrivateClient.java | 13 ++++ .../client/clients/PrivateClient2.java | 13 ++++ .../client/clients/other/PrivateClient2.java | 13 ++++ .../generator/core/ProcessingContext.java | 8 +-- .../org/example/pkgprivate/PrivateClient.java | 13 ++++ .../github/pkgprivate/SimplePkgPrivate.java | 12 ++++ .../src/main/java/module-info.java | 3 +- ....http.client.HttpClient$GeneratedComponent | 1 - .../github/pkgprivate/PkgPrivateTest.java | 43 +++++++++++ 15 files changed, 257 insertions(+), 75 deletions(-) create mode 100644 http-generator-client/src/test/java/io/avaje/http/generator/client/ComponentMetaDataTest.java create mode 100644 http-generator-client/src/test/java/io/avaje/http/generator/client/clients/PrivateClient.java create mode 100644 http-generator-client/src/test/java/io/avaje/http/generator/client/clients/PrivateClient2.java create mode 100644 http-generator-client/src/test/java/io/avaje/http/generator/client/clients/other/PrivateClient2.java create mode 100644 tests/test-client-generation/src/main/java/org/example/pkgprivate/PrivateClient.java create mode 100644 tests/test-client/src/main/java/example/github/pkgprivate/SimplePkgPrivate.java delete mode 100644 tests/test-client/src/main/resources/META-INF/services/io.avaje.http.client.HttpClient$GeneratedComponent create mode 100644 tests/test-client/src/test/java/example/github/pkgprivate/PkgPrivateTest.java diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java index cc7cd5f44..9b28b0954 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java @@ -1,11 +1,14 @@ package io.avaje.http.generator.client; +import static io.avaje.http.generator.core.ProcessingContext.createMetaInfWriter; import static io.avaje.http.generator.core.ProcessingContext.logError; import static io.avaje.http.generator.core.ProcessingContext.platform; import static io.avaje.http.generator.core.ProcessingContext.setPlatform; import static io.avaje.http.generator.core.ProcessingContext.typeElement; import java.io.IOException; +import java.util.HashMap; +import java.util.Map; import java.util.Objects; import java.util.Set; @@ -15,10 +18,13 @@ import javax.annotation.processing.SupportedAnnotationTypes; import javax.lang.model.SourceVersion; import javax.lang.model.element.Element; +import javax.lang.model.element.Modifier; import javax.lang.model.element.TypeElement; +import javax.tools.FileObject; import io.avaje.http.generator.core.APContext; import io.avaje.http.generator.core.ClientPrism; +import io.avaje.http.generator.core.Constants; import io.avaje.http.generator.core.ControllerReader; import io.avaje.http.generator.core.ImportPrism; import io.avaje.http.generator.core.ProcessingContext; @@ -29,9 +35,9 @@ public class ClientProcessor extends AbstractProcessor { private final ComponentMetaData metaData = new ComponentMetaData(); + private final Map privateMetaData = new HashMap<>(); private SimpleComponentWriter componentWriter; - private boolean readModuleInfo; @Override @@ -76,7 +82,7 @@ private void readModule() { return; } readModuleInfo = true; - new ComponentReader(metaData).read(); + new ComponentReader(metaData, privateMetaData).read(); } private void writeForImported(Element importedElement) { @@ -91,39 +97,65 @@ private void writeClient(Element controller) { final ControllerReader reader = new ControllerReader((TypeElement) controller); reader.read(false); try { - metaData.add(writeClientAdapter(reader)); + var packagePrivate = + !controller.getModifiers().contains(Modifier.PUBLIC) + && ClientPrism.isPresent(controller); + if (packagePrivate) { + var packageName = APContext.elements().getPackageOf(controller).getQualifiedName().toString(); + var meta = privateMetaData.computeIfAbsent(packageName, k -> new ComponentMetaData()); + meta.add(writeClientAdapter(reader, true)); + } else { + metaData.add(writeClientAdapter(reader, false)); + } + } catch (final Exception e) { logError(reader.beanType(), "Failed to write client class " + e); } } } - protected String writeClientAdapter(ControllerReader reader) throws IOException { + protected String writeClientAdapter(ControllerReader reader, boolean packagePrivate) throws IOException { var suffix = ClientSuffix.fromInterface(reader.beanType().getQualifiedName().toString()); - return new ClientWriter(reader, suffix).write(); - } - - private void initialiseComponent() { - metaData.initialiseFullName(); - if (!metaData.all().isEmpty()) { - ProcessingContext.addClientComponent(metaData.fullName()); - ProcessingContext.validateModule(); - } - try { - componentWriter.init(); - } catch (final IOException e) { - logError("Error creating writer for JsonbComponent", e); - } + return new ClientWriter(reader, suffix, packagePrivate).write(); } private void writeComponent(boolean processingOver) { - initialiseComponent(); if (processingOver) { try { - componentWriter.write(); + if (!metaData.all().isEmpty()) { + ProcessingContext.addClientComponent(metaData.fullName()); + componentWriter.init(); + componentWriter.write(); + } + + for (var meta : privateMetaData.values()) { + ProcessingContext.addClientComponent(meta.fullName()); + var writer = new SimpleComponentWriter(meta); + writer.init(); + writer.write(); + } + writeMetaInf(); + ProcessingContext.validateModule(); } catch (final IOException e) { logError("Error writing component", e); } } } + + void writeMetaInf() throws IOException { + final FileObject fileObject = createMetaInfWriter(Constants.META_INF_COMPONENT); + if (fileObject != null) { + try (var fileWriter = fileObject.openWriter()) { + if (!metaData.all().isEmpty()) { + fileWriter.write(metaData.fullName()); + fileWriter.write("\n"); + } + + for (var meta : privateMetaData.values()) { + fileWriter.write(meta.fullName()); + fileWriter.write("\n"); + } + } + } + } } diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientWriter.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientWriter.java index 115b69395..f49188b3f 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientWriter.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientWriter.java @@ -1,6 +1,5 @@ package io.avaje.http.generator.client; -import io.avaje.http.generator.core.APContext; import io.avaje.http.generator.core.BaseControllerWriter; import io.avaje.http.generator.core.ClientPrism; import io.avaje.http.generator.core.ControllerReader; @@ -27,9 +26,12 @@ final class ClientWriter extends BaseControllerWriter { private final Set propertyConstants = new HashSet<>(); private final String suffix; - ClientWriter(ControllerReader reader, String suffix) throws IOException { + private final boolean packagePrivate; + + ClientWriter(ControllerReader reader, String suffix, boolean packagePrivate) throws IOException { super(reader, suffix); this.suffix = suffix; + this.packagePrivate = packagePrivate; reader.addImportType(HTTP_CLIENT); readMethods(); } @@ -76,12 +78,12 @@ private void writeMethods() { private void writeClassStart() { writer.append(AT_GENERATED).eol(); AnnotationUtil.writeAnnotations(writer, reader.beanType()); - - writer.append("public final class %s%s implements %s, AutoCloseable {", shortName, suffix, shortName).eol().eol(); + var access = packagePrivate ? "" : "public "; + writer.append("%sfinal class %s%s implements %s, AutoCloseable {", access, shortName, suffix, shortName).eol().eol(); writer.append(" private final HttpClient client;").eol().eol(); - writer.append(" public %s%s(HttpClient client) {", shortName, suffix).eol(); + writer.append(" %s%s%s(HttpClient client) {", access, shortName, suffix).eol(); writer.append(" this.client = client;").eol(); writer.append(" }").eol().eol(); } diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ComponentMetaData.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ComponentMetaData.java index ac0866394..28b1ec99e 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ComponentMetaData.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ComponentMetaData.java @@ -4,7 +4,7 @@ final class ComponentMetaData { - private final List generatedClients = new ArrayList<>(); + private final Set generatedClients = new HashSet<>(); private String fullName; @Override @@ -12,11 +12,6 @@ public String toString() { return generatedClients.toString(); } - /** Ensure the component name has been initialised. */ - void initialiseFullName() { - fullName(); - } - void add(String type) { generatedClients.add(type); } @@ -28,13 +23,13 @@ void setFullName(String fullName) { String fullName() { if (fullName == null) { String topPackage = TopPackage.of(generatedClients); - fullName = topPackage + ".GeneratedHttpComponent"; + fullName = topPackage + "." + name(topPackage) + "HttpComponent"; } return fullName; } List all() { - return generatedClients; + return new ArrayList<>(generatedClients); } /** Return the package imports for the JsonAdapters and related types. */ @@ -46,4 +41,37 @@ Collection allImports() { return packageImports; } + + + static String name(String name) { + if (name == null) { + return null; + } + final int pos = name.lastIndexOf('.'); + if (pos > -1) { + name = name.substring(pos + 1); + } + return camelCase(name).replaceFirst("Httpclient", "Generated"); + } + + private static String camelCase(String name) { + StringBuilder sb = new StringBuilder(name.length()); + boolean upper = true; + for (char aChar : name.toCharArray()) { + if (Character.isLetterOrDigit(aChar)) { + if (upper) { + aChar = Character.toUpperCase(aChar); + upper = false; + } + sb.append(aChar); + } else if (toUpperOn(aChar)) { + upper = true; + } + } + return sb.toString(); + } + + private static boolean toUpperOn(char aChar) { + return aChar == ' ' || aChar == '-' || aChar == '_'; + } } diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ComponentReader.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ComponentReader.java index b6d335af1..086103fff 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ComponentReader.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ComponentReader.java @@ -1,8 +1,10 @@ package io.avaje.http.generator.client; + import static io.avaje.http.generator.core.ProcessingContext.filer; import static io.avaje.http.generator.core.ProcessingContext.logDebug; import static io.avaje.http.generator.core.ProcessingContext.logWarn; import static io.avaje.http.generator.core.ProcessingContext.typeElement; +import static java.util.stream.Collectors.toList; import java.io.FileNotFoundException; import java.io.LineNumberReader; @@ -11,14 +13,15 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Map; import javax.annotation.processing.FilerException; -import javax.lang.model.element.AnnotationMirror; +import javax.lang.model.element.Modifier; import javax.lang.model.element.TypeElement; -import javax.lang.model.type.TypeMirror; import javax.tools.FileObject; import javax.tools.StandardLocation; +import io.avaje.http.generator.core.APContext; import io.avaje.http.generator.core.Constants; import io.avaje.prism.GeneratePrism; @@ -26,42 +29,44 @@ final class ComponentReader { private final ComponentMetaData componentMetaData; + private final Map privateMetaData; - ComponentReader(ComponentMetaData metaData) { + ComponentReader(ComponentMetaData metaData, Map privateMetaData) { this.componentMetaData = metaData; + this.privateMetaData = privateMetaData; } void read() { - final String componentFullName = loadMetaInfServices(); - if (componentFullName != null) { - final TypeElement moduleType = typeElement(componentFullName); + for (String fqn : loadMetaInf()) { + final TypeElement moduleType = typeElement(fqn); if (moduleType != null) { - componentMetaData.setFullName(componentFullName); - readMetaData(moduleType); - } - } - } + var adapters = + MetaDataPrism.getInstanceOn(moduleType).value().stream() + .map(APContext::asTypeElement) + .collect(toList()); - /** Read the existing JsonAdapters from the MetaData annotation of the generated component. */ - private void readMetaData(TypeElement moduleType) { - for (final AnnotationMirror annotationMirror : moduleType.getAnnotationMirrors()) { - MetaDataPrism.getOptional(annotationMirror).map(MetaDataPrism::value).stream() - .flatMap(List::stream) - .map(TypeMirror::toString) - .forEach(componentMetaData::add); - } - } + if (adapters.get(0).getModifiers().contains(Modifier.PUBLIC)) { + componentMetaData.setFullName(fqn); + adapters.stream() + .map(TypeElement::getQualifiedName) + .map(Object::toString) + .forEach(componentMetaData::add); - private String loadMetaInfServices() { - final List lines = loadMetaInf(); - return lines.isEmpty() ? null : lines.get(0); + } else { + var packageName = APContext.elements().getPackageOf(moduleType).getQualifiedName().toString(); + var meta = privateMetaData.computeIfAbsent(packageName, k -> new ComponentMetaData()); + adapters.stream() + .map(TypeElement::getQualifiedName) + .map(Object::toString) + .forEach(meta::add); + } + } + } } private List loadMetaInf() { try { - final FileObject fileObject = filer() - .getResource(StandardLocation.CLASS_OUTPUT, "", Constants.META_INF_COMPONENT); - + final FileObject fileObject = filer().getResource(StandardLocation.CLASS_OUTPUT, "", Constants.META_INF_COMPONENT); if (fileObject != null) { final List lines = new ArrayList<>(); final Reader reader = fileObject.openReader(true); diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/SimpleComponentWriter.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/SimpleComponentWriter.java index 9a5f05809..8ffd70de3 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/SimpleComponentWriter.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/SimpleComponentWriter.java @@ -46,16 +46,6 @@ void write() throws IOException { writeRegister(); writeClassEnd(); writer.close(); - writeMetaInf(); - } - - void writeMetaInf() throws IOException { - final FileObject fileObject = createMetaInfWriter(Constants.META_INF_COMPONENT); - if (fileObject != null) { - try (var fileWriter = fileObject.openWriter()) { - fileWriter.write(fullName); - } - } } private void writeRegister() { diff --git a/http-generator-client/src/test/java/io/avaje/http/generator/client/ComponentMetaDataTest.java b/http-generator-client/src/test/java/io/avaje/http/generator/client/ComponentMetaDataTest.java new file mode 100644 index 000000000..116cbdf60 --- /dev/null +++ b/http-generator-client/src/test/java/io/avaje/http/generator/client/ComponentMetaDataTest.java @@ -0,0 +1,18 @@ +package io.avaje.http.generator.client; + +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +class ComponentMetaDataTest { + + @Test + void name() { + assertThat(ComponentMetaData.name(null)).isNull(); + assertThat(ComponentMetaData.name("org.foo")).isEqualTo("Foo"); + assertThat(ComponentMetaData.name("org.fooBar")).isEqualTo("FooBar"); + assertThat(ComponentMetaData.name("org.FooBar")).isEqualTo("FooBar"); + assertThat(ComponentMetaData.name("org.FooBarHttpclient")).isEqualTo("FooBarGenerated"); + assertThat(ComponentMetaData.name("org.FooBarHttpclientAgainHttpclient")).isEqualTo("FooBarGeneratedAgainHttpclient"); + } +} diff --git a/http-generator-client/src/test/java/io/avaje/http/generator/client/clients/PrivateClient.java b/http-generator-client/src/test/java/io/avaje/http/generator/client/clients/PrivateClient.java new file mode 100644 index 000000000..06fc0b735 --- /dev/null +++ b/http-generator-client/src/test/java/io/avaje/http/generator/client/clients/PrivateClient.java @@ -0,0 +1,13 @@ +package io.avaje.http.generator.client.clients; + +import io.avaje.http.api.Client; +import io.avaje.http.api.Get; +import io.avaje.http.api.Header; + +@Client +interface PrivateClient { + + @Get("/private") + String apiCall(@Header("Accept") String accept); + +} diff --git a/http-generator-client/src/test/java/io/avaje/http/generator/client/clients/PrivateClient2.java b/http-generator-client/src/test/java/io/avaje/http/generator/client/clients/PrivateClient2.java new file mode 100644 index 000000000..407fa636e --- /dev/null +++ b/http-generator-client/src/test/java/io/avaje/http/generator/client/clients/PrivateClient2.java @@ -0,0 +1,13 @@ +package io.avaje.http.generator.client.clients; + +import io.avaje.http.api.Client; +import io.avaje.http.api.Get; +import io.avaje.http.api.Header; + +@Client +public interface PrivateClient2 { + + @Get("/private") + String apiCall(@Header("Accept") String accept); + +} diff --git a/http-generator-client/src/test/java/io/avaje/http/generator/client/clients/other/PrivateClient2.java b/http-generator-client/src/test/java/io/avaje/http/generator/client/clients/other/PrivateClient2.java new file mode 100644 index 000000000..f3bfe589d --- /dev/null +++ b/http-generator-client/src/test/java/io/avaje/http/generator/client/clients/other/PrivateClient2.java @@ -0,0 +1,13 @@ +package io.avaje.http.generator.client.clients.other; + +import io.avaje.http.api.Client; +import io.avaje.http.api.Get; +import io.avaje.http.api.Header; + +@Client +interface PrivateClient2 { + + @Get("/private") + String apiCall(@Header("Accept") String accept); + +} diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java index f15a9ebc0..c865caa14 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java @@ -3,6 +3,7 @@ import java.io.IOException; import java.net.URI; import java.nio.file.Paths; +import java.util.HashSet; import java.util.List; import java.util.Objects; import java.util.Optional; @@ -49,7 +50,7 @@ private static final class Ctx { private final boolean instrumentAllMethods; private final boolean disableDirectWrites; private final boolean javalin6; - private String clientFQN; + private final Set clientFQN = new HashSet<>(); Ctx(ProcessingEnvironment env, PlatformAdapter adapter, boolean generateOpenAPI) { readAdapter = adapter; @@ -243,9 +244,8 @@ public static void validateModule() { logWarn(module, "io.avaje.http.api.javalin only contains SOURCE retention annotations. It should added as `requires static`"); } }); - var fqn = CTX.get().clientFQN; - reader.validateServices("io.avaje.http.client.HttpClient.GeneratedComponent", Set.of(fqn)); + reader.validateServices("io.avaje.http.client.HttpClient.GeneratedComponent", CTX.get().clientFQN); } catch (Exception e) { // can't read module @@ -285,6 +285,6 @@ private static boolean resourceExists(String relativeName) { } public static void addClientComponent(String clientFQN) { - CTX.get().clientFQN = clientFQN; + CTX.get().clientFQN.add(clientFQN); } } diff --git a/tests/test-client-generation/src/main/java/org/example/pkgprivate/PrivateClient.java b/tests/test-client-generation/src/main/java/org/example/pkgprivate/PrivateClient.java new file mode 100644 index 000000000..cb9511b44 --- /dev/null +++ b/tests/test-client-generation/src/main/java/org/example/pkgprivate/PrivateClient.java @@ -0,0 +1,13 @@ +package org.example.pkgprivate; + +import io.avaje.http.api.Client; +import io.avaje.http.api.Get; +import io.avaje.http.api.Header; + +@Client +interface PrivateClient { + + @Get("/private") + String apiCall(@Header("Accept") String accept); + +} diff --git a/tests/test-client/src/main/java/example/github/pkgprivate/SimplePkgPrivate.java b/tests/test-client/src/main/java/example/github/pkgprivate/SimplePkgPrivate.java new file mode 100644 index 000000000..674f1ccb8 --- /dev/null +++ b/tests/test-client/src/main/java/example/github/pkgprivate/SimplePkgPrivate.java @@ -0,0 +1,12 @@ +package example.github.pkgprivate; + +import io.avaje.http.api.Client; +import io.avaje.http.api.Get; +import io.avaje.http.client.HttpException; + +@Client +interface SimplePkgPrivate { + + @Get("private") + String get() throws HttpException; +} diff --git a/tests/test-client/src/main/java/module-info.java b/tests/test-client/src/main/java/module-info.java index a925d770c..a83254a65 100644 --- a/tests/test-client/src/main/java/module-info.java +++ b/tests/test-client/src/main/java/module-info.java @@ -7,5 +7,6 @@ exports example.github; - provides io.avaje.http.client.HttpClient.GeneratedComponent with example.github.httpclient.GeneratedHttpComponent; + provides io.avaje.http.client.HttpClient.GeneratedComponent + with example.github.httpclient.GeneratedHttpComponent, example.github.pkgprivate.PkgprivateHttpComponent; } diff --git a/tests/test-client/src/main/resources/META-INF/services/io.avaje.http.client.HttpClient$GeneratedComponent b/tests/test-client/src/main/resources/META-INF/services/io.avaje.http.client.HttpClient$GeneratedComponent deleted file mode 100644 index d419efe24..000000000 --- a/tests/test-client/src/main/resources/META-INF/services/io.avaje.http.client.HttpClient$GeneratedComponent +++ /dev/null @@ -1 +0,0 @@ -example.github.httpclient.GeneratedHttpComponent \ No newline at end of file diff --git a/tests/test-client/src/test/java/example/github/pkgprivate/PkgPrivateTest.java b/tests/test-client/src/test/java/example/github/pkgprivate/PkgPrivateTest.java new file mode 100644 index 000000000..54ce01373 --- /dev/null +++ b/tests/test-client/src/test/java/example/github/pkgprivate/PkgPrivateTest.java @@ -0,0 +1,43 @@ +package example.github.pkgprivate; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +import io.avaje.http.client.HttpClient; +import io.avaje.jex.Jex; + +class PkgPrivateTest { + + static Jex.Server server = null; + String url = "http://localhost:" + server.port(); + + @BeforeAll + static void startServer() { + server = Jex.create().get("/private", ctx -> ctx.text("myPrivateResult")).port(0).start(); + } + + @AfterAll + static void stop() { + server.shutdown(); + } + + @Test + void test_create() { + final HttpClient client = HttpClient.builder().baseUrl("https://api.github.com").build(); + + final var simple = client.create(SimplePkgPrivate.class); + assertThat(simple).isNotNull(); + } + + @Test + void test_pkg_private() { + final HttpClient client = HttpClient.builder().baseUrl(url).build(); + + final var simple = client.create(SimplePkgPrivate.class); + final var result = simple.get(); + assertThat(result).isEqualTo("myPrivateResult"); + } +} From 29270a2c60c032ff956bafc2c948ca588f173d33 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sun, 26 Jan 2025 15:47:33 -0500 Subject: [PATCH 1234/1323] [jex-generator] Remove Exception from generated signature (#554) * Update ControllerMethodWriter.java * Bump to Jex 3.0-RC15 --------- Co-authored-by: Rob Bygrave --- .../io/avaje/http/generator/jex/ControllerMethodWriter.java | 2 +- tests/pom.xml | 2 +- tests/test-client/pom.xml | 4 ++-- .../src/main/java/org/example/web/TestController.java | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java index c55586912..bdff607aa 100644 --- a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java +++ b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java @@ -157,7 +157,7 @@ void writeHandler(boolean requestScoped) { if (method.isErrorMethod()) { writer.append(" private void _%s(Context ctx, %s ex) {", method.simpleName(), method.exceptionShortName()); } else if (isFilter) { - writer.append(" private void _%s(Context ctx, FilterChain chain) throws Exception {", method.simpleName()); + writer.append(" private void _%s(Context ctx, FilterChain chain) {", method.simpleName()); } else { writer.append(" private void _%s(Context ctx) throws Exception {", method.simpleName()); } diff --git a/tests/pom.xml b/tests/pom.xml index 16ab60bab..104dc8ef2 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -15,7 +15,7 @@ 5.11.4 3.27.3 2.18.2 - 3.0-RC14 + 3.0-RC15 11.1 4.1.6 6.4.0 diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index 46855762f..3a091df45 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -58,10 +58,10 @@ io.avaje avaje-jex - 3.0-RC14 + ${jex.version} test - + io.avaje avaje-http-client-generator diff --git a/tests/test-jex/src/main/java/org/example/web/TestController.java b/tests/test-jex/src/main/java/org/example/web/TestController.java index b25c6a393..0c447d05c 100644 --- a/tests/test-jex/src/main/java/org/example/web/TestController.java +++ b/tests/test-jex/src/main/java/org/example/web/TestController.java @@ -46,8 +46,8 @@ String strBody(@BodyString String body, Context ctx) { } @Filter - void filter(FilterChain chain) throws Exception { - System.err.println("do nothing lmao"); + void filter(FilterChain chain) { + // do nothing chain.proceed(); } From 6c734c05796f99819a9a53393e14d1902ef31a0e Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Mon, 27 Jan 2025 04:12:15 -0500 Subject: [PATCH 1235/1323] [client] rename import types member (#557) --- http-api/src/main/java/io/avaje/http/api/Client.java | 2 +- .../java/io/avaje/http/generator/client/ClientProcessor.java | 2 +- .../src/main/java/org/example/package-info.java | 2 +- .../src/test/java/org/example/CommonApiTest.java | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/http-api/src/main/java/io/avaje/http/api/Client.java b/http-api/src/main/java/io/avaje/http/api/Client.java index a3409a353..32b259239 100644 --- a/http-api/src/main/java/io/avaje/http/api/Client.java +++ b/http-api/src/main/java/io/avaje/http/api/Client.java @@ -53,6 +53,6 @@ /** * Client interface types that we want to generate HTTP clients for. */ - Class[] types(); + Class[] value(); } } diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java index 9b28b0954..f1fae46d6 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientProcessor.java @@ -86,7 +86,7 @@ private void readModule() { } private void writeForImported(Element importedElement) { - ImportPrism.getInstanceOn(importedElement).types().stream() + ImportPrism.getInstanceOn(importedElement).value().stream() .map(ProcessingContext::asElement) .filter(Objects::nonNull) .forEach(this::writeClient); diff --git a/tests/test-client-generation/src/main/java/org/example/package-info.java b/tests/test-client-generation/src/main/java/org/example/package-info.java index 46f00d34e..e9a57c6d7 100644 --- a/tests/test-client-generation/src/main/java/org/example/package-info.java +++ b/tests/test-client-generation/src/main/java/org/example/package-info.java @@ -1,4 +1,4 @@ -@Client.Import(types = OtherApi.class) +@Client.Import(value = OtherApi.class) package org.example; import io.avaje.http.api.Client; diff --git a/tests/test-client-generation/src/test/java/org/example/CommonApiTest.java b/tests/test-client-generation/src/test/java/org/example/CommonApiTest.java index 28eab4660..19ecdcec7 100644 --- a/tests/test-client-generation/src/test/java/org/example/CommonApiTest.java +++ b/tests/test-client-generation/src/test/java/org/example/CommonApiTest.java @@ -12,7 +12,7 @@ import static org.assertj.core.api.Assertions.assertThat; -@Client.Import(types = CommonApi.class) +@Client.Import(CommonApi.class) class CommonApiTest { static CommonApi client; From c310a0cf51f04af77f7e35adf78f3bffb21c47dc Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 28 Jan 2025 07:25:59 +1300 Subject: [PATCH 1236/1323] Version 3.0-RC1 --- htmx-api/pom.xml | 2 +- htmx-nima-jstache/pom.xml | 2 +- htmx-nima/pom.xml | 4 ++-- http-api-javalin/pom.xml | 2 +- http-api/pom.xml | 2 +- http-client-gson-adapter/pom.xml | 4 ++-- http-client-moshi-adapter/pom.xml | 4 ++-- http-client/pom.xml | 2 +- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 2 +- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-generator-sigma/pom.xml | 2 +- http-inject-plugin/pom.xml | 2 +- pom.xml | 4 ++-- tests/pom.xml | 2 +- tests/test-client-generation/pom.xml | 2 +- tests/test-client/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-htmx/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- tests/test-sigma/pom.xml | 2 +- 26 files changed, 30 insertions(+), 30 deletions(-) diff --git a/htmx-api/pom.xml b/htmx-api/pom.xml index c38b1230a..d8fc298fc 100644 --- a/htmx-api/pom.xml +++ b/htmx-api/pom.xml @@ -6,7 +6,7 @@ io.avaje avaje-http-parent - 2.9-RC8 + 3.0-RC1 avaje-htmx-api diff --git a/htmx-nima-jstache/pom.xml b/htmx-nima-jstache/pom.xml index 988f879e4..0176ad624 100644 --- a/htmx-nima-jstache/pom.xml +++ b/htmx-nima-jstache/pom.xml @@ -6,7 +6,7 @@ io.avaje avaje-http-parent - 2.9-RC8 + 3.0-RC1 avaje-htmx-nima-jstache diff --git a/htmx-nima/pom.xml b/htmx-nima/pom.xml index 1669c9244..cdafa303d 100644 --- a/htmx-nima/pom.xml +++ b/htmx-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje avaje-http-parent - 2.9-RC8 + 3.0-RC1 avaje-htmx-nima @@ -21,7 +21,7 @@ io.avaje avaje-htmx-api - 2.9-RC8 + 3.0-RC1 io.helidon.webserver diff --git a/http-api-javalin/pom.xml b/http-api-javalin/pom.xml index 3f03ac99d..87af23037 100644 --- a/http-api-javalin/pom.xml +++ b/http-api-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.9-RC8 + 3.0-RC1 .. diff --git a/http-api/pom.xml b/http-api/pom.xml index 0c2623694..ab3d0f379 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.9-RC8 + 3.0-RC1 .. diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index 79ae60e5a..c5022a482 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.9-RC8 + 3.0-RC1 avaje-http-client-gson @@ -20,7 +20,7 @@ io.avaje avaje-http-client - 2.9-RC8 + 3.0-RC1 provided diff --git a/http-client-moshi-adapter/pom.xml b/http-client-moshi-adapter/pom.xml index ca2219f16..c6b1b2e34 100644 --- a/http-client-moshi-adapter/pom.xml +++ b/http-client-moshi-adapter/pom.xml @@ -3,7 +3,7 @@ io.avaje avaje-http-parent - 2.9-RC8 + 3.0-RC1 avaje-http-client-moshi @@ -19,7 +19,7 @@ io.avaje avaje-http-client - 2.9-RC8 + 3.0-RC1 provided diff --git a/http-client/pom.xml b/http-client/pom.xml index 6909b1bc7..a44487d38 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.9-RC8 + 3.0-RC1 avaje-http-client diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index 2db339d1a..b96f0769b 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.9-RC8 + 3.0-RC1 avaje-http-client-generator diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index f922da9f7..cd1501c39 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.9-RC8 + 3.0-RC1 avaje-http-generator-core diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index 9d217834f..c5fd5f42b 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.9-RC8 + 3.0-RC1 avaje-http-helidon-generator diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index a6612e388..4e103bdce 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.9-RC8 + 3.0-RC1 avaje-http-javalin-generator diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index 493cfefb5..944e4bfa2 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.9-RC8 + 3.0-RC1 avaje-http-jex-generator diff --git a/http-generator-sigma/pom.xml b/http-generator-sigma/pom.xml index c2b88c543..0d0fb5782 100644 --- a/http-generator-sigma/pom.xml +++ b/http-generator-sigma/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.9-RC8 + 3.0-RC1 avaje-http-sigma-generator diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index f832d5efc..a865c4f48 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 2.9-RC8 + 3.0-RC1 .. diff --git a/pom.xml b/pom.xml index 20f78eb6a..a4622f2d0 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-parent - 2.9-RC8 + 3.0-RC1 pom @@ -23,7 +23,7 @@ 2.14.2 3.0-RC10 1.37 - 2025-01-16T05:02:23Z + 2025-01-27T17:59:51Z ${project.build.directory}${file.separator}module-info.shade diff --git a/tests/pom.xml b/tests/pom.xml index 104dc8ef2..8fbac87aa 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 2.9-RC8 + 3.0-RC1 tests diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index b52189471..d11531628 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.9-RC8 + 3.0-RC1 test-client-generation diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index 3a091df45..6bbe89f7f 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.9-RC8 + 3.0-RC1 test-client diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 5ce8b8a23..680bb9ade 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 2.9-RC8 + 3.0-RC1 test-javalin-jsonb diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 8fdd0a68a..efecb734b 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.9-RC8 + 3.0-RC1 test-javalin diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 066a881a4..a60ead06b 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 2.9-RC8 + 3.0-RC1 test-jex diff --git a/tests/test-nima-htmx/pom.xml b/tests/test-nima-htmx/pom.xml index 451cf39cf..9729145a5 100644 --- a/tests/test-nima-htmx/pom.xml +++ b/tests/test-nima-htmx/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.9-RC8 + 3.0-RC1 test-nima-htmx diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 90df6c9a1..2eae8eaa3 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.9-RC8 + 3.0-RC1 test-nima-jsonb diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index 0cd4babff..406d0348a 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 2.9-RC8 + 3.0-RC1 test-nima diff --git a/tests/test-sigma/pom.xml b/tests/test-sigma/pom.xml index 8cd6000c4..b38f2c5fb 100644 --- a/tests/test-sigma/pom.xml +++ b/tests/test-sigma/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 2.9-RC8 + 3.0-RC1 test-sigma From 6eb173f85af152f46da3e20413469fdcce66bbcb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 27 Jan 2025 19:13:31 +0000 Subject: [PATCH 1237/1323] Bump the dependencies group with 6 updates Bumps the dependencies group with 6 updates: | Package | From | To | | --- | --- | --- | | [io.avaje:avaje-prisms](https://github.com/avaje/avaje-prisms) | `1.37` | `1.38` | | [io.avaje:avaje-validator](https://github.com/avaje/avaje-validator) | `2.4` | `2.5` | | io.avaje:avaje-validator-constraints | `2.4` | `2.5` | | io.avaje:avaje-validator-generator | `2.4` | `2.5` | | [io.avaje:avaje-jex](https://github.com/avaje/avaje-jex) | `3.0-RC15` | `3.0-RC16` | | io.avaje:avaje-jex-htmx | `3.0-RC15` | `3.0-RC16` | Updates `io.avaje:avaje-prisms` from 1.37 to 1.38 - [Release notes](https://github.com/avaje/avaje-prisms/releases) - [Commits](https://github.com/avaje/avaje-prisms/compare/1.37...1.38) Updates `io.avaje:avaje-validator` from 2.4 to 2.5 - [Release notes](https://github.com/avaje/avaje-validator/releases) - [Commits](https://github.com/avaje/avaje-validator/compare/2.4...2.5) Updates `io.avaje:avaje-validator-constraints` from 2.4 to 2.5 Updates `io.avaje:avaje-validator-generator` from 2.4 to 2.5 Updates `io.avaje:avaje-jex` from 3.0-RC15 to 3.0-RC16 - [Release notes](https://github.com/avaje/avaje-jex/releases) - [Commits](https://github.com/avaje/avaje-jex/commits) Updates `io.avaje:avaje-jex-htmx` from 3.0-RC15 to 3.0-RC16 Updates `io.avaje:avaje-jex-htmx` from 3.0-RC15 to 3.0-RC16 --- updated-dependencies: - dependency-name: io.avaje:avaje-prisms dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.avaje:avaje-validator dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.avaje:avaje-validator-constraints dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.avaje:avaje-validator-generator dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.avaje:avaje-jex dependency-type: direct:development dependency-group: dependencies - dependency-name: io.avaje:avaje-jex-htmx dependency-type: direct:production dependency-group: dependencies - dependency-name: io.avaje:avaje-jex-htmx dependency-type: direct:production dependency-group: dependencies ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- tests/pom.xml | 8 ++++---- tests/test-javalin/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/pom.xml b/pom.xml index 20f78eb6a..c460b5904 100644 --- a/pom.xml +++ b/pom.xml @@ -22,7 +22,7 @@ 2.2.28 2.14.2 3.0-RC10 - 1.37 + 1.38 2025-01-16T05:02:23Z ${project.build.directory}${file.separator}module-info.shade diff --git a/tests/pom.xml b/tests/pom.xml index 104dc8ef2..3447094eb 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -15,7 +15,7 @@ 5.11.4 3.27.3 2.18.2 - 3.0-RC15 + 3.0-RC16 11.1 4.1.6 6.4.0 @@ -48,19 +48,19 @@ io.avaje avaje-validator - 2.4 + 2.5 io.avaje avaje-validator-constraints - 2.4 + 2.5 io.avaje avaje-validator-generator - 2.4 + 2.5 diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 8fdd0a68a..454e95466 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -57,7 +57,7 @@ io.avaje avaje-validator - 2.4 + 2.5 diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 90df6c9a1..ee3225362 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -90,7 +90,7 @@ io.avaje avaje-validator-generator - 2.4 + 2.5 From 4ab81db0b48934d54fd8c09a7772b9e16fe48c4e Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Tue, 28 Jan 2025 00:13:34 -0500 Subject: [PATCH 1238/1323] Fix test client ruining main detection (#559) --- .../generator/client/ComponentReader.java | 58 +++++++++++-------- .../src/test/java/example/github/Dummy.java | 14 +++++ 2 files changed, 47 insertions(+), 25 deletions(-) create mode 100644 tests/test-client/src/test/java/example/github/Dummy.java diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ComponentReader.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ComponentReader.java index 086103fff..93f101bf0 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ComponentReader.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ComponentReader.java @@ -7,18 +7,18 @@ import static java.util.stream.Collectors.toList; import java.io.FileNotFoundException; -import java.io.LineNumberReader; -import java.io.Reader; +import java.io.IOException; +import java.net.URI; +import java.nio.file.Files; import java.nio.file.NoSuchFileException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; +import java.nio.file.Path; +import java.util.HashSet; import java.util.Map; +import java.util.Set; import javax.annotation.processing.FilerException; import javax.lang.model.element.Modifier; import javax.lang.model.element.TypeElement; -import javax.tools.FileObject; import javax.tools.StandardLocation; import io.avaje.http.generator.core.APContext; @@ -64,32 +64,40 @@ void read() { } } - private List loadMetaInf() { + private Set loadMetaInf() { + var set = new HashSet(); try { - final FileObject fileObject = filer().getResource(StandardLocation.CLASS_OUTPUT, "", Constants.META_INF_COMPONENT); - if (fileObject != null) { - final List lines = new ArrayList<>(); - final Reader reader = fileObject.openReader(true); - final LineNumberReader lineReader = new LineNumberReader(reader); - String line; - while ((line = lineReader.readLine()) != null) { - line = line.trim(); - if (!line.isEmpty()) { - lines.add(line); - } - } - return lines; - } + addLines(mainMetaInfURI(), set); + addLines(metaInfURI(), set); + } catch (final IOException e) { + logWarn("Error reading services file: " + e.getMessage()); + } + return set; + } + private static void addLines(URI uri, HashSet set) { + try (var lines = Files.lines(Path.of(uri))) { + lines.forEach(set::add); } catch (FileNotFoundException | NoSuchFileException e) { // logDebug("no services file yet"); - } catch (final FilerException e) { logDebug("FilerException reading services file"); - - } catch (final Exception e) { + } catch (Exception e) { logWarn("Error reading services file: " + e.getMessage()); } - return Collections.emptyList(); + } + + private static URI mainMetaInfURI() throws IOException { + return URI.create( + metaInfURI() + .toString() + .replaceFirst("java/test", "java/main") + .replaceFirst("test-classes", "classes")); + } + + private static URI metaInfURI() throws IOException { + return filer() + .getResource(StandardLocation.CLASS_OUTPUT, "", Constants.META_INF_COMPONENT) + .toUri(); } } diff --git a/tests/test-client/src/test/java/example/github/Dummy.java b/tests/test-client/src/test/java/example/github/Dummy.java new file mode 100644 index 000000000..2459269fe --- /dev/null +++ b/tests/test-client/src/test/java/example/github/Dummy.java @@ -0,0 +1,14 @@ +package example.github; + +import java.util.List; + +import io.avaje.http.api.Client; +import io.avaje.http.api.Get; +import io.avaje.http.client.HttpException; + +@Client +public interface Dummy { + + @Get("users/{user}/repos") + List listRepos(String user, String other) throws HttpException; +} From d3aba250f0a22691dfac8a98bd27298e1cb1a35b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Feb 2025 19:30:40 +0000 Subject: [PATCH 1239/1323] Bump the dependencies group with 8 updates Bumps the dependencies group with 8 updates: | Package | From | To | | --- | --- | --- | | [io.avaje:avaje-inject](https://github.com/avaje/avaje-inject) | `11.1` | `11.2` | | io.avaje:avaje-inject-generator | `11.1` | `11.2` | | [com.google.code.gson:gson](https://github.com/google/gson) | `2.11.0` | `2.12.1` | | [jakarta.validation:jakarta.validation-api](https://github.com/jakartaee/validation) | `3.1.0` | `3.1.1` | | [io.avaje:avaje-validator](https://github.com/avaje/avaje-validator) | `2.5` | `2.6` | | io.avaje:avaje-validator-constraints | `2.5` | `2.6` | | io.avaje:avaje-validator-generator | `2.5` | `2.6` | | io.avaje:avaje-inject-maven-plugin | `11.1` | `11.2` | Updates `io.avaje:avaje-inject` from 11.1 to 11.2 - [Release notes](https://github.com/avaje/avaje-inject/releases) - [Commits](https://github.com/avaje/avaje-inject/compare/11.1...11.2) Updates `io.avaje:avaje-inject-generator` from 11.1 to 11.2 Updates `io.avaje:avaje-inject-generator` from 11.1 to 11.2 Updates `com.google.code.gson:gson` from 2.11.0 to 2.12.1 - [Release notes](https://github.com/google/gson/releases) - [Changelog](https://github.com/google/gson/blob/main/CHANGELOG.md) - [Commits](https://github.com/google/gson/compare/gson-parent-2.11.0...gson-parent-2.12.1) Updates `jakarta.validation:jakarta.validation-api` from 3.1.0 to 3.1.1 - [Release notes](https://github.com/jakartaee/validation/releases) - [Commits](https://github.com/jakartaee/validation/compare/3.1.0...3.1.1) Updates `io.avaje:avaje-validator` from 2.5 to 2.6 - [Release notes](https://github.com/avaje/avaje-validator/releases) - [Commits](https://github.com/avaje/avaje-validator/compare/2.5...2.6) Updates `io.avaje:avaje-validator-constraints` from 2.5 to 2.6 Updates `io.avaje:avaje-validator-generator` from 2.5 to 2.6 Updates `io.avaje:avaje-inject-maven-plugin` from 11.1 to 11.2 --- updated-dependencies: - dependency-name: io.avaje:avaje-inject dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.avaje:avaje-inject-generator dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.avaje:avaje-inject-generator dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: com.google.code.gson:gson dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: jakarta.validation:jakarta.validation-api dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: io.avaje:avaje-validator dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.avaje:avaje-validator-constraints dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.avaje:avaje-validator-generator dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.avaje:avaje-inject-maven-plugin dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies ... Signed-off-by: dependabot[bot] --- htmx-nima-jstache/pom.xml | 2 +- http-client-gson-adapter/pom.xml | 2 +- http-client/pom.xml | 4 ++-- http-generator-core/pom.xml | 2 +- http-inject-plugin/pom.xml | 2 +- tests/pom.xml | 8 ++++---- tests/test-client-generation/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-nima-htmx/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 4 ++-- tests/test-nima/pom.xml | 2 +- 11 files changed, 16 insertions(+), 16 deletions(-) diff --git a/htmx-nima-jstache/pom.xml b/htmx-nima-jstache/pom.xml index 0176ad624..02ec227be 100644 --- a/htmx-nima-jstache/pom.xml +++ b/htmx-nima-jstache/pom.xml @@ -39,7 +39,7 @@ io.avaje avaje-inject - 11.1 + 11.2 provided true diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index c5022a482..21fcba9be 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -14,7 +14,7 @@ com.google.code.gson gson - 2.11.0 + 2.12.1 diff --git a/http-client/pom.xml b/http-client/pom.xml index a44487d38..6e4d294d8 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -50,7 +50,7 @@ io.avaje avaje-inject - 11.1 + 11.2 true @@ -106,7 +106,7 @@ io.avaje avaje-inject-generator - 11.1 + 11.2 diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index cd1501c39..5f6121b44 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -57,7 +57,7 @@ jakarta.validation jakarta.validation-api - 3.1.0 + 3.1.1 true provided diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index a865c4f48..833daac5d 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -19,7 +19,7 @@ io.avaje avaje-inject - 11.1 + 11.2 provided true diff --git a/tests/pom.xml b/tests/pom.xml index 461d5c0f7..134c0f3c6 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -16,7 +16,7 @@ 3.27.3 2.18.2 3.0-RC16 - 11.1 + 11.2 4.1.6 6.4.0 @@ -48,19 +48,19 @@ io.avaje avaje-validator - 2.5 + 2.6 io.avaje avaje-validator-constraints - 2.5 + 2.6 io.avaje avaje-validator-generator - 2.5 + 2.6 diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index d11531628..6b31f5489 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -141,7 +141,7 @@ io.avaje avaje-inject-maven-plugin - 11.1 + 11.2 process-sources diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 53dfd9635..37c75adf5 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -57,7 +57,7 @@ io.avaje avaje-validator - 2.5 + 2.6 diff --git a/tests/test-nima-htmx/pom.xml b/tests/test-nima-htmx/pom.xml index 9729145a5..65d413d7f 100644 --- a/tests/test-nima-htmx/pom.xml +++ b/tests/test-nima-htmx/pom.xml @@ -103,7 +103,7 @@ io.avaje avaje-inject-maven-plugin - 11.1 + 11.2 process-sources diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 1df70846a..1525e484b 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -90,7 +90,7 @@ io.avaje avaje-validator-generator - 2.5 + 2.6 @@ -109,7 +109,7 @@ io.avaje avaje-inject-maven-plugin - 11.1 + 11.2 process-sources diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index 406d0348a..bb6860e46 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -90,7 +90,7 @@ io.avaje avaje-inject-maven-plugin - 11.1 + 11.2 process-sources From 86e7fa6e49ec58c9dc7e370038306718f8de5626 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Mon, 10 Feb 2025 14:00:17 +1300 Subject: [PATCH 1240/1323] Update to avaje-jsonb 3.0-RC7 with SimpleMapper renamed to JsonMapper (#562) For http-client SingleBodyAdapter and Cognito AuthTokenProvider --- aws-cognito/http-client-authtoken/pom.xml | 4 ++-- .../client/cognito/AmzCognitoAuthTokenProvider.java | 4 ++-- http-client/pom.xml | 4 ++-- .../main/java/io/avaje/http/client/DSingleAdapter.java | 10 +++++----- .../java/io/avaje/http/client/SingleBodyAdapter.java | 4 ++-- .../java/io/avaje/http/client/HelloControllerTest.java | 6 +++--- 6 files changed, 16 insertions(+), 16 deletions(-) diff --git a/aws-cognito/http-client-authtoken/pom.xml b/aws-cognito/http-client-authtoken/pom.xml index efbab1311..77164d4d1 100644 --- a/aws-cognito/http-client-authtoken/pom.xml +++ b/aws-cognito/http-client-authtoken/pom.xml @@ -23,14 +23,14 @@ io.avaje avaje-json-core - 3.0-RC6 + 3.0-RC7 io.avaje avaje-json-node - 3.0-RC6 + 3.0-RC7 test diff --git a/aws-cognito/http-client-authtoken/src/main/java/io/avaje/aws/client/cognito/AmzCognitoAuthTokenProvider.java b/aws-cognito/http-client-authtoken/src/main/java/io/avaje/aws/client/cognito/AmzCognitoAuthTokenProvider.java index 359fbfcae..437421f99 100644 --- a/aws-cognito/http-client-authtoken/src/main/java/io/avaje/aws/client/cognito/AmzCognitoAuthTokenProvider.java +++ b/aws-cognito/http-client-authtoken/src/main/java/io/avaje/aws/client/cognito/AmzCognitoAuthTokenProvider.java @@ -4,7 +4,7 @@ import io.avaje.http.client.AuthTokenProvider; import io.avaje.http.client.BasicAuthIntercept; import io.avaje.http.client.HttpClientRequest; -import io.avaje.json.simple.SimpleMapper; +import io.avaje.json.mapper.JsonMapper; import java.net.http.HttpResponse; import java.time.Instant; @@ -47,7 +47,7 @@ public AuthTokenProvider build() { private static final class Provider implements AuthTokenProvider { - private static final SimpleMapper MAPPER = SimpleMapper.builder().build(); + private static final JsonMapper MAPPER = JsonMapper.builder().build(); private final String url; private final String clientId; diff --git a/http-client/pom.xml b/http-client/pom.xml index 6e4d294d8..4d01f268a 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -36,14 +36,14 @@ io.avaje avaje-jsonb - 3.0-RC6 + 3.0-RC7 true io.avaje avaje-json-node - 3.0-RC6 + 3.0-RC7 test diff --git a/http-client/src/main/java/io/avaje/http/client/DSingleAdapter.java b/http-client/src/main/java/io/avaje/http/client/DSingleAdapter.java index 8d9e80478..864a2f0e9 100644 --- a/http-client/src/main/java/io/avaje/http/client/DSingleAdapter.java +++ b/http-client/src/main/java/io/avaje/http/client/DSingleAdapter.java @@ -1,7 +1,7 @@ package io.avaje.http.client; import io.avaje.http.client.SingleBodyAdapter.JsonBodyAdapter; -import io.avaje.json.simple.SimpleMapper; +import io.avaje.json.mapper.JsonMapper; import java.util.List; @@ -10,7 +10,7 @@ final class DSingleAdapter implements BodyAdapter { private final ReaderWriter adapter; - static BodyAdapter of(SimpleMapper.Type jsonType) { + static BodyAdapter of(JsonMapper.Type jsonType) { return new DSingleAdapter(toAdapter(jsonType)); } @@ -22,7 +22,7 @@ private DSingleAdapter(JsonBodyAdapter source) { this.adapter = new ReaderWriter<>(source); } - private static JsonBodyAdapter toAdapter(SimpleMapper.Type jsonType) { + private static JsonBodyAdapter toAdapter(JsonMapper.Type jsonType) { return new SimpleJsonAdapter<>(jsonType); } @@ -72,9 +72,9 @@ public BodyContent write(T bean) { private static final class SimpleJsonAdapter implements JsonBodyAdapter { - private final SimpleMapper.Type jsonType; + private final JsonMapper.Type jsonType; - public SimpleJsonAdapter(SimpleMapper.Type jsonType) { + public SimpleJsonAdapter(JsonMapper.Type jsonType) { this.jsonType = jsonType; } diff --git a/http-client/src/main/java/io/avaje/http/client/SingleBodyAdapter.java b/http-client/src/main/java/io/avaje/http/client/SingleBodyAdapter.java index 7aafb5f11..c9546f25b 100644 --- a/http-client/src/main/java/io/avaje/http/client/SingleBodyAdapter.java +++ b/http-client/src/main/java/io/avaje/http/client/SingleBodyAdapter.java @@ -1,6 +1,6 @@ package io.avaje.http.client; -import io.avaje.json.simple.SimpleMapper; +import io.avaje.json.mapper.JsonMapper; /** * A BodyAdapter that supports converting the request/response body to a single type. @@ -25,7 +25,7 @@ static BodyAdapter create(JsonBodyAdapter jsonAdapter) { * @param jsonType The only type supported to read or write the body content. * @return The BodyAdapter that the HttpClient can use. */ - static BodyAdapter create(SimpleMapper.Type jsonType) { + static BodyAdapter create(JsonMapper.Type jsonType) { return DSingleAdapter.of(jsonType); } diff --git a/http-client/src/test/java/io/avaje/http/client/HelloControllerTest.java b/http-client/src/test/java/io/avaje/http/client/HelloControllerTest.java index 04da68cc1..b6ae766d9 100644 --- a/http-client/src/test/java/io/avaje/http/client/HelloControllerTest.java +++ b/http-client/src/test/java/io/avaje/http/client/HelloControllerTest.java @@ -1,7 +1,7 @@ package io.avaje.http.client; import com.fasterxml.jackson.databind.ObjectMapper; -import io.avaje.json.simple.SimpleMapper; +import io.avaje.json.mapper.JsonMapper; import org.example.webserver.ErrorResponse; import org.example.webserver.HelloDto; import org.junit.jupiter.api.Test; @@ -821,9 +821,9 @@ void get_bean_404() { @Test void singleBodyAdapter_returningBean() { - var simpleMapper = SimpleMapper.builder().build(); + var mapper = JsonMapper.builder().build(); - SimpleMapper.Type type = simpleMapper.type(new HelloDtoAdapter()); + JsonMapper.Type type = mapper.type(new HelloDtoAdapter()); BodyAdapter bodyAdapter = SingleBodyAdapter.create(type); HttpClient client = client(bodyAdapter); From 99cfc51a4f999ec66619860ff36de810bd87a661 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sun, 9 Feb 2025 20:45:39 -0500 Subject: [PATCH 1241/1323] update jex context package --- .../java/io/avaje/http/generator/jex/ControllerWriter.java | 4 ++-- tests/pom.xml | 2 +- .../src/main/java/org/example/web/TestController.java | 4 ++-- .../src/main/java/org/example/web/myapp/WebController.java | 4 +--- 4 files changed, 6 insertions(+), 8 deletions(-) diff --git a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerWriter.java b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerWriter.java index 410bb0578..da470c8b4 100644 --- a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerWriter.java +++ b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerWriter.java @@ -13,7 +13,7 @@ class ControllerWriter extends BaseControllerWriter { private static final String AT_GENERATED = "@Generated(\"avaje-jex-generator\")"; - private static final String API_CONTEXT = "io.avaje.jex.Context"; + private static final String API_CONTEXT = "io.avaje.jex.http.Context"; private static final String API_ROUTING = "io.avaje.jex.Routing"; private final boolean useJsonB; private final Map jsonTypes; @@ -27,7 +27,7 @@ class ControllerWriter extends BaseControllerWriter { if (reader.methods().stream() .map(MethodReader::webMethod) .anyMatch(w -> CoreWebMethod.FILTER == w)) { - reader.addImportType("io.avaje.jex.HttpFilter.FilterChain"); + reader.addImportType("io.avaje.jex.http.HttpFilter.FilterChain"); } if (reader.methods().stream() .map(MethodReader::hxRequest) diff --git a/tests/pom.xml b/tests/pom.xml index 134c0f3c6..09702382a 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -15,7 +15,7 @@ 5.11.4 3.27.3 2.18.2 - 3.0-RC16 + 3.0-RC18 11.2 4.1.6 6.4.0 diff --git a/tests/test-jex/src/main/java/org/example/web/TestController.java b/tests/test-jex/src/main/java/org/example/web/TestController.java index 0c447d05c..9b61882e6 100644 --- a/tests/test-jex/src/main/java/org/example/web/TestController.java +++ b/tests/test-jex/src/main/java/org/example/web/TestController.java @@ -13,8 +13,8 @@ import io.avaje.http.api.Post; import io.avaje.http.api.Produces; import io.avaje.http.api.QueryParam; -import io.avaje.jex.Context; -import io.avaje.jex.HttpFilter.FilterChain; +import io.avaje.jex.http.Context; +import io.avaje.jex.http.HttpFilter.FilterChain; @Path("test/") @Controller diff --git a/tests/test-jex/src/main/java/org/example/web/myapp/WebController.java b/tests/test-jex/src/main/java/org/example/web/myapp/WebController.java index ca73d0542..47ff90274 100644 --- a/tests/test-jex/src/main/java/org/example/web/myapp/WebController.java +++ b/tests/test-jex/src/main/java/org/example/web/myapp/WebController.java @@ -6,8 +6,6 @@ import java.util.ArrayList; import java.util.List; import java.util.Optional; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.Executors; import org.example.web.AppRoles; import org.example.web.myapp.other.Foo; @@ -25,7 +23,7 @@ import io.avaje.http.api.Produces; import io.avaje.http.api.QueryParam; import io.avaje.http.api.Valid; -import io.avaje.jex.Context; +import io.avaje.jex.http.Context; import io.swagger.v3.oas.annotations.Hidden; import jakarta.inject.Inject; From 186f0e17a0eadf9ff7faefcc907b26cbf7348356 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sun, 9 Feb 2025 22:31:02 -0500 Subject: [PATCH 1242/1323] fix test --- .../main/java/io/avaje/http/generator/jex/JexAdapter.java | 2 +- .../src/main/java/org/example/web/HelloController.java | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/JexAdapter.java b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/JexAdapter.java index 730fd52f6..100589c1f 100644 --- a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/JexAdapter.java +++ b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/JexAdapter.java @@ -12,7 +12,7 @@ class JexAdapter implements PlatformAdapter { - static final String JEX_CONTEXT = "io.avaje.jex.Context"; + static final String JEX_CONTEXT = "io.avaje.jex.http.Context"; @Override public boolean isContextType(String rawType) { diff --git a/tests/test-jex/src/main/java/org/example/web/HelloController.java b/tests/test-jex/src/main/java/org/example/web/HelloController.java index 899acb8f3..8f56f008f 100644 --- a/tests/test-jex/src/main/java/org/example/web/HelloController.java +++ b/tests/test-jex/src/main/java/org/example/web/HelloController.java @@ -1,5 +1,7 @@ package org.example.web; +import java.math.BigInteger; + import io.avaje.http.api.Controller; import io.avaje.http.api.Default; import io.avaje.http.api.Get; @@ -7,9 +9,7 @@ import io.avaje.http.api.Produces; import io.avaje.http.api.Put; import io.avaje.http.api.Valid; -import io.avaje.jex.Context; - -import java.math.BigInteger; +import io.avaje.jex.http.Context; // @Roles(AppRoles.BASIC_USER) @Controller From d7d8c5d88649d0c2b2706243d012dc25821fb658 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Mon, 10 Feb 2025 21:31:32 +1300 Subject: [PATCH 1243/1323] Version 3.0-RC2 --- aws-cognito/http-client-authtoken/pom.xml | 2 +- htmx-api/pom.xml | 2 +- htmx-nima-jstache/pom.xml | 2 +- htmx-nima/pom.xml | 4 ++-- http-api-javalin/pom.xml | 2 +- http-api/pom.xml | 2 +- http-client-gson-adapter/pom.xml | 4 ++-- http-client-moshi-adapter/pom.xml | 4 ++-- http-client/pom.xml | 2 +- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 2 +- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-generator-sigma/pom.xml | 2 +- http-inject-plugin/pom.xml | 2 +- pom.xml | 4 ++-- tests/pom.xml | 2 +- tests/test-client-generation/pom.xml | 2 +- tests/test-client/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-htmx/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- tests/test-sigma/pom.xml | 2 +- 27 files changed, 31 insertions(+), 31 deletions(-) diff --git a/aws-cognito/http-client-authtoken/pom.xml b/aws-cognito/http-client-authtoken/pom.xml index 77164d4d1..670a3f0b4 100644 --- a/aws-cognito/http-client-authtoken/pom.xml +++ b/aws-cognito/http-client-authtoken/pom.xml @@ -11,7 +11,7 @@ io.avaje.aws avaje-cognito-client-token - 1.0-RC1 + 1.0-RC2 diff --git a/htmx-api/pom.xml b/htmx-api/pom.xml index d8fc298fc..32c58716d 100644 --- a/htmx-api/pom.xml +++ b/htmx-api/pom.xml @@ -6,7 +6,7 @@ io.avaje avaje-http-parent - 3.0-RC1 + 3.0-RC2 avaje-htmx-api diff --git a/htmx-nima-jstache/pom.xml b/htmx-nima-jstache/pom.xml index 02ec227be..8a36dcc72 100644 --- a/htmx-nima-jstache/pom.xml +++ b/htmx-nima-jstache/pom.xml @@ -6,7 +6,7 @@ io.avaje avaje-http-parent - 3.0-RC1 + 3.0-RC2 avaje-htmx-nima-jstache diff --git a/htmx-nima/pom.xml b/htmx-nima/pom.xml index cdafa303d..2317fbe37 100644 --- a/htmx-nima/pom.xml +++ b/htmx-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje avaje-http-parent - 3.0-RC1 + 3.0-RC2 avaje-htmx-nima @@ -21,7 +21,7 @@ io.avaje avaje-htmx-api - 3.0-RC1 + 3.0-RC2 io.helidon.webserver diff --git a/http-api-javalin/pom.xml b/http-api-javalin/pom.xml index 87af23037..c82bef135 100644 --- a/http-api-javalin/pom.xml +++ b/http-api-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.0-RC1 + 3.0-RC2 .. diff --git a/http-api/pom.xml b/http-api/pom.xml index ab3d0f379..0311969a1 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.0-RC1 + 3.0-RC2 .. diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index 21fcba9be..3834846da 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.0-RC1 + 3.0-RC2 avaje-http-client-gson @@ -20,7 +20,7 @@ io.avaje avaje-http-client - 3.0-RC1 + 3.0-RC2 provided diff --git a/http-client-moshi-adapter/pom.xml b/http-client-moshi-adapter/pom.xml index c6b1b2e34..cdca0846d 100644 --- a/http-client-moshi-adapter/pom.xml +++ b/http-client-moshi-adapter/pom.xml @@ -3,7 +3,7 @@ io.avaje avaje-http-parent - 3.0-RC1 + 3.0-RC2 avaje-http-client-moshi @@ -19,7 +19,7 @@ io.avaje avaje-http-client - 3.0-RC1 + 3.0-RC2 provided diff --git a/http-client/pom.xml b/http-client/pom.xml index 4d01f268a..54dbb5cef 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.0-RC1 + 3.0-RC2 avaje-http-client diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index b96f0769b..3aedbd118 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.0-RC1 + 3.0-RC2 avaje-http-client-generator diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 5f6121b44..d4150a977 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.0-RC1 + 3.0-RC2 avaje-http-generator-core diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index c5fd5f42b..b60d25d41 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 3.0-RC1 + 3.0-RC2 avaje-http-helidon-generator diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index 4e103bdce..c401b4df5 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.0-RC1 + 3.0-RC2 avaje-http-javalin-generator diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index 944e4bfa2..9d2e9a95c 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.0-RC1 + 3.0-RC2 avaje-http-jex-generator diff --git a/http-generator-sigma/pom.xml b/http-generator-sigma/pom.xml index 0d0fb5782..2447a3e30 100644 --- a/http-generator-sigma/pom.xml +++ b/http-generator-sigma/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.0-RC1 + 3.0-RC2 avaje-http-sigma-generator diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index 833daac5d..2fb54abac 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.0-RC1 + 3.0-RC2 .. diff --git a/pom.xml b/pom.xml index 14bf1d9ee..0a2306101 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-parent - 3.0-RC1 + 3.0-RC2 pom @@ -23,7 +23,7 @@ 2.14.2 3.0-RC10 1.38 - 2025-01-16T05:02:23Z + 2025-02-10T07:09:31Z ${project.build.directory}${file.separator}module-info.shade diff --git a/tests/pom.xml b/tests/pom.xml index 09702382a..dc2161343 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 3.0-RC1 + 3.0-RC2 tests diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index 6b31f5489..a49b1ce91 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 3.0-RC1 + 3.0-RC2 test-client-generation diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index 6bbe89f7f..cc06ce169 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 3.0-RC1 + 3.0-RC2 test-client diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 680bb9ade..417a78af2 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 3.0-RC1 + 3.0-RC2 test-javalin-jsonb diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 37c75adf5..e010a106a 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 3.0-RC1 + 3.0-RC2 test-javalin diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index a60ead06b..db631ad58 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 3.0-RC1 + 3.0-RC2 test-jex diff --git a/tests/test-nima-htmx/pom.xml b/tests/test-nima-htmx/pom.xml index 65d413d7f..dbf6cbc1d 100644 --- a/tests/test-nima-htmx/pom.xml +++ b/tests/test-nima-htmx/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 3.0-RC1 + 3.0-RC2 test-nima-htmx diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 1525e484b..b41318e46 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 3.0-RC1 + 3.0-RC2 test-nima-jsonb diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index bb6860e46..fa71d2f47 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 3.0-RC1 + 3.0-RC2 test-nima diff --git a/tests/test-sigma/pom.xml b/tests/test-sigma/pom.xml index b38f2c5fb..1c9aa7d0e 100644 --- a/tests/test-sigma/pom.xml +++ b/tests/test-sigma/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 3.0-RC1 + 3.0-RC2 test-sigma From 03ede3c61cfe19695458e385e4ff8b8eeb58ebb5 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Mon, 10 Feb 2025 21:40:20 +1300 Subject: [PATCH 1244/1323] Update to avaje-jsonb version 3.0 --- aws-cognito/http-client-authtoken/pom.xml | 6 +++--- http-client/pom.xml | 4 ++-- tests/test-javalin-jsonb/pom.xml | 10 +++++----- tests/test-jex/pom.xml | 4 ++-- tests/test-nima-htmx/pom.xml | 4 ++-- tests/test-nima-jsonb/pom.xml | 4 ++-- tests/test-sigma/pom.xml | 4 ++-- 7 files changed, 18 insertions(+), 18 deletions(-) diff --git a/aws-cognito/http-client-authtoken/pom.xml b/aws-cognito/http-client-authtoken/pom.xml index 670a3f0b4..88540c8d1 100644 --- a/aws-cognito/http-client-authtoken/pom.xml +++ b/aws-cognito/http-client-authtoken/pom.xml @@ -17,20 +17,20 @@ io.avaje avaje-http-client - 2.8 + 3.0-RC2 io.avaje avaje-json-core - 3.0-RC7 + 3.0 io.avaje avaje-json-node - 3.0-RC7 + 3.0 test diff --git a/http-client/pom.xml b/http-client/pom.xml index 54dbb5cef..4502922ec 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -36,14 +36,14 @@ io.avaje avaje-jsonb - 3.0-RC7 + 3.0 true io.avaje avaje-json-node - 3.0-RC7 + 3.0 test diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 417a78af2..53ec71ba0 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -53,8 +53,8 @@ io.swagger.core.v3 swagger-annotations ${swagger.version} - - + + @@ -74,16 +74,16 @@ io.avaje avaje-jsonb - 3.0-RC6 + 3.0 io.avaje avaje-jsonb-generator - 3.0-RC5 + 3.0 provided - + io.avaje diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index db631ad58..ca9d14ce7 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -74,7 +74,7 @@ io.avaje avaje-jsonb - 3.0-RC6 + 3.0 @@ -96,7 +96,7 @@ io.avaje avaje-jsonb-generator - 3.0-RC5 + 3.0 diff --git a/tests/test-nima-htmx/pom.xml b/tests/test-nima-htmx/pom.xml index dbf6cbc1d..abe5e1f8d 100644 --- a/tests/test-nima-htmx/pom.xml +++ b/tests/test-nima-htmx/pom.xml @@ -49,7 +49,7 @@ avaje-nima 1.1 - + io.avaje avaje-http-helidon-generator @@ -88,7 +88,7 @@ io.avaje avaje-jsonb-generator - 2.4 + 3.0 io.jstach diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index b41318e46..ac1998d56 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -31,7 +31,7 @@ io.avaje avaje-jsonb - 3.0-RC6 + 3.0 io.helidon.webserver @@ -85,7 +85,7 @@ io.avaje avaje-jsonb-generator - 3.0-RC2 + 3.0 io.avaje diff --git a/tests/test-sigma/pom.xml b/tests/test-sigma/pom.xml index 1c9aa7d0e..186881f55 100644 --- a/tests/test-sigma/pom.xml +++ b/tests/test-sigma/pom.xml @@ -67,12 +67,12 @@ io.avaje avaje-jsonb - 3.0-RC6 + 3.0 io.avaje avaje-jsonb-generator - 3.0-RC5 + 3.0 provided From 1d869c09d5de3d499c3965d8b92eb988839c59a9 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Mon, 10 Feb 2025 21:41:25 +1300 Subject: [PATCH 1245/1323] Version 3.0 --- aws-cognito/http-client-authtoken/pom.xml | 2 +- htmx-api/pom.xml | 2 +- htmx-nima-jstache/pom.xml | 2 +- htmx-nima/pom.xml | 4 ++-- http-api-javalin/pom.xml | 2 +- http-api/pom.xml | 2 +- http-client-gson-adapter/pom.xml | 4 ++-- http-client-moshi-adapter/pom.xml | 4 ++-- http-client/pom.xml | 2 +- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 2 +- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-generator-sigma/pom.xml | 2 +- http-inject-plugin/pom.xml | 2 +- pom.xml | 4 ++-- tests/pom.xml | 2 +- tests/test-client-generation/pom.xml | 2 +- tests/test-client/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-htmx/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- tests/test-sigma/pom.xml | 2 +- 27 files changed, 31 insertions(+), 31 deletions(-) diff --git a/aws-cognito/http-client-authtoken/pom.xml b/aws-cognito/http-client-authtoken/pom.xml index 88540c8d1..4d46c79e4 100644 --- a/aws-cognito/http-client-authtoken/pom.xml +++ b/aws-cognito/http-client-authtoken/pom.xml @@ -17,7 +17,7 @@ io.avaje avaje-http-client - 3.0-RC2 + 3.0 diff --git a/htmx-api/pom.xml b/htmx-api/pom.xml index 32c58716d..0692c6e91 100644 --- a/htmx-api/pom.xml +++ b/htmx-api/pom.xml @@ -6,7 +6,7 @@ io.avaje avaje-http-parent - 3.0-RC2 + 3.0 avaje-htmx-api diff --git a/htmx-nima-jstache/pom.xml b/htmx-nima-jstache/pom.xml index 8a36dcc72..76a642715 100644 --- a/htmx-nima-jstache/pom.xml +++ b/htmx-nima-jstache/pom.xml @@ -6,7 +6,7 @@ io.avaje avaje-http-parent - 3.0-RC2 + 3.0 avaje-htmx-nima-jstache diff --git a/htmx-nima/pom.xml b/htmx-nima/pom.xml index 2317fbe37..547162a13 100644 --- a/htmx-nima/pom.xml +++ b/htmx-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje avaje-http-parent - 3.0-RC2 + 3.0 avaje-htmx-nima @@ -21,7 +21,7 @@ io.avaje avaje-htmx-api - 3.0-RC2 + 3.0 io.helidon.webserver diff --git a/http-api-javalin/pom.xml b/http-api-javalin/pom.xml index c82bef135..0863ee7a3 100644 --- a/http-api-javalin/pom.xml +++ b/http-api-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.0-RC2 + 3.0 .. diff --git a/http-api/pom.xml b/http-api/pom.xml index 0311969a1..7754ff9df 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.0-RC2 + 3.0 .. diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index 3834846da..9e71b8088 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.0-RC2 + 3.0 avaje-http-client-gson @@ -20,7 +20,7 @@ io.avaje avaje-http-client - 3.0-RC2 + 3.0 provided diff --git a/http-client-moshi-adapter/pom.xml b/http-client-moshi-adapter/pom.xml index cdca0846d..956cd96fa 100644 --- a/http-client-moshi-adapter/pom.xml +++ b/http-client-moshi-adapter/pom.xml @@ -3,7 +3,7 @@ io.avaje avaje-http-parent - 3.0-RC2 + 3.0 avaje-http-client-moshi @@ -19,7 +19,7 @@ io.avaje avaje-http-client - 3.0-RC2 + 3.0 provided diff --git a/http-client/pom.xml b/http-client/pom.xml index 4502922ec..5eb547f6d 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.0-RC2 + 3.0 avaje-http-client diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index 3aedbd118..78fe5f976 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.0-RC2 + 3.0 avaje-http-client-generator diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index d4150a977..3294d9125 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.0-RC2 + 3.0 avaje-http-generator-core diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index b60d25d41..54aa6753b 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 3.0-RC2 + 3.0 avaje-http-helidon-generator diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index c401b4df5..faaa1af9e 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.0-RC2 + 3.0 avaje-http-javalin-generator diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index 9d2e9a95c..d765f58c3 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.0-RC2 + 3.0 avaje-http-jex-generator diff --git a/http-generator-sigma/pom.xml b/http-generator-sigma/pom.xml index 2447a3e30..a63121afd 100644 --- a/http-generator-sigma/pom.xml +++ b/http-generator-sigma/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.0-RC2 + 3.0 avaje-http-sigma-generator diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index 2fb54abac..b7d661e41 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.0-RC2 + 3.0 .. diff --git a/pom.xml b/pom.xml index 0a2306101..e9d5c9deb 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-parent - 3.0-RC2 + 3.0 pom @@ -23,7 +23,7 @@ 2.14.2 3.0-RC10 1.38 - 2025-02-10T07:09:31Z + 2025-02-10T08:40:37Z ${project.build.directory}${file.separator}module-info.shade diff --git a/tests/pom.xml b/tests/pom.xml index dc2161343..1d3e742d0 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 3.0-RC2 + 3.0 tests diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index a49b1ce91..d13ec4659 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 3.0-RC2 + 3.0 test-client-generation diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index cc06ce169..3497b45b8 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 3.0-RC2 + 3.0 test-client diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 53ec71ba0..aadaa7ecd 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 3.0-RC2 + 3.0 test-javalin-jsonb diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index e010a106a..90cdf5516 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 3.0-RC2 + 3.0 test-javalin diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index ca9d14ce7..74d429955 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 3.0-RC2 + 3.0 test-jex diff --git a/tests/test-nima-htmx/pom.xml b/tests/test-nima-htmx/pom.xml index abe5e1f8d..4971eeeb5 100644 --- a/tests/test-nima-htmx/pom.xml +++ b/tests/test-nima-htmx/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 3.0-RC2 + 3.0 test-nima-htmx diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index ac1998d56..b5a34d359 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 3.0-RC2 + 3.0 test-nima-jsonb diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index fa71d2f47..4eefbe5fe 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 3.0-RC2 + 3.0 test-nima diff --git a/tests/test-sigma/pom.xml b/tests/test-sigma/pom.xml index 186881f55..37bfac092 100644 --- a/tests/test-sigma/pom.xml +++ b/tests/test-sigma/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 3.0-RC2 + 3.0 test-sigma From 51a3930aaf302956912c95a005a9b1aed1312094 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 10 Feb 2025 19:58:48 +0000 Subject: [PATCH 1246/1323] Bump the dependencies group with 3 updates Bumps the dependencies group with 3 updates: [io.avaje:avaje-validator](https://github.com/avaje/avaje-validator), io.avaje:avaje-validator-constraints and io.avaje:avaje-validator-generator. Updates `io.avaje:avaje-validator` from 2.6 to 2.7 - [Release notes](https://github.com/avaje/avaje-validator/releases) - [Commits](https://github.com/avaje/avaje-validator/compare/2.6...2.7) Updates `io.avaje:avaje-validator-constraints` from 2.6 to 2.7 Updates `io.avaje:avaje-validator-generator` from 2.6 to 2.7 --- updated-dependencies: - dependency-name: io.avaje:avaje-validator dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.avaje:avaje-validator-constraints dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.avaje:avaje-validator-generator dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies ... Signed-off-by: dependabot[bot] --- tests/pom.xml | 6 +++--- tests/test-javalin/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/pom.xml b/tests/pom.xml index 1d3e742d0..6be019994 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -48,19 +48,19 @@ io.avaje avaje-validator - 2.6 + 2.7 io.avaje avaje-validator-constraints - 2.6 + 2.7 io.avaje avaje-validator-generator - 2.6 + 2.7 diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 90cdf5516..0a92c05de 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -57,7 +57,7 @@ io.avaje avaje-validator - 2.6 + 2.7 diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index b5a34d359..8154fa6cd 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -90,7 +90,7 @@ io.avaje avaje-validator-generator - 2.6 + 2.7 From a91b523ce373c2567cac49075606c3c71189f1a8 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 18 Feb 2025 08:00:10 +1300 Subject: [PATCH 1247/1323] avaje-cognito-client-token Version 1.0 --- aws-cognito/http-client-authtoken/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aws-cognito/http-client-authtoken/pom.xml b/aws-cognito/http-client-authtoken/pom.xml index 4d46c79e4..bb288726d 100644 --- a/aws-cognito/http-client-authtoken/pom.xml +++ b/aws-cognito/http-client-authtoken/pom.xml @@ -11,7 +11,7 @@ io.avaje.aws avaje-cognito-client-token - 1.0-RC2 + 1.0 From f32f46a40c9897384aa17230791d512ceb433958 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 17 Feb 2025 19:13:39 +0000 Subject: [PATCH 1248/1323] Bump io.rest-assured:rest-assured in the dependencies group Bumps the dependencies group with 1 update: [io.rest-assured:rest-assured](https://github.com/rest-assured/rest-assured). Updates `io.rest-assured:rest-assured` from 5.5.0 to 5.5.1 - [Changelog](https://github.com/rest-assured/rest-assured/blob/master/changelog.txt) - [Commits](https://github.com/rest-assured/rest-assured/compare/rest-assured-5.5.0...rest-assured-5.5.1) --- updated-dependencies: - dependency-name: io.rest-assured:rest-assured dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies ... Signed-off-by: dependabot[bot] --- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index aadaa7ecd..23a24c337 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -95,7 +95,7 @@ io.rest-assured rest-assured - 5.5.0 + 5.5.1 test diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 0a92c05de..99ab6d110 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -93,7 +93,7 @@ io.rest-assured rest-assured - 5.5.0 + 5.5.1 test From 684007389188362ed89543aed98bbb8d24716fd7 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Thu, 20 Feb 2025 03:47:59 -0500 Subject: [PATCH 1249/1323] Add Native JStachio support (#567) * Add JStachio support for jex * add it to javalin * helidon * Update ControllerMethodWriter.java --- .../generator/core/BaseControllerWriter.java | 4 +- .../http/generator/core/ControllerReader.java | 25 +++ .../generator/core/JStacheConfigPrism.java | 203 ++++++++++++++++++ .../http/generator/core/JStachePrism.java | 94 ++++++++ .../avaje/http/generator/core/JsonBUtil.java | 4 +- .../generator/core/ProcessingContext.java | 41 +++- .../helidon/nima/ControllerMethodWriter.java | 21 +- .../helidon/nima/ControllerWriter.java | 2 +- .../javalin/ControllerMethodWriter.java | 20 +- .../generator/jex/ControllerMethodWriter.java | 49 +++-- .../web/jstache/JstacheController.java | 77 +++++++ .../src/main/resources/public/openapi.json | 82 +++++++ tests/test-nima-jsonb/pom.xml | 11 + .../example/jstache/JstacheController.java | 77 +++++++ 14 files changed, 680 insertions(+), 30 deletions(-) create mode 100644 http-generator-core/src/main/java/io/avaje/http/generator/core/JStacheConfigPrism.java create mode 100644 http-generator-core/src/main/java/io/avaje/http/generator/core/JStachePrism.java create mode 100644 tests/test-jex/src/main/java/org/example/web/jstache/JstacheController.java create mode 100644 tests/test-nima-jsonb/src/main/java/org/example/jstache/JstacheController.java diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseControllerWriter.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseControllerWriter.java index 7f9053116..25d708af4 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseControllerWriter.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseControllerWriter.java @@ -73,7 +73,9 @@ protected void writeImports() { writer.append("import static %s;", type).eol(); } writer.eol(); - for (String type : reader.importTypes()) { + var importTypes = reader.importTypes(); + importTypes.removeIf(i -> i.substring(0, i.lastIndexOf(".")).equals(packageName)); + for (String type : importTypes) { writer.append("import %s;", type).eol(); } writer.eol(); diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java index 2e5cd9dcd..bc8139b93 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java @@ -59,6 +59,7 @@ public final class ControllerReader { private boolean requestScope; private boolean docHidden; private final boolean hasInstrument; + private boolean hasJstache; public ControllerReader(TypeElement beanType) { this(beanType, ""); @@ -249,6 +250,7 @@ public void read(boolean withSingleton) { } } deriveIncludeValidation(); + jstacheImport(); addImports(withSingleton); } @@ -266,6 +268,25 @@ private boolean anyMethodHasValid() { return false; } + private void jstacheImport() { + for (final MethodReader method : methods) { + final var asTypeElement = APContext.asTypeElement(method.returnType()); + if (ProcessingContext.isJstacheTemplate(method.returnType())) { + if ("JStachio.render".equals(ProcessingContext.jstacheRenderer(method.returnType()))) { + addImportType("io.jstach.jstachio.JStachio"); + } else { + // jstachio generated classes don't have the parent type in the name + addImportType( + APContext.elements().getPackageOf(asTypeElement).getQualifiedName().toString() + + "." + + asTypeElement.getSimpleName() + + "Renderer"); + } + this.hasJstache = true; + } + } + } + private boolean anyMethodHasContentCache() { for (final MethodReader method : methods) { if (method.hasContentCache()) { @@ -383,6 +404,10 @@ public boolean hasInstrument() { return hasInstrument; } + public boolean hasJstache() { + return hasJstache; + } + public static String sanitizeImports(String type) { final int pos = type.indexOf("@"); if (pos == -1) { diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/JStacheConfigPrism.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/JStacheConfigPrism.java new file mode 100644 index 000000000..372b15980 --- /dev/null +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/JStacheConfigPrism.java @@ -0,0 +1,203 @@ +package io.avaje.http.generator.core; + +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; + +import javax.annotation.processing.Generated; +import javax.lang.model.element.AnnotationMirror; +import javax.lang.model.element.AnnotationValue; +import javax.lang.model.element.Element; +import javax.lang.model.element.ExecutableElement; +import javax.lang.model.element.TypeElement; +import javax.lang.model.element.VariableElement; +import javax.lang.model.util.ElementFilter; + +/** A Prism representing a {@link io.jstach.jstache.JStacheConfig @JStacheConfig} annotation. */ +@Generated("avaje-prism-generator") +final class JStacheConfigPrism { + + /** store prism value of type */ + private final String _type; + + public static final String PRISM_TYPE = "io.jstach.jstache.JStacheConfig"; + + /** + * An instance of the Values inner class whose methods return the AnnotationValues used to build + * this prism. Primarily intended to support using Messager. + */ + final Values values; + + /** + * Returns true if the mirror is an instance of {@link + * io.jstach.jstache.JStacheConfig @JStacheConfig} is present on the element, else false. + * + * @param mirror mirror. + * @return true if prism is present. + */ + static boolean isInstance(AnnotationMirror mirror) { + return getInstance(mirror) != null; + } + + /** + * Returns true if {@link io.jstach.jstache.JStacheConfig @JStacheConfig} is present on the + * element, else false. + * + * @param element element. + * @return true if annotation is present on the element. + */ + static boolean isPresent(Element element) { + return getInstanceOn(element) != null; + } + + /** + * Return a prism representing the {@link io.jstach.jstache.JStacheConfig @JStacheConfig} + * annotation present on the given element. similar to {@code + * element.getAnnotation(JStacheConfig.class)} except that an instance of this class rather than + * an instance of {@link io.jstach.jstache.JStacheConfig @JStacheConfig} is returned. + * + * @param element element. + * @return prism on element or null if no annotation is found. + */ + static JStacheConfigPrism getInstanceOn(Element element) { + final var mirror = getMirror(element); + if (mirror == null) return null; + return getInstance(mirror); + } + + /** + * Return a Optional representing a nullable {@link + * io.jstach.jstache.JStacheConfig @JStacheConfig} annotation on the given element. similar to + * {@code element.getAnnotation(io.jstach.jstache.JStacheConfig.class)} except that an Optional of + * this class rather than an instance of {@link io.jstach.jstache.JStacheConfig} is returned. + * + * @param element element. + * @return prism optional for element. + */ + static Optional getOptionalOn(Element element) { + final var mirror = getMirror(element); + if (mirror == null) return Optional.empty(); + return getOptional(mirror); + } + + /** + * Return a prism of the {@link io.jstach.jstache.JStacheConfig @JStacheConfig} annotation from an + * annotation mirror. + * + * @param mirror mirror. + * @return prism for mirror or null if mirror is an incorrect type. + */ + static JStacheConfigPrism getInstance(AnnotationMirror mirror) { + if (mirror == null || !PRISM_TYPE.equals(mirror.getAnnotationType().toString())) return null; + + return new JStacheConfigPrism(mirror); + } + + /** + * Return an Optional representing a nullable {@link JStacheConfigPrism @JStacheConfigPrism} from + * an annotation mirror. similar to {@code e.getAnnotation(io.jstach.jstache.JStacheConfig.class)} + * except that an Optional of this class rather than an instance of {@link + * io.jstach.jstache.JStacheConfig @JStacheConfig} is returned. + * + * @param mirror mirror. + * @return prism optional for mirror. + */ + static Optional getOptional(AnnotationMirror mirror) { + if (mirror == null || !PRISM_TYPE.equals(mirror.getAnnotationType().toString())) + return Optional.empty(); + + return Optional.of(new JStacheConfigPrism(mirror)); + } + + private JStacheConfigPrism(AnnotationMirror mirror) { + for (final ExecutableElement key : mirror.getElementValues().keySet()) { + memberValues.put(key.getSimpleName().toString(), mirror.getElementValues().get(key)); + } + for (final ExecutableElement member : + ElementFilter.methodsIn(mirror.getAnnotationType().asElement().getEnclosedElements())) { + defaults.put(member.getSimpleName().toString(), member.getDefaultValue()); + } + VariableElement typeMirror = getValue("type", VariableElement.class); + valid = valid && typeMirror != null; + _type = typeMirror == null ? null : typeMirror.getSimpleName().toString(); + this.values = new Values(memberValues); + this.mirror = mirror; + this.isValid = valid; + } + + /** + * Returns a String representing the value of the {@code io.jstach.jstache.JStacheType type()} + * member of the Annotation. + * + * @see io.jstach.jstache.JStacheConfig#type() + */ + public String type() { + return _type; + } + + /** + * Determine whether the underlying AnnotationMirror has no errors. True if the underlying + * AnnotationMirror has no errors. When true is returned, none of the methods will return null. + * When false is returned, a least one member will either return null, or another prism that is + * not valid. + */ + final boolean isValid; + + /** + * The underlying AnnotationMirror of the annotation represented by this Prism. Primarily intended + * to support using Messager. + */ + final AnnotationMirror mirror; + + /** + * A class whose members correspond to those of {@link + * io.jstach.jstache.JStacheConfig @JStacheConfig} but which each return the AnnotationValue + * corresponding to that member in the model of the annotations. Returns null for defaulted + * members. Used for Messager, so default values are not useful. + */ + static final class Values { + private final Map values; + + private Values(Map values) { + this.values = values; + } + + AnnotationValue type() { + return values.get("type"); + } + } + + private final Map defaults = new HashMap<>(10); + private final Map memberValues = + new HashMap<>(10); + private boolean valid = true; + + private T getValue(String name, Class clazz) { + final T result = JStacheConfigPrism.getValue(memberValues, defaults, name, clazz); + if (result == null) valid = false; + return result; + } + + private static AnnotationMirror getMirror(Element target) { + for (final var m : target.getAnnotationMirrors()) { + final CharSequence mfqn = + ((TypeElement) m.getAnnotationType().asElement()).getQualifiedName(); + if (PRISM_TYPE.contentEquals(mfqn)) return m; + } + return null; + } + + private static T getValue( + Map memberValues, + Map defaults, + String name, + Class clazz) { + AnnotationValue av = memberValues.get(name); + if (av == null) av = defaults.get(name); + if (av == null) { + return null; + } + if (clazz.isInstance(av.getValue())) return clazz.cast(av.getValue()); + return null; + } +} diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/JStachePrism.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/JStachePrism.java new file mode 100644 index 000000000..d5d5a40cf --- /dev/null +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/JStachePrism.java @@ -0,0 +1,94 @@ +package io.avaje.http.generator.core; + +import javax.annotation.processing.Generated; +import javax.lang.model.element.AnnotationMirror; +import javax.lang.model.element.Element; +import javax.lang.model.element.TypeElement; + +/** A Prism representing a {@link io.jstach.jstache.JStache @JStache} annotation. */ +@Generated("avaje-prism-generator") +public final class JStachePrism { + + public static final String PRISM_TYPE = "io.jstach.jstache.JStache"; + + /** + * Returns true if the mirror is an instance of {@link io.jstach.jstache.JStache @JStache} is + * present on the element, else false. + * + * @param mirror mirror. + * @return true if prism is present. + */ + public static boolean isInstance(AnnotationMirror mirror) { + return getInstance(mirror) != null; + } + + /** + * Returns true if {@link io.jstach.jstache.JStache @JStache} is present on the element, else + * false. + * + * @param element element. + * @return true if annotation is present on the element. + */ + public static boolean isPresent(Element element) { + return getInstanceOn(element) != null; + } + + /** + * Return a prism representing the {@link io.jstach.jstache.JStache @JStache} annotation present + * on the given element. similar to {@code element.getAnnotation(JStache.class)} except that an + * instance of this class rather than an instance of {@link io.jstach.jstache.JStache @JStache} is + * returned. + * + * @param element element. + * @return prism on element or null if no annotation is found. + */ + static JStachePrism getInstanceOn(Element element) { + final var mirror = getMirror(element); + if (mirror == null) return null; + return getInstance(mirror); + } + + /** + * Return a prism of the {@link io.jstach.jstache.JStache @JStache} annotation from an annotation + * mirror. + * + * @param mirror mirror. + * @return prism for mirror or null if mirror is an incorrect type. + */ + static JStachePrism getInstance(AnnotationMirror mirror) { + if (mirror == null || !PRISM_TYPE.equals(mirror.getAnnotationType().toString())) return null; + + return new JStachePrism(mirror); + } + + private JStachePrism(AnnotationMirror mirror) { + + this.mirror = mirror; + this.isValid = valid; + } + + /** + * Determine whether the underlying AnnotationMirror has no errors. True if the underlying + * AnnotationMirror has no errors. When true is returned, none of the methods will return null. + * When false is returned, a least one member will either return null, or another prism that is + * not valid. + */ + final boolean isValid; + + /** + * The underlying AnnotationMirror of the annotation represented by this Prism. Primarily intended + * to support using Messager. + */ + final AnnotationMirror mirror; + + private final boolean valid = true; + + private static AnnotationMirror getMirror(Element target) { + for (final var m : target.getAnnotationMirrors()) { + final CharSequence mfqn = + ((TypeElement) m.getAnnotationType().asElement()).getQualifiedName(); + if (PRISM_TYPE.contentEquals(mfqn)) return m; + } + return null; + } +} diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java index 2a33c04a9..f6c2a5a67 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java @@ -29,9 +29,9 @@ public static Map jsonTypes(ControllerReader reader) { if (!methodReader.isErrorMethod()) { addJsonBodyType(methodReader, addToMap); } - if (!methodReader.isVoid()) { + final var asTypeElement = APContext.asTypeElement(methodReader.returnType()); + if (!methodReader.isVoid() && (asTypeElement == null || !JStachePrism.isPresent(asTypeElement))) { var uType = UType.parse(methodReader.returnType()); - if ("java.util.concurrent.CompletableFuture".equals(uType.mainType())) { uType = uType.paramRaw(); } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java index c865caa14..c3fcbf2ea 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java @@ -3,8 +3,10 @@ import java.io.IOException; import java.net.URI; import java.nio.file.Paths; +import java.util.HashMap; import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Objects; import java.util.Optional; import java.util.Set; @@ -34,6 +36,9 @@ public final class ProcessingContext { private static final ThreadLocal CTX = new ThreadLocal<>(); + private static final boolean ZERO_JSTACHIO = APContext.typeElement("io.jstach.jstachio.JStachio") == null; + private static final Map jstacheRenderers = new HashMap<>(); + private ProcessingContext() {} private static final class Ctx { @@ -142,7 +147,6 @@ public static JavaFileObject createWriter(String cls, Element origin) throws IOE /** Create a file writer for the META-INF services file. */ public static FileObject createMetaInfWriter(String target) throws IOException { - return filer().createResource(StandardLocation.CLASS_OUTPUT, "", target); } @@ -287,4 +291,39 @@ private static boolean resourceExists(String relativeName) { public static void addClientComponent(String clientFQN) { CTX.get().clientFQN.add(clientFQN); } + + public static String jstacheRenderer(TypeMirror typeMirror) { + final var typeElement = APContext.asTypeElement(typeMirror); + final var typeName = typeElement.getSimpleName().toString(); + return jstacheRenderers.computeIfAbsent(typeName, k -> determineJstacheRenderer(typeElement)); + } + + private static String determineJstacheRenderer(TypeElement typeElement) { + return ZERO_JSTACHIO + ? jstacheTypeRenderer(typeElement) + : checkJstacheConfig(typeElement, typeElement); + } + + private static String checkJstacheConfig(Element element, TypeElement typeElement) { + if (element == null) { + return "JStachio.render"; + } + var config = JStacheConfigPrism.getInstanceOn(element); + if (config != null && "STACHE".equals(config.type())) { + return jstacheTypeRenderer(typeElement); + } else if (config != null && "JSTACHIO".equals(config.type())) { + return "JStachio.render"; + } + + return checkJstacheConfig(element.getEnclosingElement(), typeElement); + } + + private static String jstacheTypeRenderer(TypeElement typeElement) { + return typeElement.getSimpleName() + "Renderer.of().execute"; + } + + public static boolean isJstacheTemplate(TypeMirror mirror) { + final var typeElement = APContext.asTypeElement(mirror); + return typeElement != null && JStachePrism.isPresent(typeElement); + } } diff --git a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java index 993ea6c64..a89aa596a 100644 --- a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java +++ b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java @@ -61,13 +61,15 @@ final class ControllerMethodWriter { private final boolean instrumentContext; private final boolean isFilter; private final ControllerReader reader; + private final boolean useJstachio; ControllerMethodWriter(MethodReader method, Append writer, boolean useJsonB, ControllerReader reader) { this.reader = reader; this.method = method; this.writer = writer; this.webMethod = method.webMethod(); - this.useJsonB = useJsonB; + this.useJstachio = ProcessingContext.isJstacheTemplate(method.returnType()); + this.useJsonB = !useJstachio && useJsonB; this.instrumentContext = method.instrumentContext(); this.isFilter = webMethod == CoreWebMethod.FILTER; if (isFilter) { @@ -246,6 +248,12 @@ void writeHandler(boolean requestScoped) { writeContextReturn(indent); writer.append(indent).append("res.send(content);").eol(); + } else if (responseMode == ResponseMode.Jstachio) { + var renderer = ProcessingContext.jstacheRenderer(method.returnType()); + writer.append(indent).append("var content = %s(result);", renderer).eol(); + writeContextReturn(indent); + writer.append(indent).append("res.send(content);").eol(); + } else { writeContextReturn(indent); if (responseMode == ResponseMode.InputStream) { @@ -272,6 +280,7 @@ void writeHandler(boolean requestScoped) { enum ResponseMode { Void, Json, + Jstachio, Templating, InputStream, Other @@ -290,6 +299,9 @@ ResponseMode responseMode() { if (useTemplating()) { return ResponseMode.Templating; } + if (useJstachio) { + return ResponseMode.Jstachio; + } return ResponseMode.Other; } @@ -361,10 +373,13 @@ private boolean usesFormParams() { private void writeContextReturn(String indent) { final var producesOp = Optional.ofNullable(method.produces()); - if (producesOp.isEmpty() && !useJsonB) { + if (producesOp.isEmpty() && !useJsonB && !useJstachio) { return; } - final var produces = producesOp.map(MediaType::parse).orElse(MediaType.APPLICATION_JSON); + final var produces = + producesOp + .map(MediaType::parse) + .orElse(useJstachio ? MediaType.HTML_UTF8 : MediaType.APPLICATION_JSON); final var contentTypeString = "res.headers().contentType(MediaTypes."; writer.append(indent); switch (produces) { diff --git a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java index 4e5d61bd8..3c8d2c726 100644 --- a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java +++ b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java @@ -137,7 +137,7 @@ private void writeClassStart() { if (reader.isIncludeValidator()) { writer.append(" private static final HeaderName HEADER_ACCEPT_LANGUAGE = HeaderNames.create(\"Accept-Language\");").eol(); } - if (reader.html()) { + if (reader.html() || reader.hasJstache()) { writer.append(" private static final io.helidon.common.media.type.MediaType HTML_UTF8 = MediaTypes.create(\"text/html;charset=UTF8\");").eol(); } diff --git a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java index 799d67763..00336283e 100644 --- a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java +++ b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerMethodWriter.java @@ -16,13 +16,15 @@ class ControllerMethodWriter { private final boolean useJsonB; private final boolean instrumentContext; private final boolean customMethod; + private final boolean useJstachio; ControllerMethodWriter(MethodReader method, Append writer, boolean useJsonB) { this.method = method; this.writer = writer; final var webM = method.webMethod(); this.webMethod = webM == CoreWebMethod.FILTER ? JavalinWebMethod.BEFORE : webM; - this.useJsonB = useJsonB && !disabledDirectWrites(); + this.useJstachio = ProcessingContext.isJstacheTemplate(method.returnType()); + this.useJsonB = !useJstachio && useJsonB && !disabledDirectWrites(); this.instrumentContext = method.instrumentContext(); customMethod = !(webMethod instanceof CoreWebMethod); } @@ -152,6 +154,11 @@ private void writeContextReturn() { private void writeContextReturn(final String resultVariableName) { var produces = method.produces(); + + if (useJstachio && produces == null) { + produces = MediaType.TEXT_HTML.getValue(); + } + boolean applicationJson = produces == null || MediaType.APPLICATION_JSON.getValue().equalsIgnoreCase(produces); if (applicationJson || JsonBUtil.isJsonMimeType(produces)) { if (useJsonB) { @@ -170,13 +177,14 @@ private void writeContextReturn(final String resultVariableName) { if (isfuture || method.isErrorMethod()) { writer.append(" } catch (java.io.IOException e) { throw new java.io.UncheckedIOException(e); }"); } + } else if (applicationJson) { + writer.append(" ctx.json(%s);", resultVariableName); } else { - if (applicationJson) { - writer.append(" ctx.json(%s);", resultVariableName); - } else { - writer.append(" ctx.contentType(\"%s\").json(%s);", produces, resultVariableName); - } + writer.append(" ctx.contentType(\"%s\").json(%s);", produces, resultVariableName); } + } else if (useJstachio) { + var renderer = ProcessingContext.jstacheRenderer(method.returnType()); + writer.append(" ctx.contentType(\"%s\").result(%s(%s));", produces, renderer, resultVariableName); } else if (MediaType.TEXT_HTML.getValue().equalsIgnoreCase(produces)) { writer.append(" ctx.html(%s);", resultVariableName); } else if (MediaType.TEXT_PLAIN.getValue().equalsIgnoreCase(produces)) { diff --git a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java index bdff607aa..60557b0c3 100644 --- a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java +++ b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java @@ -9,16 +9,14 @@ import static io.avaje.http.generator.core.ProcessingContext.*; -/** - * Write code to register Web route for a given controller method. - */ +/** Write code to register Web route for a given controller method. */ class ControllerMethodWriter { - private final MethodReader method; private final Append writer; private final ControllerReader reader; private final WebMethod webMethod; private final boolean useJsonB; + private final boolean useJstachio; private final boolean instrumentContext; private final boolean isFilter; @@ -27,7 +25,8 @@ class ControllerMethodWriter { this.method = method; this.writer = writer; this.reader = reader; - this.useJsonB = useJsonB; + this.useJstachio = ProcessingContext.isJstacheTemplate(method.returnType()); + this.useJsonB = !useJstachio && useJsonB; this.webMethod = method.webMethod(); this.instrumentContext = method.instrumentContext(); this.isFilter = webMethod == CoreWebMethod.FILTER; @@ -102,6 +101,7 @@ enum ResponseMode { Void, Json, Text, + Jstachio, Templating, InputStream, Other @@ -120,6 +120,9 @@ ResponseMode responseMode() { if (useTemplating()) { return ResponseMode.Templating; } + if (useJstachio) { + return ResponseMode.Jstachio; + } if (producesText()) { return ResponseMode.Text; } @@ -132,11 +135,12 @@ private boolean isInputStream(TypeMirror type) { private boolean producesJson() { return !"byte[]".equals(method.returnType().toString()) + && !useJstachio && (method.produces() == null || method.produces().toLowerCase().contains("json")); } private boolean producesText() { - return (method.produces() != null && method.produces().toLowerCase().contains("text")); + return (method.produces() != null && method.produces().toLowerCase().contains("text")); } private boolean useContentCache() { @@ -245,16 +249,25 @@ private void write(boolean requestScoped) { if (includeNoContent) { writer.append(" if (result != null) {").eol(); } - if (responseMode == ResponseMode.Templating) { - writer.append(indent).append("var content = renderer.render(result);").eol(); - if (withContentCache) { - writer.append(indent).append("contentCache.contentPut(key, content);").eol(); + switch (responseMode) { + case Templating -> { + writer.append(indent).append("var content = renderer.render(result);").eol(); + if (withContentCache) { + writer.append(indent).append("contentCache.contentPut(key, content);").eol(); + } + writer.append(indent); + writeContextReturn(responseMode, "content"); + } + case Jstachio -> { + var renderer = ProcessingContext.jstacheRenderer(method.returnType()); + writer.append(indent).append("var content = %s(result);", renderer).eol(); + writer.append(indent); + writeContextReturn(responseMode, "content"); + } + default -> { + writer.append(indent); + writeContextReturn(responseMode, "result"); } - writer.append(indent); - writeContextReturn(responseMode, "content"); - } else { - writer.append(indent); - writeContextReturn(responseMode, "result"); } if (includeNoContent) { writer.append(" }").eol(); @@ -270,7 +283,11 @@ private void writeContextReturn(ResponseMode responseMode, String resultVariable return; } - final var produces = method.produces(); + var produces = method.produces(); + if (produces == null && useJstachio) { + writer.append("ctx.html(%s);", resultVariable).eol(); + return; + } switch (responseMode) { case Void -> {} case Json -> writeJsonReturn(produces); diff --git a/tests/test-jex/src/main/java/org/example/web/jstache/JstacheController.java b/tests/test-jex/src/main/java/org/example/web/jstache/JstacheController.java new file mode 100644 index 000000000..47b32e959 --- /dev/null +++ b/tests/test-jex/src/main/java/org/example/web/jstache/JstacheController.java @@ -0,0 +1,77 @@ +package org.example.web.jstache; + +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; +import java.time.temporal.ChronoUnit; +import java.util.List; + +import io.avaje.http.api.Controller; +import io.avaje.http.api.Get; +import io.jstach.jstache.JStache; +import io.jstach.jstache.JStacheConfig; +import io.jstach.jstache.JStacheLambda; +import io.jstach.jstache.JStacheType; + +@Controller("/jstache") +public class JstacheController { + + @Get("/hello") + public HelloWorldZeroDependency hello() { + Person rick = new Person("Rick", LocalDate.now().minusYears(70)); + Person morty = new Person("Morty", LocalDate.now().minusYears(14)); + Person beth = new Person("Beth", LocalDate.now().minusYears(35)); + Person jerry = new Person("Jerry", LocalDate.now().minusYears(35)); + return new HelloWorldZeroDependency("Hello alien", List.of(rick, morty, beth, jerry)); + } + + @Get("/helloRuntime") + public HelloWorld helloRuntime() { + Person rick = new Person("Rick", LocalDate.now().minusYears(70)); + Person morty = new Person("Morty", LocalDate.now().minusYears(14)); + Person beth = new Person("Beth", LocalDate.now().minusYears(35)); + Person jerry = new Person("Jerry", LocalDate.now().minusYears(35)); + return new HelloWorld("Hello alien", List.of(rick, morty, beth, jerry)); + } + + /* + * Annotate the root model with an inline mustache template + */ + @JStacheConfig(type = JStacheType.STACHE) + @JStache( + template = + """ + {{#people}} + {{message}} {{name}}! You are {{#ageInfo}}{{age}}{{/ageInfo}} years old! + {{#-last}} + That is all for now! + {{/-last}} + {{/people}} + """) + public record HelloWorldZeroDependency(String message, List people) implements AgeLambdaSupport {} + + public record Person(String name, LocalDate birthday) {} + + public record AgeInfo(long age, String date) {} + + public interface AgeLambdaSupport { + @JStacheLambda + default AgeInfo ageInfo(Person person) { + long age = ChronoUnit.YEARS.between(person.birthday(), LocalDate.now()); + String date = person.birthday().format(DateTimeFormatter.ISO_DATE); + return new AgeInfo(age, date); + } + } + + @JStache( + template = + """ + {{#people}} + {{message}} {{name}}! You are {{#ageInfo}}{{age}}{{/ageInfo}} years old! + {{#-last}} + That is all for now! + {{/-last}} + {{/people}} + """) + public record HelloWorld(String message, List people) implements AgeLambdaSupport {} + +} diff --git a/tests/test-jex/src/main/resources/public/openapi.json b/tests/test-jex/src/main/resources/public/openapi.json index e4b99b6d6..e31f0de26 100644 --- a/tests/test-jex/src/main/resources/public/openapi.json +++ b/tests/test-jex/src/main/resources/public/openapi.json @@ -1023,6 +1023,48 @@ "deprecated" : true } }, + "/jstache/hello" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/HelloWorldZeroDependency" + } + } + } + } + } + } + }, + "/jstache/helloRuntime" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/HelloWorld" + } + } + } + } + } + } + }, "/other/{name}" : { "get" : { "tags" : [ @@ -1516,6 +1558,34 @@ } } }, + "HelloWorld" : { + "type" : "object", + "properties" : { + "message" : { + "type" : "string" + }, + "people" : { + "type" : "array", + "items" : { + "$ref" : "#/components/schemas/Person" + } + } + } + }, + "HelloWorldZeroDependency" : { + "type" : "object", + "properties" : { + "message" : { + "type" : "string" + }, + "people" : { + "type" : "array", + "items" : { + "$ref" : "#/components/schemas/Person" + } + } + } + }, "Long>" : { "type" : "object", "properties" : { @@ -1532,6 +1602,18 @@ } } }, + "Person" : { + "type" : "object", + "properties" : { + "name" : { + "type" : "string" + }, + "birthday" : { + "type" : "string", + "format" : "date" + } + } + }, "String>" : { "type" : "object", "properties" : { diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 8154fa6cd..2cd8cdb04 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -49,6 +49,12 @@ ${project.version} + + io.jstach + jstachio + 1.3.6 + + io.avaje junit @@ -92,6 +98,11 @@ avaje-validator-generator 2.7 + + io.jstach + jstachio-apt + 1.3.6 + diff --git a/tests/test-nima-jsonb/src/main/java/org/example/jstache/JstacheController.java b/tests/test-nima-jsonb/src/main/java/org/example/jstache/JstacheController.java new file mode 100644 index 000000000..43817e411 --- /dev/null +++ b/tests/test-nima-jsonb/src/main/java/org/example/jstache/JstacheController.java @@ -0,0 +1,77 @@ +package org.example.jstache; + +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; +import java.time.temporal.ChronoUnit; +import java.util.List; + +import io.avaje.http.api.Controller; +import io.avaje.http.api.Get; +import io.jstach.jstache.JStache; +import io.jstach.jstache.JStacheConfig; +import io.jstach.jstache.JStacheLambda; +import io.jstach.jstache.JStacheType; + +@Controller("/jstache") +public class JstacheController { + + @Get("/hello") + public HelloWorldZeroDependency hello() { + Person rick = new Person("Rick", LocalDate.now().minusYears(70)); + Person morty = new Person("Morty", LocalDate.now().minusYears(14)); + Person beth = new Person("Beth", LocalDate.now().minusYears(35)); + Person jerry = new Person("Jerry", LocalDate.now().minusYears(35)); + return new HelloWorldZeroDependency("Hello alien", List.of(rick, morty, beth, jerry)); + } + + @Get("/helloRuntime") + public HelloWorld helloRuntime() { + Person rick = new Person("Rick", LocalDate.now().minusYears(70)); + Person morty = new Person("Morty", LocalDate.now().minusYears(14)); + Person beth = new Person("Beth", LocalDate.now().minusYears(35)); + Person jerry = new Person("Jerry", LocalDate.now().minusYears(35)); + return new HelloWorld("Hello alien", List.of(rick, morty, beth, jerry)); + } + + /* + * Annotate the root model with an inline mustache template + */ + @JStacheConfig(type = JStacheType.STACHE) + @JStache( + template = + """ + {{#people}} + {{message}} {{name}}! You are {{#ageInfo}}{{age}}{{/ageInfo}} years old! + {{#-last}} + That is all for now! + {{/-last}} + {{/people}} + """) + public record HelloWorldZeroDependency(String message, List people) implements AgeLambdaSupport {} + + public record Person(String name, LocalDate birthday) {} + + public record AgeInfo(long age, String date) {} + + public interface AgeLambdaSupport { + @JStacheLambda + default AgeInfo ageInfo(Person person) { + long age = ChronoUnit.YEARS.between(person.birthday(), LocalDate.now()); + String date = person.birthday().format(DateTimeFormatter.ISO_DATE); + return new AgeInfo(age, date); + } + } + + @JStache( + template = + """ + {{#people}} + {{message}} {{name}}! You are {{#ageInfo}}{{age}}{{/ageInfo}} years old! + {{#-last}} + That is all for now! + {{/-last}} + {{/people}} + """) + public record HelloWorld(String message, List people) implements AgeLambdaSupport {} + +} From 23e05b9d4e12561165675444da4558ec362281d0 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Thu, 20 Feb 2025 04:21:57 -0500 Subject: [PATCH 1250/1323] use optimized jex jsonb (#568) requires another jex RC Co-authored-by: Rob Bygrave --- .../generator/jex/ControllerMethodWriter.java | 4 +--- tests/pom.xml | 2 +- .../src/main/resources/public/openapi.json | 22 ++----------------- 3 files changed, 4 insertions(+), 24 deletions(-) diff --git a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java index 60557b0c3..c3244def0 100644 --- a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java +++ b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java @@ -308,9 +308,7 @@ private void writeJsonReturn(String produces) { return; } if (useJsonB) { - writer.append( - "%sJsonType.toJson(result, ctx.contentType(\"%s\").outputStream());", - uType.shortName(), produces); + writer.append("ctx.jsonb(%sJsonType, result);", uType.shortName()); } else { writer.append("ctx.json(result);"); } diff --git a/tests/pom.xml b/tests/pom.xml index 6be019994..60b9ae458 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -15,7 +15,7 @@ 5.11.4 3.27.3 2.18.2 - 3.0-RC18 + 3.0-RC20 11.2 4.1.6 6.4.0 diff --git a/tests/test-jex/src/main/resources/public/openapi.json b/tests/test-jex/src/main/resources/public/openapi.json index e31f0de26..6ce043677 100644 --- a/tests/test-jex/src/main/resources/public/openapi.json +++ b/tests/test-jex/src/main/resources/public/openapi.json @@ -1587,20 +1587,10 @@ } }, "Long>" : { - "type" : "object", - "properties" : { - "value" : { - "$ref" : "#/components/schemas/T" - } - } + "type" : "object" }, "NestedEnum>" : { - "type" : "object", - "properties" : { - "value" : { - "$ref" : "#/components/schemas/T" - } - } + "type" : "object" }, "Person" : { "type" : "object", @@ -1615,14 +1605,6 @@ } }, "String>" : { - "type" : "object", - "properties" : { - "value" : { - "$ref" : "#/components/schemas/T" - } - } - }, - "T" : { "type" : "object" }, "ViewHome" : { From 9797d6c82c49339472bc7937ba0e9bfab30dd623 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Fri, 21 Feb 2025 23:08:43 +1300 Subject: [PATCH 1251/1323] Version 3.1-RC1 --- aws-cognito/http-client-authtoken/pom.xml | 2 +- htmx-api/pom.xml | 2 +- htmx-nima-jstache/pom.xml | 2 +- htmx-nima/pom.xml | 4 ++-- http-api-javalin/pom.xml | 2 +- http-api/pom.xml | 2 +- http-client-gson-adapter/pom.xml | 4 ++-- http-client-moshi-adapter/pom.xml | 4 ++-- http-client/pom.xml | 2 +- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 2 +- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-generator-sigma/pom.xml | 2 +- http-inject-plugin/pom.xml | 2 +- pom.xml | 4 ++-- tests/pom.xml | 2 +- tests/test-client-generation/pom.xml | 2 +- tests/test-client/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-htmx/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- tests/test-sigma/pom.xml | 2 +- 27 files changed, 31 insertions(+), 31 deletions(-) diff --git a/aws-cognito/http-client-authtoken/pom.xml b/aws-cognito/http-client-authtoken/pom.xml index bb288726d..73c8efb8e 100644 --- a/aws-cognito/http-client-authtoken/pom.xml +++ b/aws-cognito/http-client-authtoken/pom.xml @@ -17,7 +17,7 @@ io.avaje avaje-http-client - 3.0 + 3.1-RC1 diff --git a/htmx-api/pom.xml b/htmx-api/pom.xml index 0692c6e91..3e45f30a9 100644 --- a/htmx-api/pom.xml +++ b/htmx-api/pom.xml @@ -6,7 +6,7 @@ io.avaje avaje-http-parent - 3.0 + 3.1-RC1 avaje-htmx-api diff --git a/htmx-nima-jstache/pom.xml b/htmx-nima-jstache/pom.xml index 76a642715..eb0a5b28b 100644 --- a/htmx-nima-jstache/pom.xml +++ b/htmx-nima-jstache/pom.xml @@ -6,7 +6,7 @@ io.avaje avaje-http-parent - 3.0 + 3.1-RC1 avaje-htmx-nima-jstache diff --git a/htmx-nima/pom.xml b/htmx-nima/pom.xml index 547162a13..02a04e28f 100644 --- a/htmx-nima/pom.xml +++ b/htmx-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje avaje-http-parent - 3.0 + 3.1-RC1 avaje-htmx-nima @@ -21,7 +21,7 @@ io.avaje avaje-htmx-api - 3.0 + 3.1-RC1 io.helidon.webserver diff --git a/http-api-javalin/pom.xml b/http-api-javalin/pom.xml index 0863ee7a3..628df333b 100644 --- a/http-api-javalin/pom.xml +++ b/http-api-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.0 + 3.1-RC1 .. diff --git a/http-api/pom.xml b/http-api/pom.xml index 7754ff9df..36e7a9f08 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.0 + 3.1-RC1 .. diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index 9e71b8088..029359735 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.0 + 3.1-RC1 avaje-http-client-gson @@ -20,7 +20,7 @@ io.avaje avaje-http-client - 3.0 + 3.1-RC1 provided diff --git a/http-client-moshi-adapter/pom.xml b/http-client-moshi-adapter/pom.xml index 956cd96fa..38def5854 100644 --- a/http-client-moshi-adapter/pom.xml +++ b/http-client-moshi-adapter/pom.xml @@ -3,7 +3,7 @@ io.avaje avaje-http-parent - 3.0 + 3.1-RC1 avaje-http-client-moshi @@ -19,7 +19,7 @@ io.avaje avaje-http-client - 3.0 + 3.1-RC1 provided diff --git a/http-client/pom.xml b/http-client/pom.xml index 5eb547f6d..4c64e7cc7 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.0 + 3.1-RC1 avaje-http-client diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index 78fe5f976..a49b2e364 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.0 + 3.1-RC1 avaje-http-client-generator diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 3294d9125..f47053a3d 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.0 + 3.1-RC1 avaje-http-generator-core diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index 54aa6753b..15d3dedc2 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 3.0 + 3.1-RC1 avaje-http-helidon-generator diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index faaa1af9e..a3fdb2e9d 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.0 + 3.1-RC1 avaje-http-javalin-generator diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index d765f58c3..c7e3e85bc 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.0 + 3.1-RC1 avaje-http-jex-generator diff --git a/http-generator-sigma/pom.xml b/http-generator-sigma/pom.xml index a63121afd..b5fe27b02 100644 --- a/http-generator-sigma/pom.xml +++ b/http-generator-sigma/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.0 + 3.1-RC1 avaje-http-sigma-generator diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index b7d661e41..c9c7e5443 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.0 + 3.1-RC1 .. diff --git a/pom.xml b/pom.xml index e9d5c9deb..cd3ac482c 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-parent - 3.0 + 3.1-RC1 pom @@ -23,7 +23,7 @@ 2.14.2 3.0-RC10 1.38 - 2025-02-10T08:40:37Z + 2025-02-21T09:57:12Z ${project.build.directory}${file.separator}module-info.shade diff --git a/tests/pom.xml b/tests/pom.xml index 60b9ae458..a25c3cda7 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 3.0 + 3.1-RC1 tests diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index d13ec4659..f9193c4ce 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 3.0 + 3.1-RC1 test-client-generation diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index 3497b45b8..feccf53c4 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 3.0 + 3.1-RC1 test-client diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 23a24c337..ec62dc6e8 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 3.0 + 3.1-RC1 test-javalin-jsonb diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 99ab6d110..3700eda0e 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 3.0 + 3.1-RC1 test-javalin diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 74d429955..7caceb7f9 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 3.0 + 3.1-RC1 test-jex diff --git a/tests/test-nima-htmx/pom.xml b/tests/test-nima-htmx/pom.xml index 4971eeeb5..8390d0f5d 100644 --- a/tests/test-nima-htmx/pom.xml +++ b/tests/test-nima-htmx/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 3.0 + 3.1-RC1 test-nima-htmx diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 2cd8cdb04..d7bad8492 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 3.0 + 3.1-RC1 test-nima-jsonb diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index 4eefbe5fe..ee2ef13c5 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 3.0 + 3.1-RC1 test-nima diff --git a/tests/test-sigma/pom.xml b/tests/test-sigma/pom.xml index 37bfac092..9c8caa1b9 100644 --- a/tests/test-sigma/pom.xml +++ b/tests/test-sigma/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 3.0 + 3.1-RC1 test-sigma From f4ed525bba08a3482a7872ff79b3d00984395b1a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 24 Feb 2025 20:07:01 +0000 Subject: [PATCH 1252/1323] Bump the dependencies group with 8 updates Bumps the dependencies group with 8 updates: | Package | From | To | | --- | --- | --- | | [org.apache.maven.plugins:maven-compiler-plugin](https://github.com/apache/maven-compiler-plugin) | `3.13.0` | `3.14.0` | | io.avaje:avaje-spi-service | `2.9` | `2.10` | | [io.avaje:avaje-prisms](https://github.com/avaje/avaje-prisms) | `1.38` | `1.39` | | [io.avaje:avaje-validator](https://github.com/avaje/avaje-validator) | `2.7` | `2.8` | | io.avaje:avaje-validator-constraints | `2.7` | `2.8` | | io.avaje:avaje-validator-generator | `2.7` | `2.8` | | [org.junit.jupiter:junit-jupiter-api](https://github.com/junit-team/junit5) | `5.11.4` | `5.12.0` | | [org.junit.jupiter:junit-jupiter-engine](https://github.com/junit-team/junit5) | `5.11.4` | `5.12.0` | Updates `org.apache.maven.plugins:maven-compiler-plugin` from 3.13.0 to 3.14.0 - [Release notes](https://github.com/apache/maven-compiler-plugin/releases) - [Commits](https://github.com/apache/maven-compiler-plugin/compare/maven-compiler-plugin-3.13.0...maven-compiler-plugin-3.14.0) Updates `io.avaje:avaje-spi-service` from 2.9 to 2.10 Updates `io.avaje:avaje-prisms` from 1.38 to 1.39 - [Release notes](https://github.com/avaje/avaje-prisms/releases) - [Commits](https://github.com/avaje/avaje-prisms/compare/1.38...1.39) Updates `io.avaje:avaje-validator` from 2.7 to 2.8 - [Release notes](https://github.com/avaje/avaje-validator/releases) - [Commits](https://github.com/avaje/avaje-validator/compare/2.7...2.8) Updates `io.avaje:avaje-validator-constraints` from 2.7 to 2.8 Updates `io.avaje:avaje-validator-generator` from 2.7 to 2.8 Updates `org.junit.jupiter:junit-jupiter-api` from 5.11.4 to 5.12.0 - [Release notes](https://github.com/junit-team/junit5/releases) - [Commits](https://github.com/junit-team/junit5/compare/r5.11.4...r5.12.0) Updates `org.junit.jupiter:junit-jupiter-engine` from 5.11.4 to 5.12.0 - [Release notes](https://github.com/junit-team/junit5/releases) - [Commits](https://github.com/junit-team/junit5/compare/r5.11.4...r5.12.0) Updates `org.junit.jupiter:junit-jupiter-engine` from 5.11.4 to 5.12.0 - [Release notes](https://github.com/junit-team/junit5/releases) - [Commits](https://github.com/junit-team/junit5/compare/r5.11.4...r5.12.0) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-compiler-plugin dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.avaje:avaje-spi-service dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.avaje:avaje-prisms dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.avaje:avaje-validator dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.avaje:avaje-validator-constraints dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.avaje:avaje-validator-generator dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: org.junit.jupiter:junit-jupiter-api dependency-type: direct:development update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: org.junit.jupiter:junit-jupiter-engine dependency-type: direct:development update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: org.junit.jupiter:junit-jupiter-engine dependency-type: direct:development update-type: version-update:semver-minor dependency-group: dependencies ... Signed-off-by: dependabot[bot] --- htmx-nima-jstache/pom.xml | 2 +- http-client/pom.xml | 2 +- http-inject-plugin/pom.xml | 2 +- pom.xml | 2 +- tests/pom.xml | 8 ++++---- tests/test-client-generation/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-nima-htmx/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- 10 files changed, 13 insertions(+), 13 deletions(-) diff --git a/htmx-nima-jstache/pom.xml b/htmx-nima-jstache/pom.xml index eb0a5b28b..94f98e5ed 100644 --- a/htmx-nima-jstache/pom.xml +++ b/htmx-nima-jstache/pom.xml @@ -46,7 +46,7 @@ io.avaje avaje-spi-service - 2.9 + 2.10 provided true diff --git a/http-client/pom.xml b/http-client/pom.xml index 4c64e7cc7..143635023 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -97,7 +97,7 @@ org.apache.maven.plugins maven-compiler-plugin - 3.13.0 + 3.14.0 default-testCompile diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index c9c7e5443..686769827 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -33,7 +33,7 @@ io.avaje avaje-spi-service - 2.9 + 2.10 provided true diff --git a/pom.xml b/pom.xml index cd3ac482c..f09ddfa3d 100644 --- a/pom.xml +++ b/pom.xml @@ -22,7 +22,7 @@ 2.2.28 2.14.2 3.0-RC10 - 1.38 + 1.39 2025-02-21T09:57:12Z ${project.build.directory}${file.separator}module-info.shade diff --git a/tests/pom.xml b/tests/pom.xml index a25c3cda7..683c03d4d 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -12,7 +12,7 @@ true - 5.11.4 + 5.12.0 3.27.3 2.18.2 3.0-RC20 @@ -48,19 +48,19 @@ io.avaje avaje-validator - 2.7 + 2.8 io.avaje avaje-validator-constraints - 2.7 + 2.8 io.avaje avaje-validator-generator - 2.7 + 2.8 diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index f9193c4ce..9fe9b2ce8 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -116,7 +116,7 @@ org.apache.maven.plugins maven-compiler-plugin - 3.13.0 + 3.14.0 diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 3700eda0e..1dc23914b 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -57,7 +57,7 @@ io.avaje avaje-validator - 2.7 + 2.8 diff --git a/tests/test-nima-htmx/pom.xml b/tests/test-nima-htmx/pom.xml index 8390d0f5d..92ef45cc6 100644 --- a/tests/test-nima-htmx/pom.xml +++ b/tests/test-nima-htmx/pom.xml @@ -71,7 +71,7 @@ org.apache.maven.plugins maven-compiler-plugin - 3.13.0 + 3.14.0 21 diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index d7bad8492..d2616b48c 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -96,7 +96,7 @@ io.avaje avaje-validator-generator - 2.7 + 2.8 io.jstach diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index ee2ef13c5..dfe88e0e9 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -56,7 +56,7 @@ org.apache.maven.plugins maven-compiler-plugin - 3.13.0 + 3.14.0 21 From 12f5079c5cc97bb159a8d76b4c314f9e58eaa2cb Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Mon, 24 Feb 2025 21:21:15 -0800 Subject: [PATCH 1253/1323] Merge pull request #569 from SentryMan/jsonb-template [generators] Remove jsonb generation if no jsontypes available --- .../avaje/http/generator/core/JsonBUtil.java | 39 ++++++++++++++++++- .../helidon/nima/ControllerWriter.java | 13 ++----- .../generator/javalin/ControllerWriter.java | 14 ++----- .../http/generator/jex/ControllerWriter.java | 13 ++----- 4 files changed, 48 insertions(+), 31 deletions(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java index f6c2a5a67..cf40c9076 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java @@ -7,14 +7,51 @@ public final class JsonBUtil { + private static final JsonBDetect NO_JSONB = new JsonBDetect(); + /** + * Detect JsonB use and handle imports as needed. + */ + public static final class JsonBDetect { + private final Map jsonTypes; + + private JsonBDetect() { + this.jsonTypes = Map.of(); + } + + private JsonBDetect(ControllerReader reader) { + this.jsonTypes = JsonBUtil.jsonTypes(reader); + addImports(reader); + } + + private void addImports(ControllerReader reader) { + if (useJsonB()) { + reader.addImportType("io.avaje.jsonb.Jsonb"); + reader.addImportType("io.avaje.jsonb.JsonType"); + reader.addImportType("io.avaje.jsonb.Types"); + jsonTypes.values().stream().map(UType::importTypes).forEach(reader::addImportTypes); + } + } + + public boolean useJsonB() { + return !jsonTypes.isEmpty(); + } + + public Map jsonTypes() { + return jsonTypes; + } + } + private JsonBUtil() {} public static boolean isJsonMimeType(String producesMimeType) { return producesMimeType == null || producesMimeType.toLowerCase().contains("application/json"); } - public static Map jsonTypes(ControllerReader reader) { + public static JsonBDetect detect(boolean jsonb, ControllerReader reader) { + return !jsonb ? NO_JSONB : new JsonBDetect(reader); + } + public static Map jsonTypes(ControllerReader reader) { final Map jsonTypes = new LinkedHashMap<>(); final Consumer addToMap = uType -> jsonTypes.put(uType.full(), uType); diff --git a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java index 3c8d2c726..e47da1301 100644 --- a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java +++ b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java @@ -26,18 +26,11 @@ class ControllerWriter extends BaseControllerWriter { ControllerWriter(ControllerReader reader, boolean jsonb) throws IOException { super(reader); - this.useJsonB = jsonb; + final var detectJsonB = JsonBUtil.detect(jsonb, reader); + this.useJsonB = detectJsonB.useJsonB(); + this.jsonTypes = detectJsonB.jsonTypes(); if (useJsonB) { - reader.addImportType("io.avaje.jsonb.Jsonb"); - reader.addImportType("io.avaje.jsonb.JsonType"); - reader.addImportType("io.avaje.jsonb.Types"); reader.addImportType(jsonOutputType()); - this.jsonTypes = JsonBUtil.jsonTypes(reader); - jsonTypes.values().stream() - .map(UType::importTypes) - .forEach(reader::addImportTypes); - } else { - this.jsonTypes = Map.of(); } reader.addImportType("io.helidon.common.media.type.MediaTypes"); reader.addImportType("io.helidon.common.parameters.Parameters"); diff --git a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java index 340b702e0..c9a7f1324 100644 --- a/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java +++ b/http-generator-javalin/src/main/java/io/avaje/http/generator/javalin/ControllerWriter.java @@ -26,16 +26,10 @@ class ControllerWriter extends BaseControllerWriter { ControllerWriter(ControllerReader reader, boolean jsonb) throws IOException { super(reader); - this.useJsonB = jsonb; - if (useJsonB) { - reader.addImportType("io.avaje.jsonb.Jsonb"); - reader.addImportType("io.avaje.jsonb.JsonType"); - reader.addImportType("io.avaje.jsonb.Types"); - this.jsonTypes = JsonBUtil.jsonTypes(reader); - jsonTypes.values().stream().map(UType::importTypes).forEach(reader::addImportTypes); - } else { - this.jsonTypes = Map.of(); - } + final var detectJsonB = JsonBUtil.detect(jsonb, reader); + this.useJsonB = detectJsonB.useJsonB(); + this.jsonTypes = detectJsonB.jsonTypes(); + reader.addImportType("io.javalin.plugin.Plugin"); if (javalin6) { reader.addImportType("io.javalin.config.JavalinConfig"); diff --git a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerWriter.java b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerWriter.java index da470c8b4..0138d8f9b 100644 --- a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerWriter.java +++ b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerWriter.java @@ -20,7 +20,9 @@ class ControllerWriter extends BaseControllerWriter { ControllerWriter(ControllerReader reader, boolean jsonb) throws IOException { super(reader); - this.useJsonB = jsonb; + final var detectJsonB = JsonBUtil.detect(jsonb, reader); + this.useJsonB = detectJsonB.useJsonB(); + this.jsonTypes = detectJsonB.jsonTypes(); reader.addImportType(API_CONTEXT); reader.addImportType(API_ROUTING); reader.addImportType("java.io.IOException"); @@ -40,15 +42,6 @@ class ControllerWriter extends BaseControllerWriter { reader.addImportType("io.avaje.jex.htmx.TemplateContentCache"); } } - if (useJsonB) { - reader.addImportType("io.avaje.jsonb.Jsonb"); - reader.addImportType("io.avaje.jsonb.JsonType"); - reader.addImportType("io.avaje.jsonb.Types"); - this.jsonTypes = JsonBUtil.jsonTypes(reader); - jsonTypes.values().stream().map(UType::importTypes).forEach(reader::addImportTypes); - } else { - this.jsonTypes = Map.of(); - } } void write() { From 097f3f4c5aac110f2d7fa6e4ff07b504beeaf663 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Tue, 25 Feb 2025 18:39:24 -0500 Subject: [PATCH 1254/1323] [sigma] add jstachio support almost forgot about this one --- .../sigma/ControllerMethodWriter.java | 23 +++++- tests/test-sigma/pom.xml | 15 ++++ .../myapp/web/jstache/JstacheController.java | 77 +++++++++++++++++++ 3 files changed, 113 insertions(+), 2 deletions(-) create mode 100644 tests/test-sigma/src/main/java/org/example/myapp/web/jstache/JstacheController.java diff --git a/http-generator-sigma/src/main/java/io/avaje/http/generator/sigma/ControllerMethodWriter.java b/http-generator-sigma/src/main/java/io/avaje/http/generator/sigma/ControllerMethodWriter.java index cdd03ed26..459b395c8 100644 --- a/http-generator-sigma/src/main/java/io/avaje/http/generator/sigma/ControllerMethodWriter.java +++ b/http-generator-sigma/src/main/java/io/avaje/http/generator/sigma/ControllerMethodWriter.java @@ -1,10 +1,19 @@ package io.avaje.http.generator.sigma; -import static io.avaje.http.generator.core.ProcessingContext.*; +import static io.avaje.http.generator.core.ProcessingContext.isAssignable2Interface; +import static io.avaje.http.generator.core.ProcessingContext.logError; +import static io.avaje.http.generator.core.ProcessingContext.platform; import java.util.List; -import io.avaje.http.generator.core.*; +import io.avaje.http.generator.core.Append; +import io.avaje.http.generator.core.CoreWebMethod; +import io.avaje.http.generator.core.JsonBUtil; +import io.avaje.http.generator.core.MethodParam; +import io.avaje.http.generator.core.MethodReader; +import io.avaje.http.generator.core.PathSegments; +import io.avaje.http.generator.core.ProcessingContext; +import io.avaje.http.generator.core.WebMethod; import io.avaje.http.generator.core.openapi.MediaType; /** Write code to register Web route for a given controller method. */ @@ -15,6 +24,7 @@ class ControllerMethodWriter { private final WebMethod webMethod; private final boolean instrumentContext; private final boolean isFilter; + private boolean useJstachio; ControllerMethodWriter(MethodReader method, Append writer) { this.method = method; @@ -22,6 +32,7 @@ class ControllerMethodWriter { this.webMethod = method.webMethod(); this.instrumentContext = method.instrumentContext(); this.isFilter = webMethod == CoreWebMethod.FILTER; + this.useJstachio = ProcessingContext.isJstacheTemplate(method.returnType()); if (isFilter) { validateFilter(); } @@ -122,6 +133,11 @@ private List writeParams(final PathSegments segments) { private void writeContextReturn() { var produces = method.produces(); + + if (useJstachio && produces == null) { + produces = MediaType.TEXT_HTML.getValue(); + } + boolean applicationJson = produces == null || MediaType.APPLICATION_JSON.getValue().equalsIgnoreCase(produces); if (applicationJson || JsonBUtil.isJsonMimeType(produces)) { @@ -130,6 +146,9 @@ private void writeContextReturn() { } else { writer.append(" ctx.contentType(\"%s\").result(result);", produces); } + } else if (useJstachio) { + var renderer = ProcessingContext.jstacheRenderer(method.returnType()); + writer.append(" ctx.contentType(\"%s\").result(%s(result));", produces, renderer); } else if (MediaType.TEXT_HTML.getValue().equalsIgnoreCase(produces)) { writer.append(" ctx.html(result);"); } else if (MediaType.TEXT_PLAIN.getValue().equalsIgnoreCase(produces)) { diff --git a/tests/test-sigma/pom.xml b/tests/test-sigma/pom.xml index 9c8caa1b9..bde53376b 100644 --- a/tests/test-sigma/pom.xml +++ b/tests/test-sigma/pom.xml @@ -48,8 +48,23 @@ swagger-annotations ${swagger.version} + + + + io.jstach + jstachio + 1.3.6 + + + + + io.jstach + jstachio-apt + 1.3.6 + + io.avaje avaje-inject-generator diff --git a/tests/test-sigma/src/main/java/org/example/myapp/web/jstache/JstacheController.java b/tests/test-sigma/src/main/java/org/example/myapp/web/jstache/JstacheController.java new file mode 100644 index 000000000..f1e634e27 --- /dev/null +++ b/tests/test-sigma/src/main/java/org/example/myapp/web/jstache/JstacheController.java @@ -0,0 +1,77 @@ +package org.example.myapp.web.jstache; + +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; +import java.time.temporal.ChronoUnit; +import java.util.List; + +import io.avaje.http.api.Controller; +import io.avaje.http.api.Get; +import io.jstach.jstache.JStache; +import io.jstach.jstache.JStacheConfig; +import io.jstach.jstache.JStacheLambda; +import io.jstach.jstache.JStacheType; + +@Controller("/jstache") +public class JstacheController { + + @Get("/hello") + public HelloWorldZeroDependency hello() { + Person rick = new Person("Rick", LocalDate.now().minusYears(70)); + Person morty = new Person("Morty", LocalDate.now().minusYears(14)); + Person beth = new Person("Beth", LocalDate.now().minusYears(35)); + Person jerry = new Person("Jerry", LocalDate.now().minusYears(35)); + return new HelloWorldZeroDependency("Hello alien", List.of(rick, morty, beth, jerry)); + } + + @Get("/helloRuntime") + public HelloWorld helloRuntime() { + Person rick = new Person("Rick", LocalDate.now().minusYears(70)); + Person morty = new Person("Morty", LocalDate.now().minusYears(14)); + Person beth = new Person("Beth", LocalDate.now().minusYears(35)); + Person jerry = new Person("Jerry", LocalDate.now().minusYears(35)); + return new HelloWorld("Hello alien", List.of(rick, morty, beth, jerry)); + } + + /* + * Annotate the root model with an inline mustache template + */ + @JStacheConfig(type = JStacheType.STACHE) + @JStache( + template = + """ + {{#people}} + {{message}} {{name}}! You are {{#ageInfo}}{{age}}{{/ageInfo}} years old! + {{#-last}} + That is all for now! + {{/-last}} + {{/people}} + """) + public record HelloWorldZeroDependency(String message, List people) implements AgeLambdaSupport {} + + public record Person(String name, LocalDate birthday) {} + + public record AgeInfo(long age, String date) {} + + public interface AgeLambdaSupport { + @JStacheLambda + default AgeInfo ageInfo(Person person) { + long age = ChronoUnit.YEARS.between(person.birthday(), LocalDate.now()); + String date = person.birthday().format(DateTimeFormatter.ISO_DATE); + return new AgeInfo(age, date); + } + } + + @JStache( + template = + """ + {{#people}} + {{message}} {{name}}! You are {{#ageInfo}}{{age}}{{/ageInfo}} years old! + {{#-last}} + That is all for now! + {{/-last}} + {{/people}} + """) + public record HelloWorld(String message, List people) implements AgeLambdaSupport {} + +} From 45f74969e2744613231b6de9dc5ebbac175a6474 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Tue, 25 Feb 2025 18:39:24 -0500 Subject: [PATCH 1255/1323] [sigma] add jstachio support almost forgot about this one --- .../sigma/ControllerMethodWriter.java | 23 +++++- tests/test-sigma/pom.xml | 15 ++++ .../myapp/web/jstache/JstacheController.java | 77 +++++++++++++++++++ 3 files changed, 113 insertions(+), 2 deletions(-) create mode 100644 tests/test-sigma/src/main/java/org/example/myapp/web/jstache/JstacheController.java diff --git a/http-generator-sigma/src/main/java/io/avaje/http/generator/sigma/ControllerMethodWriter.java b/http-generator-sigma/src/main/java/io/avaje/http/generator/sigma/ControllerMethodWriter.java index cdd03ed26..459b395c8 100644 --- a/http-generator-sigma/src/main/java/io/avaje/http/generator/sigma/ControllerMethodWriter.java +++ b/http-generator-sigma/src/main/java/io/avaje/http/generator/sigma/ControllerMethodWriter.java @@ -1,10 +1,19 @@ package io.avaje.http.generator.sigma; -import static io.avaje.http.generator.core.ProcessingContext.*; +import static io.avaje.http.generator.core.ProcessingContext.isAssignable2Interface; +import static io.avaje.http.generator.core.ProcessingContext.logError; +import static io.avaje.http.generator.core.ProcessingContext.platform; import java.util.List; -import io.avaje.http.generator.core.*; +import io.avaje.http.generator.core.Append; +import io.avaje.http.generator.core.CoreWebMethod; +import io.avaje.http.generator.core.JsonBUtil; +import io.avaje.http.generator.core.MethodParam; +import io.avaje.http.generator.core.MethodReader; +import io.avaje.http.generator.core.PathSegments; +import io.avaje.http.generator.core.ProcessingContext; +import io.avaje.http.generator.core.WebMethod; import io.avaje.http.generator.core.openapi.MediaType; /** Write code to register Web route for a given controller method. */ @@ -15,6 +24,7 @@ class ControllerMethodWriter { private final WebMethod webMethod; private final boolean instrumentContext; private final boolean isFilter; + private boolean useJstachio; ControllerMethodWriter(MethodReader method, Append writer) { this.method = method; @@ -22,6 +32,7 @@ class ControllerMethodWriter { this.webMethod = method.webMethod(); this.instrumentContext = method.instrumentContext(); this.isFilter = webMethod == CoreWebMethod.FILTER; + this.useJstachio = ProcessingContext.isJstacheTemplate(method.returnType()); if (isFilter) { validateFilter(); } @@ -122,6 +133,11 @@ private List writeParams(final PathSegments segments) { private void writeContextReturn() { var produces = method.produces(); + + if (useJstachio && produces == null) { + produces = MediaType.TEXT_HTML.getValue(); + } + boolean applicationJson = produces == null || MediaType.APPLICATION_JSON.getValue().equalsIgnoreCase(produces); if (applicationJson || JsonBUtil.isJsonMimeType(produces)) { @@ -130,6 +146,9 @@ private void writeContextReturn() { } else { writer.append(" ctx.contentType(\"%s\").result(result);", produces); } + } else if (useJstachio) { + var renderer = ProcessingContext.jstacheRenderer(method.returnType()); + writer.append(" ctx.contentType(\"%s\").result(%s(result));", produces, renderer); } else if (MediaType.TEXT_HTML.getValue().equalsIgnoreCase(produces)) { writer.append(" ctx.html(result);"); } else if (MediaType.TEXT_PLAIN.getValue().equalsIgnoreCase(produces)) { diff --git a/tests/test-sigma/pom.xml b/tests/test-sigma/pom.xml index 9c8caa1b9..bde53376b 100644 --- a/tests/test-sigma/pom.xml +++ b/tests/test-sigma/pom.xml @@ -48,8 +48,23 @@ swagger-annotations ${swagger.version} + + + + io.jstach + jstachio + 1.3.6 + + + + + io.jstach + jstachio-apt + 1.3.6 + + io.avaje avaje-inject-generator diff --git a/tests/test-sigma/src/main/java/org/example/myapp/web/jstache/JstacheController.java b/tests/test-sigma/src/main/java/org/example/myapp/web/jstache/JstacheController.java new file mode 100644 index 000000000..f1e634e27 --- /dev/null +++ b/tests/test-sigma/src/main/java/org/example/myapp/web/jstache/JstacheController.java @@ -0,0 +1,77 @@ +package org.example.myapp.web.jstache; + +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; +import java.time.temporal.ChronoUnit; +import java.util.List; + +import io.avaje.http.api.Controller; +import io.avaje.http.api.Get; +import io.jstach.jstache.JStache; +import io.jstach.jstache.JStacheConfig; +import io.jstach.jstache.JStacheLambda; +import io.jstach.jstache.JStacheType; + +@Controller("/jstache") +public class JstacheController { + + @Get("/hello") + public HelloWorldZeroDependency hello() { + Person rick = new Person("Rick", LocalDate.now().minusYears(70)); + Person morty = new Person("Morty", LocalDate.now().minusYears(14)); + Person beth = new Person("Beth", LocalDate.now().minusYears(35)); + Person jerry = new Person("Jerry", LocalDate.now().minusYears(35)); + return new HelloWorldZeroDependency("Hello alien", List.of(rick, morty, beth, jerry)); + } + + @Get("/helloRuntime") + public HelloWorld helloRuntime() { + Person rick = new Person("Rick", LocalDate.now().minusYears(70)); + Person morty = new Person("Morty", LocalDate.now().minusYears(14)); + Person beth = new Person("Beth", LocalDate.now().minusYears(35)); + Person jerry = new Person("Jerry", LocalDate.now().minusYears(35)); + return new HelloWorld("Hello alien", List.of(rick, morty, beth, jerry)); + } + + /* + * Annotate the root model with an inline mustache template + */ + @JStacheConfig(type = JStacheType.STACHE) + @JStache( + template = + """ + {{#people}} + {{message}} {{name}}! You are {{#ageInfo}}{{age}}{{/ageInfo}} years old! + {{#-last}} + That is all for now! + {{/-last}} + {{/people}} + """) + public record HelloWorldZeroDependency(String message, List people) implements AgeLambdaSupport {} + + public record Person(String name, LocalDate birthday) {} + + public record AgeInfo(long age, String date) {} + + public interface AgeLambdaSupport { + @JStacheLambda + default AgeInfo ageInfo(Person person) { + long age = ChronoUnit.YEARS.between(person.birthday(), LocalDate.now()); + String date = person.birthday().format(DateTimeFormatter.ISO_DATE); + return new AgeInfo(age, date); + } + } + + @JStache( + template = + """ + {{#people}} + {{message}} {{name}}! You are {{#ageInfo}}{{age}}{{/ageInfo}} years old! + {{#-last}} + That is all for now! + {{/-last}} + {{/people}} + """) + public record HelloWorld(String message, List people) implements AgeLambdaSupport {} + +} From 0806718912c66bd765fcae3f81a9505bce9be96b Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Tue, 25 Feb 2025 19:15:08 -0500 Subject: [PATCH 1256/1323] Update SigmaProcessorTest.java --- .../java/io/avaje/http/generator/SigmaProcessorTest.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/test-sigma/src/test/java/io/avaje/http/generator/SigmaProcessorTest.java b/tests/test-sigma/src/test/java/io/avaje/http/generator/SigmaProcessorTest.java index dda2e39b7..b0d37a7ad 100644 --- a/tests/test-sigma/src/test/java/io/avaje/http/generator/SigmaProcessorTest.java +++ b/tests/test-sigma/src/test/java/io/avaje/http/generator/SigmaProcessorTest.java @@ -50,7 +50,9 @@ public void runAnnotationProcessor() throws Exception { new PrintWriter(System.out), null, null, - List.of("--release=11", "-AdisableDirectWrites=true"), + List.of( + "--release=" + Integer.getInteger("java.specification.version"), + "-AdisableDirectWrites=true"), null, files); task.setProcessors(List.of(new SigmaProcessor())); @@ -75,7 +77,7 @@ void runAnnotationProcessorJakarta() throws Exception { null, null, List.of( - "--release=11", + "--release=" + Integer.getInteger("java.specification.version"), "-AuseJavax=false", "-AuseSingleton=true", "-AdisableDirectWrites=true"), From 8efca6c94e05763b0156e1bf75723ab3f4218c87 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Mar 2025 19:37:51 +0000 Subject: [PATCH 1257/1323] Bump the dependencies group with 7 updates Bumps the dependencies group with 7 updates: | Package | From | To | | --- | --- | --- | | [com.fasterxml.jackson.core:jackson-databind](https://github.com/FasterXML/jackson) | `2.18.2` | `2.18.3` | | [io.avaje:avaje-sigma](https://github.com/avaje/avaje-sigma) | `0.4` | `1.0` | | io.helidon.webserver:helidon-webserver | `4.1.6` | `4.2.0` | | io.helidon.webserver:helidon-webserver-security | `4.1.6` | `4.2.0` | | io.helidon.http.media:helidon-http-media-jsonb | `4.1.6` | `4.2.0` | | org.slf4j:slf4j-jdk-platform-logging | `2.0.16` | `2.0.17` | | [ch.qos.logback:logback-classic](https://github.com/qos-ch/logback) | `1.5.16` | `1.5.17` | Updates `com.fasterxml.jackson.core:jackson-databind` from 2.18.2 to 2.18.3 - [Commits](https://github.com/FasterXML/jackson/commits) Updates `io.avaje:avaje-sigma` from 0.4 to 1.0 - [Release notes](https://github.com/avaje/avaje-sigma/releases) - [Commits](https://github.com/avaje/avaje-sigma/compare/0.4...1.0) Updates `io.helidon.webserver:helidon-webserver` from 4.1.6 to 4.2.0 Updates `io.helidon.webserver:helidon-webserver-security` from 4.1.6 to 4.2.0 Updates `io.helidon.http.media:helidon-http-media-jsonb` from 4.1.6 to 4.2.0 Updates `io.helidon.webserver:helidon-webserver-security` from 4.1.6 to 4.2.0 Updates `io.helidon.http.media:helidon-http-media-jsonb` from 4.1.6 to 4.2.0 Updates `org.slf4j:slf4j-jdk-platform-logging` from 2.0.16 to 2.0.17 Updates `ch.qos.logback:logback-classic` from 1.5.16 to 1.5.17 - [Release notes](https://github.com/qos-ch/logback/releases) - [Commits](https://github.com/qos-ch/logback/compare/v_1.5.16...v_1.5.17) --- updated-dependencies: - dependency-name: com.fasterxml.jackson.core:jackson-databind dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: io.avaje:avaje-sigma dependency-type: direct:production update-type: version-update:semver-major dependency-group: dependencies - dependency-name: io.helidon.webserver:helidon-webserver dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.helidon.webserver:helidon-webserver-security dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.helidon.http.media:helidon-http-media-jsonb dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.helidon.webserver:helidon-webserver-security dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.helidon.http.media:helidon-http-media-jsonb dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: org.slf4j:slf4j-jdk-platform-logging dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: ch.qos.logback:logback-classic dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies ... Signed-off-by: dependabot[bot] --- htmx-nima/pom.xml | 2 +- http-client/pom.xml | 2 +- tests/pom.xml | 4 ++-- tests/test-client-generation/pom.xml | 4 ++-- tests/test-sigma/pom.xml | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/htmx-nima/pom.xml b/htmx-nima/pom.xml index 02a04e28f..832641463 100644 --- a/htmx-nima/pom.xml +++ b/htmx-nima/pom.xml @@ -26,7 +26,7 @@ io.helidon.webserver helidon-webserver - 4.1.6 + 4.2.0 diff --git a/http-client/pom.xml b/http-client/pom.xml index 143635023..adb811c42 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -29,7 +29,7 @@ com.fasterxml.jackson.core jackson-databind - 2.18.2 + 2.18.3 true diff --git a/tests/pom.xml b/tests/pom.xml index 683c03d4d..e003572bb 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -14,10 +14,10 @@ true 5.12.0 3.27.3 - 2.18.2 + 2.18.3 3.0-RC20 11.2 - 4.1.6 + 4.2.0 6.4.0 diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index 9fe9b2ce8..8883406c3 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -20,13 +20,13 @@ org.slf4j slf4j-jdk-platform-logging - 2.0.16 + 2.0.17 ch.qos.logback logback-classic - 1.5.16 + 1.5.17 diff --git a/tests/test-sigma/pom.xml b/tests/test-sigma/pom.xml index bde53376b..f522ba80c 100644 --- a/tests/test-sigma/pom.xml +++ b/tests/test-sigma/pom.xml @@ -28,7 +28,7 @@ io.avaje avaje-sigma - 0.4 + 1.0 From 9188ae930d19c533c3f2cd76ba72ea32d5b33784 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Fri, 7 Mar 2025 16:23:12 +1300 Subject: [PATCH 1258/1323] openapi.json - add reading operationId from swagger @Operation annotation (#573) --- .../http/generator/core/MethodReader.java | 20 +++++++++++++++++++ .../core/openapi/MethodDocBuilder.java | 4 +--- .../http/generator/core/package-info.java | 1 + .../example/myapp/web/HelloController.java | 2 ++ .../src/main/resources/public/openapi.json | 1 + 5 files changed, 25 insertions(+), 3 deletions(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java index b51abc302..169faf06a 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java @@ -22,6 +22,7 @@ import io.avaje.http.generator.core.javadoc.Javadoc; import io.avaje.http.generator.core.openapi.MethodDocBuilder; +import io.swagger.v3.oas.models.Operation; public class MethodReader { @@ -269,6 +270,25 @@ private List buildApiResponses() { return responses; } + public void readOperation(Operation operation, Javadoc javadoc) { + OperationPrism.getOptionalOn(element).ifPresent(an -> { + operation.setOperationId(emptyToNull(an.operationId())); + operation.setDeprecated(an.deprecated()); + operation.setSummary(emptyToNull(an.summary())); + operation.setDescription(emptyToNull(an.description())); + }); + if (operation.getDescription() == null) { + operation.setDescription(javadoc.getDescription()); + } + if (operation.getSummary() == null) { + operation.setSummary(javadoc.getSummary()); + } + } + + private static String emptyToNull(String val) { + return val.isEmpty() ? null : val; + } + public Optional findAnnotation(Function> prismFunc) { return findAnnotation(prismFunc, element); } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/MethodDocBuilder.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/MethodDocBuilder.java index 944a5d183..55b6a913f 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/MethodDocBuilder.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/MethodDocBuilder.java @@ -39,9 +39,7 @@ public void build() { return; } - //operation.setOperationId(); - operation.setSummary(javadoc.getSummary()); - operation.setDescription(javadoc.getDescription()); + methodReader.readOperation(operation, javadoc); operation.setTags(methodReader.tags()); if (javadoc.isDeprecated() diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/package-info.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/package-info.java index 5300dda1b..50ff9161b 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/package-info.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/package-info.java @@ -23,6 +23,7 @@ @GeneratePrism(value = io.avaje.http.api.InstrumentServerContext.class) @GeneratePrism(value = io.avaje.http.api.ExceptionHandler.class) @GeneratePrism(value = io.swagger.v3.oas.annotations.OpenAPIDefinition.class, publicAccess = true) +@GeneratePrism(value = io.swagger.v3.oas.annotations.Operation.class, publicAccess = true) @GeneratePrism(value = io.swagger.v3.oas.annotations.tags.Tag.class, publicAccess = true) @GeneratePrism(value = io.swagger.v3.oas.annotations.tags.Tags.class, publicAccess = true) @GeneratePrism(value = io.swagger.v3.oas.annotations.security.SecurityScheme.class, publicAccess = true) diff --git a/tests/test-javalin/src/main/java/org/example/myapp/web/HelloController.java b/tests/test-javalin/src/main/java/org/example/myapp/web/HelloController.java index 0dbc23f18..2d3bb523b 100644 --- a/tests/test-javalin/src/main/java/org/example/myapp/web/HelloController.java +++ b/tests/test-javalin/src/main/java/org/example/myapp/web/HelloController.java @@ -8,6 +8,7 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.Executors; +import io.swagger.v3.oas.annotations.Operation; import org.example.myapp.service.MyService; import io.avaje.http.api.BeanParam; @@ -61,6 +62,7 @@ String getPlainMessage() { */ @Deprecated @Roles({AppRoles.ADMIN, AppRoles.BASIC_USER}) + @Operation(operationId = "helloByDate") @Get("/{id}/{date}") HelloDto hello(int id, LocalDate date, String otherParam) { return new HelloDto(id, date.toString(), otherParam); diff --git a/tests/test-javalin/src/main/resources/public/openapi.json b/tests/test-javalin/src/main/resources/public/openapi.json index 7088ed71f..d20624dbc 100644 --- a/tests/test-javalin/src/main/resources/public/openapi.json +++ b/tests/test-javalin/src/main/resources/public/openapi.json @@ -750,6 +750,7 @@ ], "summary" : "Return the Hello DTO", "description" : "", + "operationId" : "helloByDate", "parameters" : [ { "name" : "id", From 7452d4f12ca7f38ce55cd313298eb9f11f95e231 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Mon, 10 Mar 2025 14:07:49 +1300 Subject: [PATCH 1259/1323] Versionn 3.1-RC2 --- aws-cognito/http-client-authtoken/pom.xml | 2 +- htmx-api/pom.xml | 2 +- htmx-nima-jstache/pom.xml | 2 +- htmx-nima/pom.xml | 4 ++-- http-api-javalin/pom.xml | 2 +- http-api/pom.xml | 2 +- http-client-gson-adapter/pom.xml | 4 ++-- http-client-moshi-adapter/pom.xml | 4 ++-- http-client/pom.xml | 2 +- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 2 +- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-generator-sigma/pom.xml | 2 +- http-inject-plugin/pom.xml | 2 +- pom.xml | 4 ++-- tests/pom.xml | 2 +- tests/test-client-generation/pom.xml | 2 +- tests/test-client/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-htmx/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- tests/test-sigma/pom.xml | 2 +- 27 files changed, 31 insertions(+), 31 deletions(-) diff --git a/aws-cognito/http-client-authtoken/pom.xml b/aws-cognito/http-client-authtoken/pom.xml index 73c8efb8e..b302d2fc7 100644 --- a/aws-cognito/http-client-authtoken/pom.xml +++ b/aws-cognito/http-client-authtoken/pom.xml @@ -17,7 +17,7 @@ io.avaje avaje-http-client - 3.1-RC1 + 3.1-RC2 diff --git a/htmx-api/pom.xml b/htmx-api/pom.xml index 3e45f30a9..e23b8fb4e 100644 --- a/htmx-api/pom.xml +++ b/htmx-api/pom.xml @@ -6,7 +6,7 @@ io.avaje avaje-http-parent - 3.1-RC1 + 3.1-RC2 avaje-htmx-api diff --git a/htmx-nima-jstache/pom.xml b/htmx-nima-jstache/pom.xml index 94f98e5ed..657d488e6 100644 --- a/htmx-nima-jstache/pom.xml +++ b/htmx-nima-jstache/pom.xml @@ -6,7 +6,7 @@ io.avaje avaje-http-parent - 3.1-RC1 + 3.1-RC2 avaje-htmx-nima-jstache diff --git a/htmx-nima/pom.xml b/htmx-nima/pom.xml index 832641463..4d052de8a 100644 --- a/htmx-nima/pom.xml +++ b/htmx-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje avaje-http-parent - 3.1-RC1 + 3.1-RC2 avaje-htmx-nima @@ -21,7 +21,7 @@ io.avaje avaje-htmx-api - 3.1-RC1 + 3.1-RC2 io.helidon.webserver diff --git a/http-api-javalin/pom.xml b/http-api-javalin/pom.xml index 628df333b..6fb8acfd6 100644 --- a/http-api-javalin/pom.xml +++ b/http-api-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.1-RC1 + 3.1-RC2 .. diff --git a/http-api/pom.xml b/http-api/pom.xml index 36e7a9f08..c7ddcb82e 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.1-RC1 + 3.1-RC2 .. diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index 029359735..1b080ffb9 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.1-RC1 + 3.1-RC2 avaje-http-client-gson @@ -20,7 +20,7 @@ io.avaje avaje-http-client - 3.1-RC1 + 3.1-RC2 provided diff --git a/http-client-moshi-adapter/pom.xml b/http-client-moshi-adapter/pom.xml index 38def5854..1bd8517f7 100644 --- a/http-client-moshi-adapter/pom.xml +++ b/http-client-moshi-adapter/pom.xml @@ -3,7 +3,7 @@ io.avaje avaje-http-parent - 3.1-RC1 + 3.1-RC2 avaje-http-client-moshi @@ -19,7 +19,7 @@ io.avaje avaje-http-client - 3.1-RC1 + 3.1-RC2 provided diff --git a/http-client/pom.xml b/http-client/pom.xml index adb811c42..2412373b0 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.1-RC1 + 3.1-RC2 avaje-http-client diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index a49b2e364..a4da79a85 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.1-RC1 + 3.1-RC2 avaje-http-client-generator diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index f47053a3d..21625762c 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.1-RC1 + 3.1-RC2 avaje-http-generator-core diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index 15d3dedc2..2759aafd6 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 3.1-RC1 + 3.1-RC2 avaje-http-helidon-generator diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index a3fdb2e9d..2e916703f 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.1-RC1 + 3.1-RC2 avaje-http-javalin-generator diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index c7e3e85bc..216b84c46 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.1-RC1 + 3.1-RC2 avaje-http-jex-generator diff --git a/http-generator-sigma/pom.xml b/http-generator-sigma/pom.xml index b5fe27b02..81ed67d83 100644 --- a/http-generator-sigma/pom.xml +++ b/http-generator-sigma/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.1-RC1 + 3.1-RC2 avaje-http-sigma-generator diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index 686769827..5b74bc795 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.1-RC1 + 3.1-RC2 .. diff --git a/pom.xml b/pom.xml index f09ddfa3d..09c9732d8 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-parent - 3.1-RC1 + 3.1-RC2 pom @@ -23,7 +23,7 @@ 2.14.2 3.0-RC10 1.39 - 2025-02-21T09:57:12Z + 2025-03-10T00:18:35Z ${project.build.directory}${file.separator}module-info.shade diff --git a/tests/pom.xml b/tests/pom.xml index e003572bb..60cd02700 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 3.1-RC1 + 3.1-RC2 tests diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index 8883406c3..59000c5f1 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 3.1-RC1 + 3.1-RC2 test-client-generation diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index feccf53c4..e3279a902 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 3.1-RC1 + 3.1-RC2 test-client diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index ec62dc6e8..469a43747 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 3.1-RC1 + 3.1-RC2 test-javalin-jsonb diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 1dc23914b..1b565ac67 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 3.1-RC1 + 3.1-RC2 test-javalin diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 7caceb7f9..d512f1f1b 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 3.1-RC1 + 3.1-RC2 test-jex diff --git a/tests/test-nima-htmx/pom.xml b/tests/test-nima-htmx/pom.xml index 92ef45cc6..28b86efef 100644 --- a/tests/test-nima-htmx/pom.xml +++ b/tests/test-nima-htmx/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 3.1-RC1 + 3.1-RC2 test-nima-htmx diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index d2616b48c..6c6961d3e 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 3.1-RC1 + 3.1-RC2 test-nima-jsonb diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index dfe88e0e9..26910f4fe 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 3.1-RC1 + 3.1-RC2 test-nima diff --git a/tests/test-sigma/pom.xml b/tests/test-sigma/pom.xml index f522ba80c..db26495e6 100644 --- a/tests/test-sigma/pom.xml +++ b/tests/test-sigma/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 3.1-RC1 + 3.1-RC2 test-sigma From 70d908cc21011d7a1d4601771a5310d12978e7f1 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Mon, 10 Mar 2025 16:46:36 +1300 Subject: [PATCH 1260/1323] Add disableJsonB option to NOT use avaje-jsonb in code generation even if it's in the classpath (#574) --- .../http/generator/core/BaseProcessor.java | 2 +- .../generator/core/ProcessingContext.java | 6 ++ tests/test-jex/pom.xml | 76 +++++++++++++------ 3 files changed, 59 insertions(+), 25 deletions(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java index 485835fa3..cb89e4c1f 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java @@ -27,7 +27,7 @@ @GenerateAPContext @GenerateModuleInfoReader -@SupportedOptions({"useJavax", "useSingleton", "instrumentRequests","disableDirectWrites"}) +@SupportedOptions({"useJavax", "useSingleton", "instrumentRequests","disableDirectWrites","disableJsonB"}) public abstract class BaseProcessor extends AbstractProcessor { protected String contextPathString; diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java index c3fcbf2ea..4d5fccce1 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java @@ -54,6 +54,7 @@ private static final class Ctx { private final String diAnnotation; private final boolean instrumentAllMethods; private final boolean disableDirectWrites; + private final boolean disableJsonB; private final boolean javalin6; private final Set clientFQN = new HashSet<>(); @@ -73,6 +74,7 @@ private static final class Ctx { final var singletonOverride = options.get("useSingleton"); this.instrumentAllMethods = Boolean.parseBoolean(options.get("instrumentRequests")); this.disableDirectWrites = Boolean.parseBoolean(options.get("disableDirectWrites")); + this.disableJsonB = Boolean.parseBoolean(options.get("disableJsonB")); if (singletonOverride != null) { useComponent = !Boolean.parseBoolean(singletonOverride); } else { @@ -202,6 +204,10 @@ public static boolean instrumentAllWebMethods() { } public static boolean useJsonb() { + return isJsonbInClasspath() && !CTX.get().disableJsonB; + } + + private static boolean isJsonbInClasspath() { try { return CTX.get().elementUtils.getTypeElement("io.avaje.jsonb.Jsonb") != null || Class.forName("io.avaje.jsonb.Jsonb") != null; diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index d512f1f1b..7c006b12e 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -79,31 +79,7 @@ - - io.avaje - avaje-inject-generator - ${avaje-inject.version} - provided - - - - io.avaje - avaje-http-jex-generator - ${project.version} - provided - - - - io.avaje - avaje-jsonb-generator - 3.0 - - - io.jstach - jstachio-apt - 1.3.6 - @@ -126,6 +102,44 @@ app + + org.apache.maven.plugins + maven-compiler-plugin + 3.14.0 + + + + + + + io.avaje + avaje-inject-generator + ${avaje-inject.version} + + + io.avaje + avaje-http-jex-generator + ${project.version} + + + io.avaje + avaje-jsonb-generator + 3.0 + + + io.avaje + avaje-validator-generator + 2.8 + + + io.jstach + jstachio-apt + 1.3.6 + + + + + io.avaje openapi-maven-plugin @@ -153,6 +167,20 @@ + + + io.avaje + avaje-inject-maven-plugin + 11.2 + + + process-sources + + provides + + + + From 3ed55e54f8d2a8c477f0a74cb0508306f1e97756 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Mon, 10 Mar 2025 20:02:28 +1300 Subject: [PATCH 1261/1323] When using @Operation, treat deprecated false as NULL (reduce openapi.json noise) (#575) The prior change adding reading @Operation, introduced an issue in that all non-deprecated methods then explicitly had in openapi.json a deprecated = false attribute. This "fixes" that issue by only setting deprecated attribute when it is true. --- .../main/java/io/avaje/http/generator/core/MethodReader.java | 5 ++++- .../src/main/java/org/example/myapp/web/HelloController.java | 1 + tests/test-javalin/src/main/resources/public/openapi.json | 1 + 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java index 169faf06a..8215b71d3 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java @@ -273,9 +273,12 @@ private List buildApiResponses() { public void readOperation(Operation operation, Javadoc javadoc) { OperationPrism.getOptionalOn(element).ifPresent(an -> { operation.setOperationId(emptyToNull(an.operationId())); - operation.setDeprecated(an.deprecated()); operation.setSummary(emptyToNull(an.summary())); operation.setDescription(emptyToNull(an.description())); + if (Boolean.TRUE.equals(an.deprecated())) { + // leave deprecated false as NULL to reduce openapi noise + operation.setDeprecated(true); + } }); if (operation.getDescription() == null) { operation.setDescription(javadoc.getDescription()); diff --git a/tests/test-javalin/src/main/java/org/example/myapp/web/HelloController.java b/tests/test-javalin/src/main/java/org/example/myapp/web/HelloController.java index 2d3bb523b..854d7ac19 100644 --- a/tests/test-javalin/src/main/java/org/example/myapp/web/HelloController.java +++ b/tests/test-javalin/src/main/java/org/example/myapp/web/HelloController.java @@ -76,6 +76,7 @@ HelloDto hello(int id, LocalDate date, String otherParam) { * @return The Hellos that we found. */ @Roles(AppRoles.ADMIN) + @Operation(operationId = "findByName") @Get("/findbyname/{name}") List findByName(String name, @QueryParam("my-param") @Default("one") String myParam) { return new ArrayList<>(); diff --git a/tests/test-javalin/src/main/resources/public/openapi.json b/tests/test-javalin/src/main/resources/public/openapi.json index d20624dbc..e9b204041 100644 --- a/tests/test-javalin/src/main/resources/public/openapi.json +++ b/tests/test-javalin/src/main/resources/public/openapi.json @@ -351,6 +351,7 @@ ], "summary" : "Find Hellos by name", "description" : "", + "operationId" : "findByName", "parameters" : [ { "name" : "name", From f2643efc4110a4d2f79d3e7e4843f731407e2352 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 10 Mar 2025 20:04:58 +0000 Subject: [PATCH 1262/1323] Bump the dependencies group with 5 updates Bumps the dependencies group with 5 updates: | Package | From | To | | --- | --- | --- | | [io.javalin:javalin](https://github.com/javalin/javalin) | `6.4.0` | `6.5.0` | | io.swagger.core.v3:swagger-models | `2.2.28` | `2.2.29` | | io.swagger.core.v3:swagger-annotations | `2.2.28` | `2.2.29` | | [io.avaje:avaje-jex](https://github.com/avaje/avaje-jex) | `3.0-RC20` | `3.0-RC21` | | io.avaje:avaje-jex-htmx | `3.0-RC20` | `3.0-RC21` | Updates `io.javalin:javalin` from 6.4.0 to 6.5.0 - [Release notes](https://github.com/javalin/javalin/releases) - [Commits](https://github.com/javalin/javalin/compare/javalin-parent-6.4.0...javalin-parent-6.5.0) Updates `io.swagger.core.v3:swagger-models` from 2.2.28 to 2.2.29 Updates `io.swagger.core.v3:swagger-annotations` from 2.2.28 to 2.2.29 Updates `io.swagger.core.v3:swagger-annotations` from 2.2.28 to 2.2.29 Updates `io.avaje:avaje-jex` from 3.0-RC20 to 3.0-RC21 - [Release notes](https://github.com/avaje/avaje-jex/releases) - [Commits](https://github.com/avaje/avaje-jex/commits) Updates `io.avaje:avaje-jex-htmx` from 3.0-RC20 to 3.0-RC21 Updates `io.avaje:avaje-jex-htmx` from 3.0-RC20 to 3.0-RC21 --- updated-dependencies: - dependency-name: io.javalin:javalin dependency-type: direct:development update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.swagger.core.v3:swagger-models dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: io.swagger.core.v3:swagger-annotations dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: io.swagger.core.v3:swagger-annotations dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: io.avaje:avaje-jex dependency-type: direct:development dependency-group: dependencies - dependency-name: io.avaje:avaje-jex-htmx dependency-type: direct:production dependency-group: dependencies - dependency-name: io.avaje:avaje-jex-htmx dependency-type: direct:production dependency-group: dependencies ... Signed-off-by: dependabot[bot] --- http-api/pom.xml | 2 +- http-client/pom.xml | 2 +- pom.xml | 2 +- tests/pom.xml | 4 ++-- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-sigma/pom.xml | 2 +- 8 files changed, 9 insertions(+), 9 deletions(-) diff --git a/http-api/pom.xml b/http-api/pom.xml index c7ddcb82e..0b325f4f4 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -24,7 +24,7 @@ io.javalin javalin - 6.4.0 + 6.5.0 provided true diff --git a/http-client/pom.xml b/http-client/pom.xml index 2412373b0..0880a3002 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -66,7 +66,7 @@ io.javalin javalin - 6.4.0 + 6.5.0 test diff --git a/pom.xml b/pom.xml index 09c9732d8..aeab3cfed 100644 --- a/pom.xml +++ b/pom.xml @@ -19,7 +19,7 @@ true - 2.2.28 + 2.2.29 2.14.2 3.0-RC10 1.39 diff --git a/tests/pom.xml b/tests/pom.xml index 60cd02700..7f81efd89 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -15,10 +15,10 @@ 5.12.0 3.27.3 2.18.3 - 3.0-RC20 + 3.0-RC21 11.2 4.2.0 - 6.4.0 + 6.5.0 diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 469a43747..f5adbc191 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -13,7 +13,7 @@ true org.example.myapp.Main - 2.2.28 + 2.2.29 1.3.71 diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 1b565ac67..8a386c4bf 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -12,7 +12,7 @@ true org.example.myapp.Main - 2.2.28 + 2.2.29 1.3.71 diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 7c006b12e..93948ff70 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -12,7 +12,7 @@ 21 true org.example.myapp.Main - 2.2.28 + 2.2.29 diff --git a/tests/test-sigma/pom.xml b/tests/test-sigma/pom.xml index db26495e6..9288857cd 100644 --- a/tests/test-sigma/pom.xml +++ b/tests/test-sigma/pom.xml @@ -13,7 +13,7 @@ 17 true - 2.2.28 + 2.2.29 1.3.71 From 9507ab950eee93ef9300e5b05f60ea7286aec95f Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Wed, 12 Mar 2025 16:43:19 -0700 Subject: [PATCH 1263/1323] Cancel generation if apt errors detected (#577) --- .../main/java/io/avaje/http/generator/core/BaseProcessor.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java index cb89e4c1f..fcbe548f6 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java @@ -56,6 +56,9 @@ public synchronized void init(ProcessingEnvironment processingEnv) { @Override public boolean process(Set annotations, RoundEnvironment round) { + if (round.errorRaised()) { + return false; + } var pathElements = round.getElementsAnnotatedWith(typeElement(PathPrism.PRISM_TYPE)); APContext.setProjectModuleElement(annotations, round); if (contextPathString == null) { From 340d913ee764f9580461fbb2c1e088f965c58a8a Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Mon, 17 Mar 2025 01:42:12 -0400 Subject: [PATCH 1264/1323] [jex-generator] use jex body methods uses the new body methods of jex instead of a direct read using jsonb --- .../http/generator/core/ControllerReader.java | 2 +- .../avaje/http/generator/jex/JexAdapter.java | 46 ++++++++++++++++++- 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java index bc8139b93..a085127cf 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ControllerReader.java @@ -311,7 +311,7 @@ private void readSuper(TypeElement beanType) { if (superclass.getKind() != TypeKind.NONE) { final DeclaredType declaredType = (DeclaredType) superclass; final TypeElement superElement = asElement(superclass); - if (!"java.lang.Object".equals(superElement.toString())) { + if (!"java.lang.Object".equals(superElement.getQualifiedName().toString())) { for (final Element element : superElement.getEnclosedElements()) { if (element.getKind() == ElementKind.METHOD) { readMethod((ExecutableElement) element, declaredType); diff --git a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/JexAdapter.java b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/JexAdapter.java index 100589c1f..de0b6f8eb 100644 --- a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/JexAdapter.java +++ b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/JexAdapter.java @@ -1,6 +1,7 @@ package io.avaje.http.generator.jex; import java.util.List; +import java.util.stream.Collectors; import io.avaje.http.generator.core.Append; import io.avaje.http.generator.core.Constants; @@ -9,6 +10,7 @@ import io.avaje.http.generator.core.PlatformAdapter; import io.avaje.http.generator.core.ProcessingContext; import io.avaje.http.generator.core.UType; +import io.avaje.http.generator.core.Util; class JexAdapter implements PlatformAdapter { @@ -38,12 +40,54 @@ public String bodyAsClass(UType type) { return "ctx.body()"; } else if ("byte[]".equals(type.full())) { return "ctx.bodyAsBytes()"; + } else if (type.isGeneric() && ProcessingContext.useJsonb()) { + return "ctx.<%s>bodyAsType(%s)".formatted(type.shortType(), writeJsonbType(type)); } else if (ProcessingContext.useJsonb()) { - return type.shortName() + "JsonType.fromJson(ctx.bodyAsInputStream())"; + return "ctx.bodyAsClass(%s.class)".formatted(type.shortType()); } return "ctx.bodyAsClass(" + type.mainType() + ".class)"; } + public static String writeJsonbType(UType type) { + var writer = new StringBuilder(); + + switch (type.mainType()) { + case "java.util.List": + writeType(type.paramRaw(), writer); + writer.append(".list()"); + break; + case "java.util.Set": + writeType(type.paramRaw(), writer); + writer.append(".set()"); + break; + case "java.util.Map": + writeType(type.paramRaw(), writer); + writer.append(".map()"); + break; + default: + { + if (type.mainType().contains("java.util")) { + throw new UnsupportedOperationException( + "Only java.util Map, Set and List are supported JsonB Controller Collection Types"); + } + writeType(type, writer); + } + } + return writer.toString(); + } + + static void writeType(UType type, StringBuilder writer) { + final var params = + type.params().stream() + .map(Util::shortName) + .map(s -> "?".equals(s) ? "Object" : s) + .collect(Collectors.joining(".class, ")); + + writer.append( + "Types.newParameterizedType(%s.class, %s.class)" + .formatted(Util.shortName(type.mainType()), params)); + } + @Override public String indent() { return " "; From 54627e1bfc0f7d1efbaf7ba9f9efbb93d56d570f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 17 Mar 2025 05:54:54 +0000 Subject: [PATCH 1265/1323] Bump the dependencies group with 17 updates Bumps the dependencies group with 17 updates: | Package | From | To | | --- | --- | --- | | [io.avaje:avaje-jsonb](https://github.com/avaje/avaje-jsonb) | `3.0` | `3.1` | | io.avaje:avaje-json-node | `3.0` | `3.1` | | [io.avaje:avaje-inject](https://github.com/avaje/avaje-inject) | `11.2` | `11.3` | | io.avaje:avaje-inject-generator | `11.2` | `11.3` | | [io.avaje:avaje-prisms](https://github.com/avaje/avaje-prisms) | `1.39` | `1.40` | | [io.avaje:avaje-validator](https://github.com/avaje/avaje-validator) | `2.8` | `2.9` | | io.avaje:avaje-validator-constraints | `2.8` | `2.9` | | io.avaje:avaje-validator-generator | `2.8` | `2.9` | | io.avaje:avaje-jsonb-generator | `3.0` | `3.1` | | io.jstach:jstachio | `1.3.6` | `1.3.7` | | io.jstach:jstachio-apt | `1.3.6` | `1.3.7` | | [io.avaje:avaje-jex](https://github.com/avaje/avaje-jex) | `3.0-RC21` | `3.0-RC22` | | io.avaje:avaje-jex-htmx | `3.0-RC21` | `3.0-RC22` | | io.avaje:avaje-inject-maven-plugin | `11.2` | `11.3` | | [org.junit.jupiter:junit-jupiter-api](https://github.com/junit-team/junit5) | `5.12.0` | `5.12.1` | | [org.junit.jupiter:junit-jupiter-engine](https://github.com/junit-team/junit5) | `5.12.0` | `5.12.1` | | io.avaje:avaje-json-core | `3.0` | `3.1` | Updates `io.avaje:avaje-jsonb` from 3.0 to 3.1 - [Release notes](https://github.com/avaje/avaje-jsonb/releases) - [Commits](https://github.com/avaje/avaje-jsonb/compare/3.0...3.1) Updates `io.avaje:avaje-json-node` from 3.0 to 3.1 Updates `io.avaje:avaje-inject` from 11.2 to 11.3 - [Release notes](https://github.com/avaje/avaje-inject/releases) - [Commits](https://github.com/avaje/avaje-inject/compare/11.2...11.3) Updates `io.avaje:avaje-inject-generator` from 11.2 to 11.3 Updates `io.avaje:avaje-inject-generator` from 11.2 to 11.3 Updates `io.avaje:avaje-prisms` from 1.39 to 1.40 - [Release notes](https://github.com/avaje/avaje-prisms/releases) - [Commits](https://github.com/avaje/avaje-prisms/compare/1.39...1.40) Updates `io.avaje:avaje-validator` from 2.8 to 2.9 - [Release notes](https://github.com/avaje/avaje-validator/releases) - [Commits](https://github.com/avaje/avaje-validator/compare/2.8...2.9) Updates `io.avaje:avaje-validator-constraints` from 2.8 to 2.9 Updates `io.avaje:avaje-validator-generator` from 2.8 to 2.9 Updates `io.avaje:avaje-jsonb-generator` from 3.0 to 3.1 Updates `io.jstach:jstachio` from 1.3.6 to 1.3.7 Updates `io.jstach:jstachio-apt` from 1.3.6 to 1.3.7 Updates `io.jstach:jstachio-apt` from 1.3.6 to 1.3.7 Updates `io.avaje:avaje-jex` from 3.0-RC21 to 3.0-RC22 - [Release notes](https://github.com/avaje/avaje-jex/releases) - [Commits](https://github.com/avaje/avaje-jex/commits) Updates `io.avaje:avaje-jex-htmx` from 3.0-RC21 to 3.0-RC22 Updates `io.avaje:avaje-inject-maven-plugin` from 11.2 to 11.3 Updates `io.avaje:avaje-jex-htmx` from 3.0-RC21 to 3.0-RC22 Updates `org.junit.jupiter:junit-jupiter-api` from 5.12.0 to 5.12.1 - [Release notes](https://github.com/junit-team/junit5/releases) - [Commits](https://github.com/junit-team/junit5/compare/r5.12.0...r5.12.1) Updates `org.junit.jupiter:junit-jupiter-engine` from 5.12.0 to 5.12.1 - [Release notes](https://github.com/junit-team/junit5/releases) - [Commits](https://github.com/junit-team/junit5/compare/r5.12.0...r5.12.1) Updates `org.junit.jupiter:junit-jupiter-engine` from 5.12.0 to 5.12.1 - [Release notes](https://github.com/junit-team/junit5/releases) - [Commits](https://github.com/junit-team/junit5/compare/r5.12.0...r5.12.1) Updates `io.avaje:avaje-json-core` from 3.0 to 3.1 --- updated-dependencies: - dependency-name: io.avaje:avaje-jsonb dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.avaje:avaje-json-node dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.avaje:avaje-inject dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.avaje:avaje-inject-generator dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.avaje:avaje-inject-generator dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.avaje:avaje-prisms dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.avaje:avaje-validator dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.avaje:avaje-validator-constraints dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.avaje:avaje-validator-generator dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.avaje:avaje-jsonb-generator dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.jstach:jstachio dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: io.jstach:jstachio-apt dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: io.jstach:jstachio-apt dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: io.avaje:avaje-jex dependency-type: direct:development dependency-group: dependencies - dependency-name: io.avaje:avaje-jex-htmx dependency-type: direct:production dependency-group: dependencies - dependency-name: io.avaje:avaje-inject-maven-plugin dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.avaje:avaje-jex-htmx dependency-type: direct:production dependency-group: dependencies - dependency-name: org.junit.jupiter:junit-jupiter-api dependency-type: direct:development update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: org.junit.jupiter:junit-jupiter-engine dependency-type: direct:development update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: org.junit.jupiter:junit-jupiter-engine dependency-type: direct:development update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: io.avaje:avaje-json-core dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies ... Signed-off-by: dependabot[bot] --- aws-cognito/http-client-authtoken/pom.xml | 4 ++-- htmx-nima-jstache/pom.xml | 4 ++-- http-client/pom.xml | 8 ++++---- http-inject-plugin/pom.xml | 2 +- pom.xml | 2 +- tests/pom.xml | 12 ++++++------ tests/test-client-generation/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 4 ++-- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 12 ++++++------ tests/test-nima-htmx/pom.xml | 6 +++--- tests/test-nima-jsonb/pom.xml | 12 ++++++------ tests/test-nima/pom.xml | 2 +- tests/test-sigma/pom.xml | 8 ++++---- 14 files changed, 40 insertions(+), 40 deletions(-) diff --git a/aws-cognito/http-client-authtoken/pom.xml b/aws-cognito/http-client-authtoken/pom.xml index b302d2fc7..bfa7581d0 100644 --- a/aws-cognito/http-client-authtoken/pom.xml +++ b/aws-cognito/http-client-authtoken/pom.xml @@ -23,14 +23,14 @@ io.avaje avaje-json-core - 3.0 + 3.1 io.avaje avaje-json-node - 3.0 + 3.1 test diff --git a/htmx-nima-jstache/pom.xml b/htmx-nima-jstache/pom.xml index 657d488e6..26f13a3eb 100644 --- a/htmx-nima-jstache/pom.xml +++ b/htmx-nima-jstache/pom.xml @@ -17,7 +17,7 @@ 21 UTF-8 false - 1.3.6 + 1.3.7 @@ -39,7 +39,7 @@ io.avaje avaje-inject - 11.2 + 11.3 provided true diff --git a/http-client/pom.xml b/http-client/pom.xml index 0880a3002..21664d2d6 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -36,21 +36,21 @@ io.avaje avaje-jsonb - 3.0 + 3.1 true io.avaje avaje-json-node - 3.0 + 3.1 test io.avaje avaje-inject - 11.2 + 11.3 true @@ -106,7 +106,7 @@ io.avaje avaje-inject-generator - 11.2 + 11.3 diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index 5b74bc795..4a5ca0cf0 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -19,7 +19,7 @@ io.avaje avaje-inject - 11.2 + 11.3 provided true diff --git a/pom.xml b/pom.xml index aeab3cfed..f212cb35f 100644 --- a/pom.xml +++ b/pom.xml @@ -22,7 +22,7 @@ 2.2.29 2.14.2 3.0-RC10 - 1.39 + 1.40 2025-03-10T00:18:35Z ${project.build.directory}${file.separator}module-info.shade diff --git a/tests/pom.xml b/tests/pom.xml index 7f81efd89..4e9762dda 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -12,11 +12,11 @@ true - 5.12.0 + 5.12.1 3.27.3 2.18.3 - 3.0-RC21 - 11.2 + 3.0-RC22 + 11.3 4.2.0 6.5.0 @@ -48,19 +48,19 @@ io.avaje avaje-validator - 2.8 + 2.9 io.avaje avaje-validator-constraints - 2.8 + 2.9 io.avaje avaje-validator-generator - 2.8 + 2.9 diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index 59000c5f1..3e335b634 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -141,7 +141,7 @@ io.avaje avaje-inject-maven-plugin - 11.2 + 11.3 process-sources diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index f5adbc191..b176280c1 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -74,13 +74,13 @@ io.avaje avaje-jsonb - 3.0 + 3.1 io.avaje avaje-jsonb-generator - 3.0 + 3.1 provided diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 8a386c4bf..8d2c8d596 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -57,7 +57,7 @@ io.avaje avaje-validator - 2.8 + 2.9 diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 93948ff70..b23badff4 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -44,7 +44,7 @@ io.jstach jstachio - 1.3.6 + 1.3.7 @@ -74,7 +74,7 @@ io.avaje avaje-jsonb - 3.0 + 3.1 @@ -124,17 +124,17 @@ io.avaje avaje-jsonb-generator - 3.0 + 3.1 io.avaje avaje-validator-generator - 2.8 + 2.9 io.jstach jstachio-apt - 1.3.6 + 1.3.7 @@ -171,7 +171,7 @@ io.avaje avaje-inject-maven-plugin - 11.2 + 11.3 process-sources diff --git a/tests/test-nima-htmx/pom.xml b/tests/test-nima-htmx/pom.xml index 28b86efef..bd3f1b76c 100644 --- a/tests/test-nima-htmx/pom.xml +++ b/tests/test-nima-htmx/pom.xml @@ -15,7 +15,7 @@ 21 UTF-8 false - 1.3.6 + 1.3.7 @@ -88,7 +88,7 @@ io.avaje avaje-jsonb-generator - 3.0 + 3.1 io.jstach @@ -103,7 +103,7 @@ io.avaje avaje-inject-maven-plugin - 11.2 + 11.3 process-sources diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 6c6961d3e..0c81fe31b 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -31,7 +31,7 @@ io.avaje avaje-jsonb - 3.0 + 3.1 io.helidon.webserver @@ -52,7 +52,7 @@ io.jstach jstachio - 1.3.6 + 1.3.7 @@ -91,17 +91,17 @@ io.avaje avaje-jsonb-generator - 3.0 + 3.1 io.avaje avaje-validator-generator - 2.8 + 2.9 io.jstach jstachio-apt - 1.3.6 + 1.3.7 @@ -120,7 +120,7 @@ io.avaje avaje-inject-maven-plugin - 11.2 + 11.3 process-sources diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index 26910f4fe..29faefa23 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -90,7 +90,7 @@ io.avaje avaje-inject-maven-plugin - 11.2 + 11.3 process-sources diff --git a/tests/test-sigma/pom.xml b/tests/test-sigma/pom.xml index 9288857cd..1819b88a1 100644 --- a/tests/test-sigma/pom.xml +++ b/tests/test-sigma/pom.xml @@ -53,7 +53,7 @@ io.jstach jstachio - 1.3.6 + 1.3.7 @@ -62,7 +62,7 @@ io.jstach jstachio-apt - 1.3.6 + 1.3.7 @@ -82,12 +82,12 @@ io.avaje avaje-jsonb - 3.0 + 3.1 io.avaje avaje-jsonb-generator - 3.0 + 3.1 provided From 598a67958c17cd5675925bf5996abdfceddb694a Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 18 Mar 2025 07:56:05 +1300 Subject: [PATCH 1266/1323] Format only --- .../avaje/http/generator/jex/JexAdapter.java | 26 +++++++++---------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/JexAdapter.java b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/JexAdapter.java index de0b6f8eb..531365e01 100644 --- a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/JexAdapter.java +++ b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/JexAdapter.java @@ -33,7 +33,6 @@ public boolean isBodyMethodParam() { @Override public String bodyAsClass(UType type) { - if ("java.io.InputStream".equals(type.full())) { return "ctx.bodyAsInputStream()"; } else if ("java.lang.String".equals(type.full())) { @@ -64,28 +63,27 @@ public static String writeJsonbType(UType type) { writeType(type.paramRaw(), writer); writer.append(".map()"); break; - default: - { - if (type.mainType().contains("java.util")) { - throw new UnsupportedOperationException( - "Only java.util Map, Set and List are supported JsonB Controller Collection Types"); - } - writeType(type, writer); + default: { + if (type.mainType().contains("java.util")) { + throw new UnsupportedOperationException( + "Only java.util Map, Set and List are supported JsonB Controller Collection Types"); } + writeType(type, writer); + } } return writer.toString(); } static void writeType(UType type, StringBuilder writer) { final var params = - type.params().stream() - .map(Util::shortName) - .map(s -> "?".equals(s) ? "Object" : s) - .collect(Collectors.joining(".class, ")); + type.params().stream() + .map(Util::shortName) + .map(s -> "?".equals(s) ? "Object" : s) + .collect(Collectors.joining(".class, ")); writer.append( - "Types.newParameterizedType(%s.class, %s.class)" - .formatted(Util.shortName(type.mainType()), params)); + "Types.newParameterizedType(%s.class, %s.class)" + .formatted(Util.shortName(type.mainType()), params)); } @Override From a61aa589ac09afc20a94bcbff42adcd17611b222 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Wed, 19 Mar 2025 07:53:58 +1300 Subject: [PATCH 1267/1323] Version 3.1 --- aws-cognito/http-client-authtoken/pom.xml | 2 +- htmx-api/pom.xml | 2 +- htmx-nima-jstache/pom.xml | 2 +- htmx-nima/pom.xml | 4 +- http-api-javalin/pom.xml | 2 +- http-api/pom.xml | 2 +- http-client-gson-adapter/pom.xml | 4 +- http-client-moshi-adapter/pom.xml | 4 +- http-client/pom.xml | 2 +- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 2 +- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-generator-sigma/pom.xml | 2 +- http-inject-plugin/pom.xml | 2 +- pom.xml | 4 +- tests/pom.xml | 2 +- tests/test-client-generation/pom.xml | 2 +- tests/test-client/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- .../src/main/resources/public/openapi.json | 22 +++++- tests/test-nima-htmx/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- tests/test-sigma/pom.xml | 2 +- .../src/main/resources/public/openapi.json | 79 +++++++++++++++++-- 29 files changed, 125 insertions(+), 38 deletions(-) diff --git a/aws-cognito/http-client-authtoken/pom.xml b/aws-cognito/http-client-authtoken/pom.xml index bfa7581d0..c6411eb2d 100644 --- a/aws-cognito/http-client-authtoken/pom.xml +++ b/aws-cognito/http-client-authtoken/pom.xml @@ -17,7 +17,7 @@ io.avaje avaje-http-client - 3.1-RC2 + 3.1 diff --git a/htmx-api/pom.xml b/htmx-api/pom.xml index e23b8fb4e..c98c3784a 100644 --- a/htmx-api/pom.xml +++ b/htmx-api/pom.xml @@ -6,7 +6,7 @@ io.avaje avaje-http-parent - 3.1-RC2 + 3.1 avaje-htmx-api diff --git a/htmx-nima-jstache/pom.xml b/htmx-nima-jstache/pom.xml index 26f13a3eb..1a9dc0b53 100644 --- a/htmx-nima-jstache/pom.xml +++ b/htmx-nima-jstache/pom.xml @@ -6,7 +6,7 @@ io.avaje avaje-http-parent - 3.1-RC2 + 3.1 avaje-htmx-nima-jstache diff --git a/htmx-nima/pom.xml b/htmx-nima/pom.xml index 4d052de8a..449b7f7ac 100644 --- a/htmx-nima/pom.xml +++ b/htmx-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje avaje-http-parent - 3.1-RC2 + 3.1 avaje-htmx-nima @@ -21,7 +21,7 @@ io.avaje avaje-htmx-api - 3.1-RC2 + 3.1 io.helidon.webserver diff --git a/http-api-javalin/pom.xml b/http-api-javalin/pom.xml index 6fb8acfd6..14160d3f9 100644 --- a/http-api-javalin/pom.xml +++ b/http-api-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.1-RC2 + 3.1 .. diff --git a/http-api/pom.xml b/http-api/pom.xml index 0b325f4f4..b77407ef3 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.1-RC2 + 3.1 .. diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index 1b080ffb9..a6091c561 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.1-RC2 + 3.1 avaje-http-client-gson @@ -20,7 +20,7 @@ io.avaje avaje-http-client - 3.1-RC2 + 3.1 provided diff --git a/http-client-moshi-adapter/pom.xml b/http-client-moshi-adapter/pom.xml index 1bd8517f7..0db7d6d70 100644 --- a/http-client-moshi-adapter/pom.xml +++ b/http-client-moshi-adapter/pom.xml @@ -3,7 +3,7 @@ io.avaje avaje-http-parent - 3.1-RC2 + 3.1 avaje-http-client-moshi @@ -19,7 +19,7 @@ io.avaje avaje-http-client - 3.1-RC2 + 3.1 provided diff --git a/http-client/pom.xml b/http-client/pom.xml index 21664d2d6..486ef988b 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.1-RC2 + 3.1 avaje-http-client diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index a4da79a85..66b904d71 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.1-RC2 + 3.1 avaje-http-client-generator diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 21625762c..b4fd94ea6 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.1-RC2 + 3.1 avaje-http-generator-core diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index 2759aafd6..770f3353b 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 3.1-RC2 + 3.1 avaje-http-helidon-generator diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index 2e916703f..36bd76609 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.1-RC2 + 3.1 avaje-http-javalin-generator diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index 216b84c46..ae8b361a3 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.1-RC2 + 3.1 avaje-http-jex-generator diff --git a/http-generator-sigma/pom.xml b/http-generator-sigma/pom.xml index 81ed67d83..e0707617a 100644 --- a/http-generator-sigma/pom.xml +++ b/http-generator-sigma/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.1-RC2 + 3.1 avaje-http-sigma-generator diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index 4a5ca0cf0..9f7119603 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.1-RC2 + 3.1 .. diff --git a/pom.xml b/pom.xml index f212cb35f..0878f9095 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-parent - 3.1-RC2 + 3.1 pom @@ -23,7 +23,7 @@ 2.14.2 3.0-RC10 1.40 - 2025-03-10T00:18:35Z + 2025-03-18T18:53:23Z ${project.build.directory}${file.separator}module-info.shade diff --git a/tests/pom.xml b/tests/pom.xml index 4e9762dda..f93775f92 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 3.1-RC2 + 3.1 tests diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index 3e335b634..5693387ba 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 3.1-RC2 + 3.1 test-client-generation diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index e3279a902..165a8d9b1 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 3.1-RC2 + 3.1 test-client diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index b176280c1..834489065 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 3.1-RC2 + 3.1 test-javalin-jsonb diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 8d2c8d596..e1157c0b6 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 3.1-RC2 + 3.1 test-javalin diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index b23badff4..b21b3fe21 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 3.1-RC2 + 3.1 test-jex diff --git a/tests/test-jex/src/main/resources/public/openapi.json b/tests/test-jex/src/main/resources/public/openapi.json index 6ce043677..e31f0de26 100644 --- a/tests/test-jex/src/main/resources/public/openapi.json +++ b/tests/test-jex/src/main/resources/public/openapi.json @@ -1587,10 +1587,20 @@ } }, "Long>" : { - "type" : "object" + "type" : "object", + "properties" : { + "value" : { + "$ref" : "#/components/schemas/T" + } + } }, "NestedEnum>" : { - "type" : "object" + "type" : "object", + "properties" : { + "value" : { + "$ref" : "#/components/schemas/T" + } + } }, "Person" : { "type" : "object", @@ -1605,6 +1615,14 @@ } }, "String>" : { + "type" : "object", + "properties" : { + "value" : { + "$ref" : "#/components/schemas/T" + } + } + }, + "T" : { "type" : "object" }, "ViewHome" : { diff --git a/tests/test-nima-htmx/pom.xml b/tests/test-nima-htmx/pom.xml index bd3f1b76c..7909fc3fc 100644 --- a/tests/test-nima-htmx/pom.xml +++ b/tests/test-nima-htmx/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 3.1-RC2 + 3.1 test-nima-htmx diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 0c81fe31b..1c66d0365 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 3.1-RC2 + 3.1 test-nima-jsonb diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index 29faefa23..cad255353 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 3.1-RC2 + 3.1 test-nima diff --git a/tests/test-sigma/pom.xml b/tests/test-sigma/pom.xml index 1819b88a1..ebe1124c6 100644 --- a/tests/test-sigma/pom.xml +++ b/tests/test-sigma/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 3.1-RC2 + 3.1 test-sigma diff --git a/tests/test-sigma/src/main/resources/public/openapi.json b/tests/test-sigma/src/main/resources/public/openapi.json index 37b95ebb9..782c1c405 100644 --- a/tests/test-sigma/src/main/resources/public/openapi.json +++ b/tests/test-sigma/src/main/resources/public/openapi.json @@ -928,6 +928,48 @@ } } }, + "/jstache/hello" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/HelloWorldZeroDependency" + } + } + } + } + } + } + }, + "/jstache/helloRuntime" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/HelloWorld" + } + } + } + } + } + } + }, "/openapi/get" : { "get" : { "tags" : [ @@ -2006,6 +2048,34 @@ } } }, + "HelloWorld" : { + "type" : "object", + "properties" : { + "message" : { + "type" : "string" + }, + "people" : { + "type" : "array", + "items" : { + "$ref" : "#/components/schemas/Person" + } + } + } + }, + "HelloWorldZeroDependency" : { + "type" : "object", + "properties" : { + "message" : { + "type" : "string" + }, + "people" : { + "type" : "array", + "items" : { + "$ref" : "#/components/schemas/Person" + } + } + } + }, "MyForm" : { "type" : "object", "properties" : { @@ -2023,13 +2093,12 @@ "Person" : { "type" : "object", "properties" : { - "id" : { - "type" : "integer", - "format" : "int64", - "nullable" : false - }, "name" : { "type" : "string" + }, + "birthday" : { + "type" : "string", + "format" : "date" } } } From 0aaa1c8bfacc8b16ca8d1ce4d839227bb203bc8b Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Fri, 21 Mar 2025 00:45:15 -0400 Subject: [PATCH 1268/1323] Add compiler error for GET json bodies (#581) * Add compiler error for GET bodies --- .../io/avaje/http/generator/core/MethodReader.java | 13 +++++++++++-- .../org/example/myapp/web/test/TestController2.java | 4 ++-- .../src/main/java/org/example/TestController.java | 2 +- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java index 8215b71d3..5243eb67c 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java @@ -60,7 +60,7 @@ public class MethodReader { this.bean = bean; this.element = element; this.actualExecutable = actualExecutable; - this.actualParams = (actualExecutable == null) ? null : actualExecutable.getParameterTypes(); + this.actualParams = actualExecutable == null ? null : actualExecutable.getParameterTypes(); this.isVoid = element.getReturnType().getKind() == TypeKind.VOID; this.methodRoles = Util.findRoles(element); this.producesAnnotation = @@ -327,7 +327,7 @@ void read() { } // non-path parameters default to form or query parameters based on the // existence of @Form annotation on the method - final ParamType defaultParamType = (formMarker) ? ParamType.FORMPARAM : ParamType.QUERYPARAM; + final ParamType defaultParamType = formMarker ? ParamType.FORMPARAM : ParamType.QUERYPARAM; final List parameters = element.getParameters(); for (int i = 0; i < parameters.size(); i++) { @@ -342,6 +342,15 @@ void read() { final UType type = Util.parse(typeMirror.toString()); final MethodParam param = new MethodParam(p, type, rawType, defaultParamType, formMarker); params.add(param); + + if (CoreWebMethod.GET.equals(webMethod) + && param.isBody() + && !"java.util.Map".equals(param.utype().mainType()) + && !"ClientPlatformAdapter" + .equals(ProcessingContext.platform().getClass().getSimpleName())) { + logError(p, "Missing @BeanParam annotation"); + } + param.addImports(bean); } } diff --git a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController2.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController2.java index 0ae288653..a6d48fe85 100644 --- a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController2.java +++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/TestController2.java @@ -49,13 +49,13 @@ String mapTest(Map> strings) { return strings.toString(); } - @Get("/inputStream") + @Post("/inputStream") @Consumes("application/bson") String stream(InputStream stream) { return stream.toString(); } - @Get("/byteArray") + @Post("/byteArray") String bytes(byte[] array) { return array.toString(); } diff --git a/tests/test-nima-jsonb/src/main/java/org/example/TestController.java b/tests/test-nima-jsonb/src/main/java/org/example/TestController.java index d3f0ceef6..bbb0db331 100644 --- a/tests/test-nima-jsonb/src/main/java/org/example/TestController.java +++ b/tests/test-nima-jsonb/src/main/java/org/example/TestController.java @@ -81,7 +81,7 @@ String enumQueryImplied(String s, @QueryParam ServerType type) { } @InstrumentServerContext - @Get(value = "/inputStream") + @Post(value = "/inputStream") InputStream stream(InputStream stream) throws Exception { return stream; } From 886785d87c8d28df5a6c870d50486fa9996f9835 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Fri, 21 Mar 2025 21:28:31 +1300 Subject: [PATCH 1269/1323] [helidon generation] Improve generated code extracting queryParams variable --- .../helidon/nima/ControllerMethodWriter.java | 7 +++++++ .../helidon/nima/NimaPlatformAdapter.java | 16 +++++++--------- .../src/main/resources/public/openapi.json | 8 ++++---- .../main/java/org/example/HelloController.java | 3 ++- 4 files changed, 20 insertions(+), 14 deletions(-) diff --git a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java index a89aa596a..9c3af5d67 100644 --- a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java +++ b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java @@ -184,6 +184,9 @@ void writeHandler(boolean requestScoped) { for (final PathSegments.Segment matrixSegment : segments.matrixSegments()) { matrixSegment.writeCreateSegment(writer, platform()); } + if (usesQueryParams()) { + writer.append(" var queryParams = req.query();").eol(); + } final var params = method.params(); for (final MethodParam param : params) { if (!isExceptionOrFilterChain(param)) { @@ -371,6 +374,10 @@ private boolean usesFormParams() { return method.params().stream().anyMatch(p -> p.isForm() || ParamType.FORMPARAM.equals(p.paramType())); } + private boolean usesQueryParams() { + return method.params().stream().anyMatch(p -> ParamType.QUERYPARAM.equals(p.paramType())); + } + private void writeContextReturn(String indent) { final var producesOp = Optional.ofNullable(method.produces()); if (producesOp.isEmpty() && !useJsonB && !useJstachio) { diff --git a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/NimaPlatformAdapter.java b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/NimaPlatformAdapter.java index 8f73b0bde..a33ce1dfa 100644 --- a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/NimaPlatformAdapter.java +++ b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/NimaPlatformAdapter.java @@ -71,12 +71,11 @@ public void writeReadParameter(Append writer, ParamType paramType, String paramN switch (paramType) { case PATHPARAM -> writer.append("pathParams.contains(\"%s\") ? pathParams.get(\"%s\") : null", paramName, paramName); - case QUERYPARAM -> writer.append("req.query().contains(\"%s\") ? req.query().get(\"%s\") : null", paramName, paramName); + case QUERYPARAM -> writer.append("queryParams.contains(\"%s\") ? queryParams.get(\"%s\") : null", paramName, paramName); case FORMPARAM -> writer.append("formParams.contains(\"%s\") ? formParams.get(\"%s\") : null", paramName, paramName); - case HEADER -> writer.append( - "req.headers().value(HeaderNames.create(\"%s\")).orElse(null)", paramName); + case HEADER -> writer.append("req.headers().value(HeaderNames.create(\"%s\")).orElse(null)", paramName); case COOKIE -> writer.append("req.headers().cookies().contains(\"%s\") ? req.headers().cookies().get(\"%s\") : null", paramName, paramName); @@ -91,7 +90,7 @@ public void writeReadParameter(Append writer, ParamType paramType, String paramN "pathParams.contains(\"%s\") ? pathParams.get(\"%s\") : \"%s\"", paramName, paramName, paramDefault); case QUERYPARAM -> writer.append( - "req.query().contains(\"%s\") ? req.query().get(\"%s\") : \"%s\"", paramName, paramName, paramDefault); + "queryParams.contains(\"%s\") ? queryParams.get(\"%s\") : \"%s\"", paramName, paramName, paramDefault); case FORMPARAM -> writer.append( "formParams.contains(\"%s\") ? formParams.get(\"%s\") : \"%s\"", paramName, paramName, paramDefault); @@ -109,18 +108,17 @@ public void writeReadParameter(Append writer, ParamType paramType, String paramN @Override public void writeReadMapParameter(Append writer, ParamType paramType) { switch (paramType) { - case QUERYPARAM -> writer.append("req.query().toMap()"); + case QUERYPARAM -> writer.append("queryParams.toMap()"); case FORM, FORMPARAM -> writer.append("formParams.toMap()"); case COOKIE -> writer.append("req.headers().cookies().toMap()"); - default -> throw new UnsupportedOperationException( - "Only Form/Query/Cookie Multi-Value Maps are supported"); + default -> throw new UnsupportedOperationException("Only Form/Query/Cookie Multi-Value Maps are supported"); } } @Override public void writeReadCollectionParameter(Append writer, ParamType paramType, String paramName) { switch (paramType) { - case QUERYPARAM -> writer.append("req.query().all(\"%s\")", paramName); + case QUERYPARAM -> writer.append("queryParams.all(\"%s\")", paramName); case FORMPARAM -> writer.append("formParams.all(\"%s\")", paramName); case HEADER -> writer.append( @@ -139,7 +137,7 @@ public void writeReadCollectionParameter( Append writer, ParamType paramType, String paramName, List paramDefault) { switch (paramType) { case QUERYPARAM -> writer.append( - "req.query().all(\"%s\", () -> java.util.List.of(\"%s\"))", + "queryParams.all(\"%s\", () -> java.util.List.of(\"%s\"))", paramName, String.join(",", paramDefault)); case FORMPARAM -> writer.append( diff --git a/tests/test-javalin-jsonb/src/main/resources/public/openapi.json b/tests/test-javalin-jsonb/src/main/resources/public/openapi.json index 4ce0e1d13..ff593dbf5 100644 --- a/tests/test-javalin-jsonb/src/main/resources/public/openapi.json +++ b/tests/test-javalin-jsonb/src/main/resources/public/openapi.json @@ -1268,7 +1268,7 @@ } }, "/test/byteArray" : { - "get" : { + "post" : { "tags" : [ ], @@ -1286,7 +1286,7 @@ "required" : true }, "responses" : { - "200" : { + "201" : { "description" : "", "content" : { "application/json" : { @@ -1730,7 +1730,7 @@ } }, "/test/inputStream" : { - "get" : { + "post" : { "tags" : [ ], @@ -1748,7 +1748,7 @@ "required" : true }, "responses" : { - "200" : { + "201" : { "description" : "", "content" : { "application/json" : { diff --git a/tests/test-nima/src/main/java/org/example/HelloController.java b/tests/test-nima/src/main/java/org/example/HelloController.java index 88df46723..958cff466 100644 --- a/tests/test-nima/src/main/java/org/example/HelloController.java +++ b/tests/test-nima/src/main/java/org/example/HelloController.java @@ -1,6 +1,7 @@ package org.example; import io.avaje.http.api.Controller; +import io.avaje.http.api.Default; import io.avaje.http.api.Get; import io.avaje.http.api.Produces; @@ -23,7 +24,7 @@ Person person(String name, String sortBy) { @Roles({AppRoles.ADMIN, AppRoles.BASIC_USER}) @Produces("text/plain") @Get("other/{name}") - String name(String name) { + String name(String name, String sortBy, @Default("0") long max) { return "hi " + name; } } From 48ba7189cd64c8f413b2414f88c2f74a942c8d21 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Sat, 22 Mar 2025 02:18:31 +1300 Subject: [PATCH 1270/1323] Improve the compile error message when we think @BeanParam is needed (#582) --- .../http/generator/core/MethodReader.java | 18 ++++++++---- .../helidon/nima/ControllerMethodWriter.java | 4 ++- tests/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 6 ++-- tests/test-nima/pom.xml | 28 +++---------------- .../java/org/example/HelloController.java | 6 ++++ 6 files changed, 29 insertions(+), 35 deletions(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java index 5243eb67c..c7ab7acf8 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java @@ -5,6 +5,7 @@ import static io.avaje.http.generator.core.ProcessingContext.platform; import static io.avaje.http.generator.core.ProcessingContext.superMethods; +import java.text.MessageFormat; import java.util.*; import java.util.function.Consumer; import java.util.function.Function; @@ -343,18 +344,23 @@ void read() { final MethodParam param = new MethodParam(p, type, rawType, defaultParamType, formMarker); params.add(param); - if (CoreWebMethod.GET.equals(webMethod) - && param.isBody() - && !"java.util.Map".equals(param.utype().mainType()) - && !"ClientPlatformAdapter" - .equals(ProcessingContext.platform().getClass().getSimpleName())) { - logError(p, "Missing @BeanParam annotation"); + if (CoreWebMethod.GET.equals(webMethod) && isBodyParam(param)) { + logError(p, MessageFormat.format("Unsure how to populate {0} parameter for this @Get request. " + + "Perhaps it should be a @Post instead? or otherwise add @BeanParam to {0} to populate it from path parameters.", + param.name())); } param.addImports(bean); } } + private static boolean isBodyParam(MethodParam param) { + return param.isBody() + && !"java.util.Map".equals(param.utype().mainType()) + && !"ClientPlatformAdapter" + .equals(ProcessingContext.platform().getClass().getSimpleName()); + } + public void buildApiDoc() { buildApiDocumentation(); } diff --git a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java index 9c3af5d67..94343488c 100644 --- a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java +++ b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java @@ -375,7 +375,9 @@ private boolean usesFormParams() { } private boolean usesQueryParams() { - return method.params().stream().anyMatch(p -> ParamType.QUERYPARAM.equals(p.paramType())); + return method.params().stream().anyMatch(p -> + ParamType.QUERYPARAM.equals(p.paramType()) + || ParamType.BEANPARAM.equals(p.paramType())); } private void writeContextReturn(String indent) { diff --git a/tests/pom.xml b/tests/pom.xml index f93775f92..270730afb 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -17,7 +17,7 @@ 2.18.3 3.0-RC22 11.3 - 4.2.0 + 4.2.0 6.5.0 diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 1c66d0365..0216d126a 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -36,12 +36,12 @@ io.helidon.webserver helidon-webserver - ${nima.version} + ${helidon.version} io.helidon.http.media helidon-http-media-jsonb - ${nima.version} + ${helidon.version} io.avaje @@ -54,7 +54,7 @@ jstachio 1.3.7 - + io.avaje junit diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index cad255353..7e5a5ffc4 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -31,23 +31,17 @@ io.helidon.webserver helidon-webserver - ${nima.version} + ${helidon.version} io.helidon.webserver helidon-webserver-security - ${nima.version} + ${helidon.version} io.helidon.http.media helidon-http-media-jsonb - ${nima.version} - - - io.avaje - avaje-http-helidon-generator - ${project.version} - test + ${helidon.version} @@ -58,7 +52,6 @@ maven-compiler-plugin 3.14.0 - 21 io.avaje @@ -71,22 +64,9 @@ ${avaje-inject.version} - 21 - 21 - - io.repaint.maven - tiles-maven-plugin - 2.40 - true - - - org.avaje.tile:lib-classpath:1.1 - - - - + io.avaje avaje-inject-maven-plugin diff --git a/tests/test-nima/src/main/java/org/example/HelloController.java b/tests/test-nima/src/main/java/org/example/HelloController.java index 958cff466..ae147fc9a 100644 --- a/tests/test-nima/src/main/java/org/example/HelloController.java +++ b/tests/test-nima/src/main/java/org/example/HelloController.java @@ -1,5 +1,6 @@ package org.example; +import io.avaje.http.api.BeanParam; import io.avaje.http.api.Controller; import io.avaje.http.api.Default; import io.avaje.http.api.Get; @@ -27,4 +28,9 @@ Person person(String name, String sortBy) { String name(String name, String sortBy, @Default("0") long max) { return "hi " + name; } + + @Get("banana") + Person getP(@BeanParam Person person) { + return person; + } } From 32b159aeed236bd3349cd12b6da57441ad9483d9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 24 Mar 2025 20:51:15 +0000 Subject: [PATCH 1271/1323] Bump the dependencies group with 9 updates Bumps the dependencies group with 9 updates: | Package | From | To | | --- | --- | --- | | [io.avaje:avaje-jsonb](https://github.com/avaje/avaje-jsonb) | `3.1` | `3.2` | | io.avaje:avaje-json-node | `3.1` | `3.2` | | io.avaje:avaje-jsonb-generator | `3.1` | `3.2` | | [io.avaje:avaje-jex](https://github.com/avaje/avaje-jex) | `3.0-RC22` | `3.0-RC23` | | io.avaje:avaje-jex-htmx | `3.0-RC22` | `3.0-RC23` | | io.avaje:avaje-nima | `1.1` | `1.2` | | io.avaje:avaje-nima-test | `1.1` | `1.2` | | [ch.qos.logback:logback-classic](https://github.com/qos-ch/logback) | `1.5.17` | `1.5.18` | | io.avaje:avaje-json-core | `3.1` | `3.2` | Updates `io.avaje:avaje-jsonb` from 3.1 to 3.2 - [Release notes](https://github.com/avaje/avaje-jsonb/releases) - [Commits](https://github.com/avaje/avaje-jsonb/compare/3.1...3.2) Updates `io.avaje:avaje-json-node` from 3.1 to 3.2 Updates `io.avaje:avaje-jsonb-generator` from 3.1 to 3.2 Updates `io.avaje:avaje-jex` from 3.0-RC22 to 3.0-RC23 - [Release notes](https://github.com/avaje/avaje-jex/releases) - [Commits](https://github.com/avaje/avaje-jex/commits) Updates `io.avaje:avaje-jex-htmx` from 3.0-RC22 to 3.0-RC23 Updates `io.avaje:avaje-jex-htmx` from 3.0-RC22 to 3.0-RC23 Updates `io.avaje:avaje-nima` from 1.1 to 1.2 Updates `io.avaje:avaje-nima-test` from 1.1 to 1.2 Updates `ch.qos.logback:logback-classic` from 1.5.17 to 1.5.18 - [Release notes](https://github.com/qos-ch/logback/releases) - [Commits](https://github.com/qos-ch/logback/compare/v_1.5.17...v_1.5.18) Updates `io.avaje:avaje-json-core` from 3.1 to 3.2 --- updated-dependencies: - dependency-name: io.avaje:avaje-jsonb dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.avaje:avaje-json-node dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.avaje:avaje-jsonb-generator dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.avaje:avaje-jex dependency-type: direct:development dependency-group: dependencies - dependency-name: io.avaje:avaje-jex-htmx dependency-type: direct:production dependency-group: dependencies - dependency-name: io.avaje:avaje-jex-htmx dependency-type: direct:production dependency-group: dependencies - dependency-name: io.avaje:avaje-nima dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.avaje:avaje-nima-test dependency-type: direct:development update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: ch.qos.logback:logback-classic dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: io.avaje:avaje-json-core dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies ... Signed-off-by: dependabot[bot] --- aws-cognito/http-client-authtoken/pom.xml | 4 ++-- http-client/pom.xml | 4 ++-- tests/pom.xml | 2 +- tests/test-client-generation/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 4 ++-- tests/test-jex/pom.xml | 4 ++-- tests/test-nima-htmx/pom.xml | 6 +++--- tests/test-nima-jsonb/pom.xml | 4 ++-- tests/test-sigma/pom.xml | 4 ++-- 9 files changed, 17 insertions(+), 17 deletions(-) diff --git a/aws-cognito/http-client-authtoken/pom.xml b/aws-cognito/http-client-authtoken/pom.xml index c6411eb2d..46f6c2c32 100644 --- a/aws-cognito/http-client-authtoken/pom.xml +++ b/aws-cognito/http-client-authtoken/pom.xml @@ -23,14 +23,14 @@ io.avaje avaje-json-core - 3.1 + 3.2 io.avaje avaje-json-node - 3.1 + 3.2 test diff --git a/http-client/pom.xml b/http-client/pom.xml index 486ef988b..ed59be493 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -36,14 +36,14 @@ io.avaje avaje-jsonb - 3.1 + 3.2 true io.avaje avaje-json-node - 3.1 + 3.2 test diff --git a/tests/pom.xml b/tests/pom.xml index 270730afb..678c06d5a 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -15,7 +15,7 @@ 5.12.1 3.27.3 2.18.3 - 3.0-RC22 + 3.0-RC23 11.3 4.2.0 6.5.0 diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index 5693387ba..acd63b899 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -26,7 +26,7 @@ ch.qos.logback logback-classic - 1.5.17 + 1.5.18 diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 834489065..4d818e407 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -74,13 +74,13 @@ io.avaje avaje-jsonb - 3.1 + 3.2 io.avaje avaje-jsonb-generator - 3.1 + 3.2 provided diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index b21b3fe21..0d1614eca 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -74,7 +74,7 @@ io.avaje avaje-jsonb - 3.1 + 3.2 @@ -124,7 +124,7 @@ io.avaje avaje-jsonb-generator - 3.1 + 3.2 io.avaje diff --git a/tests/test-nima-htmx/pom.xml b/tests/test-nima-htmx/pom.xml index 7909fc3fc..6db46e960 100644 --- a/tests/test-nima-htmx/pom.xml +++ b/tests/test-nima-htmx/pom.xml @@ -47,7 +47,7 @@ io.avaje avaje-nima - 1.1 + 1.2 @@ -60,7 +60,7 @@ io.avaje avaje-nima-test - 1.1 + 1.2 test @@ -88,7 +88,7 @@ io.avaje avaje-jsonb-generator - 3.1 + 3.2 io.jstach diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 0216d126a..7ce565138 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -31,7 +31,7 @@ io.avaje avaje-jsonb - 3.1 + 3.2 io.helidon.webserver @@ -91,7 +91,7 @@ io.avaje avaje-jsonb-generator - 3.1 + 3.2 io.avaje diff --git a/tests/test-sigma/pom.xml b/tests/test-sigma/pom.xml index ebe1124c6..50cb45a93 100644 --- a/tests/test-sigma/pom.xml +++ b/tests/test-sigma/pom.xml @@ -82,12 +82,12 @@ io.avaje avaje-jsonb - 3.1 + 3.2 io.avaje avaje-jsonb-generator - 3.1 + 3.2 provided From 50fe8acf7db02e25a8056c3ff171b8e561f2e429 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Tue, 25 Mar 2025 19:12:55 -0400 Subject: [PATCH 1272/1323] start --- .../http/generator/core/AnnotationCopier.java | 141 ++++++++++++++++++ .../http/generator/core/BaseProcessor.java | 8 + .../http/generator/core/PrimitiveUtil.java | 3 +- .../http/generator/core/TestClientWriter.java | 125 ++++++++++++++++ 4 files changed, 276 insertions(+), 1 deletion(-) create mode 100644 http-generator-core/src/main/java/io/avaje/http/generator/core/AnnotationCopier.java create mode 100644 http-generator-core/src/main/java/io/avaje/http/generator/core/TestClientWriter.java diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/AnnotationCopier.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/AnnotationCopier.java new file mode 100644 index 000000000..91e610cd7 --- /dev/null +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/AnnotationCopier.java @@ -0,0 +1,141 @@ +package io.avaje.http.generator.core; + +import static java.util.stream.Collectors.toList; + +import java.util.List; +import java.util.Map.Entry; +import java.util.regex.Pattern; + +import javax.lang.model.element.AnnotationMirror; +import javax.lang.model.element.AnnotationValue; +import javax.lang.model.element.Element; +import javax.lang.model.element.ExecutableElement; +import javax.lang.model.element.VariableElement; + +final class AnnotationCopier { + private AnnotationCopier() {} + + private static final Pattern ANNOTATION_TYPE_PATTERN = Pattern.compile("@([\\w.]+)\\."); + + static String trimAnnotationString(String input) { + return ANNOTATION_TYPE_PATTERN.matcher(input).replaceAll("@"); + } + + static void copyAnnotations(Append writer, Element element, boolean newLines) { + copyAnnotations(writer, element, "", newLines); + } + + static void copyAnnotations(Append writer, Element element, String indent, boolean newLines) { + for (final AnnotationMirror annotationMirror : element.getAnnotationMirrors()) { + final var type = annotationMirror.getAnnotationType().asElement().asType().toString(); + if (!type.contains("io.avaje.http.api.") + || type.contains("Produces") + || type.contains("Consumes")) { + continue; + } + + String annotationString = toAnnotationString(indent, annotationMirror, false); + + annotationString = + annotationString + .replace("io.avaje.http.api.", "") + .replace("value=", "") + .replace("(\"\")", ""); + + writer.append(annotationString); + + if (newLines) { + writer.eol(); + } else { + writer.append(" "); + } + } + } + + static String toSimpleAnnotationString(AnnotationMirror annotationMirror) { + return trimAnnotationString(toAnnotationString("", annotationMirror, true)).substring(1); + } + + static String toAnnotationString( + String indent, AnnotationMirror annotationMirror, boolean simpleEnums) { + final String annotationName = annotationMirror.getAnnotationType().toString(); + + final StringBuilder sb = + new StringBuilder(indent).append("@").append(annotationName).append("("); + boolean first = true; + + for (final var entry : sortedValues(annotationMirror)) { + if (!first) { + sb.append(", "); + } + sb.append(entry.getKey().getSimpleName()).append("="); + writeVal(sb, entry.getValue(), simpleEnums); + first = false; + } + + return sb.append(")").toString().replace("()", ""); + } + + private static List> sortedValues( + AnnotationMirror annotationMirror) { + return APContext.elements().getElementValuesWithDefaults(annotationMirror).entrySet().stream() + .sorted(AnnotationCopier::compareBySimpleName) + .collect(toList()); + } + + private static int compareBySimpleName( + Entry entry1, + Entry entry2) { + return entry1 + .getKey() + .getSimpleName() + .toString() + .compareTo(entry2.getKey().getSimpleName().toString()); + } + + @SuppressWarnings("unchecked") + private static void writeVal( + final StringBuilder sb, final AnnotationValue annotationValue, boolean simpleEnums) { + final var value = annotationValue.getValue(); + if (value instanceof List) { + // handle array values + sb.append("{"); + boolean first = true; + for (final AnnotationValue listValue : (List) value) { + if (!first) { + sb.append(", "); + } + writeVal(sb, listValue, simpleEnums); + first = false; + } + sb.append("}"); + + } else if (value instanceof VariableElement) { + // Handle enum values + final var element = (VariableElement) value; + final var type = element.asType(); + final var str = simpleEnums ? element : type.toString() + "." + element; + sb.append(str); + + } else if (value instanceof AnnotationMirror) { + // handle annotation values + final var mirror = (AnnotationMirror) value; + final String annotationName = mirror.getAnnotationType().toString(); + sb.append("@").append(annotationName).append("("); + boolean first = true; + + for (final var entry : sortedValues(mirror)) { + if (!first) { + sb.append(", "); + } + sb.append(entry.getKey().getSimpleName()).append("="); + writeVal(sb, entry.getValue(), simpleEnums); + first = false; + } + sb.append(")"); + + } else { + sb.append(annotationValue); + } + } +} diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java index fcbe548f6..0dbd26811 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java @@ -4,6 +4,7 @@ import static io.avaje.http.generator.core.ProcessingContext.elements; import static io.avaje.http.generator.core.ProcessingContext.isOpenApiAvailable; import static io.avaje.http.generator.core.ProcessingContext.logError; +import static io.avaje.http.generator.core.ProcessingContext.logWarn; import static io.avaje.http.generator.core.ProcessingContext.typeElement; import static java.util.stream.Collectors.toMap; @@ -132,6 +133,13 @@ private void writeAdapter(Element controller) { } catch (final Throwable e) { logError(reader.beanType(), "Failed to write $Route class " + e); } + try { + if (((TypeElement) controller).getInterfaces().isEmpty()) { + new TestClientWriter(reader).write(); + } + } catch (Exception e) { + logWarn(reader.beanType(), "Failed to write test class " + e); + } } } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/PrimitiveUtil.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/PrimitiveUtil.java index cd7815ae6..40160be0a 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/PrimitiveUtil.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/PrimitiveUtil.java @@ -15,7 +15,8 @@ private PrimitiveUtil() {} "short", "Short", "double", "Double", "float", "Float", - "boolean", "Boolean"); + "boolean", "Boolean", + "void", "Void"); public static String wrap(String shortName) { final var wrapped = wrapperMap.get(shortName); diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/TestClientWriter.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/TestClientWriter.java new file mode 100644 index 000000000..afbd8f4e8 --- /dev/null +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/TestClientWriter.java @@ -0,0 +1,125 @@ +package io.avaje.http.generator.core; + +import java.io.IOException; +import java.util.Set; +import java.util.TreeSet; + +import javax.lang.model.element.TypeElement; +import javax.lang.model.type.TypeMirror; + + +public class TestClientWriter { + + private static final String AT_GENERATED = "@Generated(\"avaje-http-generator\")"; + private final Set importTypes = new TreeSet<>(); + private final ControllerReader reader; + private String originName; + private String shortName; + private String packageName; + private String fullName; + private Append writer; + + TestClientWriter(ControllerReader reader) throws IOException { + + this.reader = reader; + final TypeElement origin = reader.beanType(); + this.originName = origin.getQualifiedName().toString(); + this.shortName = origin.getSimpleName().toString(); + this.packageName = initPackageName(originName); + this.fullName = packageName + "." + shortName + "$TestAPI"; + writer = new Append(APContext.createSourceFile(fullName, reader.beanType()).openWriter()); + } + + protected String initPackageName(String originName) { + final int dp = originName.lastIndexOf('.'); + return dp > -1 ? originName.substring(0, dp) : null; + } + + void write() { + writePackage(); + writeImports(); + writeClassStart(); + writeAddRoutes(); + } + + protected void writePackage() { + if (packageName != null) { + writer.append("package %s;", packageName).eol().eol(); + } + } + + protected void writeImports() { + importTypes.add("java.net.http.HttpResponse"); + + reader + .methods() + .forEach( + m -> { + importTypes.addAll(UType.parse(m.returnType()).importTypes()); + m.params() + .forEach( + p -> importTypes.addAll(UType.parse(p.element().asType()).importTypes())); + }); + + importTypes.addAll(reader.importTypes()); + + importTypes.removeIf( + i -> + i.startsWith("java.lang") + || PrimitiveUtil.wrapperMap.containsKey(i) + || i.contains(".") && i.substring(0, i.lastIndexOf(".")).equals(packageName)); + for (String type : importTypes) { + writer.append("import %s;", type).eol(); + } + writer.eol(); + } + + private void writeClassStart() { + writer.append(AT_GENERATED).eol(); + writer.append("@Client(\"%s\")", reader.path()).eol(); + writer.append("public interface %s$TestAPI {", shortName).eol().eol(); + } + + private void writeAddRoutes() { + + reader.methods().stream() + .filter(MethodReader::isWebMethod) + .filter( + m -> + m.webMethod() instanceof CoreWebMethod + && m.webMethod() != CoreWebMethod.ERROR + && m.webMethod() != CoreWebMethod.FILTER + && m.webMethod() != CoreWebMethod.OTHER) + .forEach(this::writeRoute); + + writer.append("}").eol(); + writer.close(); + } + + private void writeRoute(MethodReader method) { + TypeMirror returnType = method.returnType(); + var isJstache = ProcessingContext.isJstacheTemplate(returnType); + AnnotationCopier.copyAnnotations(writer, method.element(), true); + + var returnTypeStr = PrimitiveUtil.wrap(UType.parse(returnType).shortType()); + writer.append( + "HttpResponse<%s> %s(", isJstache ? "String" : returnTypeStr, method.simpleName()); + boolean first = true; + for (var param : method.params()) { + + if (first) { + first = false; + } else { + writer.append(", "); + } + var type = UType.parse(param.element().asType()); + + AnnotationCopier.copyAnnotations(writer, param.element(), false); + writer.append("%s %s", type.shortType(), param.name()); + } + writer.append(");"); + + writer.eol(); + writer.eol(); + } +} From 68a0984f684e0917d3af8e9983bdee2944989f3c Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Tue, 25 Mar 2025 19:57:13 -0400 Subject: [PATCH 1273/1323] initial --- .../http/generator/core/AnnotationCopier.java | 5 +- .../http/generator/core/BaseProcessor.java | 15 +++--- .../http/generator/core/TestClientWriter.java | 51 +++++++++++-------- 3 files changed, 41 insertions(+), 30 deletions(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/AnnotationCopier.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/AnnotationCopier.java index 91e610cd7..306769d90 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/AnnotationCopier.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/AnnotationCopier.java @@ -30,7 +30,10 @@ static void copyAnnotations(Append writer, Element element, String indent, boole final var type = annotationMirror.getAnnotationType().asElement().asType().toString(); if (!type.contains("io.avaje.http.api.") || type.contains("Produces") - || type.contains("Consumes")) { + || type.contains("Consumes") + || type.contains("InstrumentServerContext") + || type.contains("Default") + || type.contains("OpenAPI")) { continue; } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java index 0dbd26811..8e05bddb1 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java @@ -4,7 +4,6 @@ import static io.avaje.http.generator.core.ProcessingContext.elements; import static io.avaje.http.generator.core.ProcessingContext.isOpenApiAvailable; import static io.avaje.http.generator.core.ProcessingContext.logError; -import static io.avaje.http.generator.core.ProcessingContext.logWarn; import static io.avaje.http.generator.core.ProcessingContext.typeElement; import static java.util.stream.Collectors.toMap; @@ -129,16 +128,16 @@ private void writeAdapter(Element controller) { final var reader = new ControllerReader((TypeElement) controller, contextPath); reader.read(true); try { + writeControllerAdapter(reader); - } catch (final Throwable e) { - logError(reader.beanType(), "Failed to write $Route class " + e); - } - try { - if (((TypeElement) controller).getInterfaces().isEmpty()) { + TypeElement typeElement = (TypeElement) controller; + if (typeElement.getInterfaces().isEmpty() + && "java.lang.Object".equals(typeElement.getSuperclass().toString())) { new TestClientWriter(reader).write(); } - } catch (Exception e) { - logWarn(reader.beanType(), "Failed to write test class " + e); + + } catch (final Throwable e) { + logError(reader.beanType(), "Failed to write $Route class " + e); } } } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/TestClientWriter.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/TestClientWriter.java index afbd8f4e8..17f65b47c 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/TestClientWriter.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/TestClientWriter.java @@ -1,13 +1,15 @@ package io.avaje.http.generator.core; +import static java.util.stream.Collectors.toList; + import java.io.IOException; +import java.util.List; import java.util.Set; import java.util.TreeSet; import javax.lang.model.element.TypeElement; import javax.lang.model.type.TypeMirror; - public class TestClientWriter { private static final String AT_GENERATED = "@Generated(\"avaje-http-generator\")"; @@ -18,6 +20,7 @@ public class TestClientWriter { private String packageName; private String fullName; private Append writer; + private List methods; TestClientWriter(ControllerReader reader) throws IOException { @@ -27,6 +30,17 @@ public class TestClientWriter { this.shortName = origin.getSimpleName().toString(); this.packageName = initPackageName(originName); this.fullName = packageName + "." + shortName + "$TestAPI"; + this.methods = + reader.methods().stream() + .filter(MethodReader::isWebMethod) + .filter( + m -> + m.webMethod() instanceof CoreWebMethod + && m.webMethod() != CoreWebMethod.ERROR + && m.webMethod() != CoreWebMethod.FILTER + && m.webMethod() != CoreWebMethod.OTHER) + .collect(toList()); + if (methods.isEmpty()) return; writer = new Append(APContext.createSourceFile(fullName, reader.beanType()).openWriter()); } @@ -36,6 +50,7 @@ protected String initPackageName(String originName) { } void write() { + if (methods.isEmpty()) return; writePackage(); writeImports(); writeClassStart(); @@ -50,18 +65,14 @@ protected void writePackage() { protected void writeImports() { importTypes.add("java.net.http.HttpResponse"); + importTypes.add("io.avaje.http.api.*"); - reader - .methods() - .forEach( - m -> { - importTypes.addAll(UType.parse(m.returnType()).importTypes()); - m.params() - .forEach( - p -> importTypes.addAll(UType.parse(p.element().asType()).importTypes())); - }); - - importTypes.addAll(reader.importTypes()); + methods.forEach( + m -> { + importTypes.addAll(UType.parse(m.returnType()).importTypes()); + m.params() + .forEach(p -> importTypes.addAll(UType.parse(p.element().asType()).importTypes())); + }); importTypes.removeIf( i -> @@ -82,15 +93,7 @@ private void writeClassStart() { private void writeAddRoutes() { - reader.methods().stream() - .filter(MethodReader::isWebMethod) - .filter( - m -> - m.webMethod() instanceof CoreWebMethod - && m.webMethod() != CoreWebMethod.ERROR - && m.webMethod() != CoreWebMethod.FILTER - && m.webMethod() != CoreWebMethod.OTHER) - .forEach(this::writeRoute); + methods.forEach(this::writeRoute); writer.append("}").eol(); writer.close(); @@ -102,6 +105,12 @@ private void writeRoute(MethodReader method) { AnnotationCopier.copyAnnotations(writer, method.element(), true); var returnTypeStr = PrimitiveUtil.wrap(UType.parse(returnType).shortType()); + + if (returnTypeStr.contains("CompletableFuture")) { + returnTypeStr = + returnTypeStr.substring(0, returnTypeStr.length() - 1).replace("CompletableFuture<", ""); + } + writer.append( "HttpResponse<%s> %s(", isJstache ? "String" : returnTypeStr, method.simpleName()); boolean first = true; From 33605fdc3927a787ff2f1cf8f94ac1c8d46b0749 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Tue, 25 Mar 2025 20:02:53 -0400 Subject: [PATCH 1274/1323] test compilation only --- .../main/java/io/avaje/http/generator/core/BaseProcessor.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java index 8e05bddb1..2c4788167 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java @@ -131,7 +131,8 @@ private void writeAdapter(Element controller) { writeControllerAdapter(reader); TypeElement typeElement = (TypeElement) controller; - if (typeElement.getInterfaces().isEmpty() + if (APContext.isTestCompilation() + && typeElement.getInterfaces().isEmpty() && "java.lang.Object".equals(typeElement.getSuperclass().toString())) { new TestClientWriter(reader).write(); } From fb4622877142c9db2894be4c8a4de2fd31f8ae5b Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Tue, 25 Mar 2025 21:11:37 -0400 Subject: [PATCH 1275/1323] Update BaseProcessor.java --- .../http/generator/core/BaseProcessor.java | 118 +++++++++++++----- 1 file changed, 86 insertions(+), 32 deletions(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java index 2c4788167..07d8d76f0 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java @@ -8,7 +8,10 @@ import static java.util.stream.Collectors.toMap; import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.StandardOpenOption; import java.util.HashMap; +import java.util.HashSet; import java.util.Map; import java.util.Map.Entry; import java.util.Set; @@ -27,13 +30,23 @@ @GenerateAPContext @GenerateModuleInfoReader -@SupportedOptions({"useJavax", "useSingleton", "instrumentRequests","disableDirectWrites","disableJsonB"}) +@SupportedOptions({ + "useJavax", + "useSingleton", + "instrumentRequests", + "disableDirectWrites", + "disableJsonB" +}) public abstract class BaseProcessor extends AbstractProcessor { + private static final String HTTP_CONTROLLERS_TXT = "controllers.txt"; + protected String contextPathString; protected Map packagePaths = new HashMap<>(); + private final Set controllerFQNs = new HashSet<>(); + @Override public SourceVersion getSupportedSourceVersion() { return SourceVersion.latest(); @@ -41,7 +54,8 @@ public SourceVersion getSupportedSourceVersion() { @Override public Set getSupportedAnnotationTypes() { - return Set.of(PathPrism.PRISM_TYPE, ControllerPrism.PRISM_TYPE, OpenAPIDefinitionPrism.PRISM_TYPE); + return Set.of( + PathPrism.PRISM_TYPE, ControllerPrism.PRISM_TYPE, OpenAPIDefinitionPrism.PRISM_TYPE); } @Override @@ -49,6 +63,21 @@ public synchronized void init(ProcessingEnvironment processingEnv) { super.init(processingEnv); APContext.init(processingEnv); ProcessingContext.init(processingEnv, providePlatformAdapter()); + + try { + var txtFilePath = APContext.getBuildResource(HTTP_CONTROLLERS_TXT); + + if (txtFilePath.toFile().exists()) { + Files.lines(txtFilePath).forEach(controllerFQNs::add); + } + if (APContext.isTestCompilation()) { + System.out.println("Trying to read: " + controllerFQNs + "from path:" + txtFilePath); + controllerFQNs.stream().map(APContext::typeElement).forEach(this::writeClientAdapter); + } + } catch (IOException e) { + e.printStackTrace(); + // not worth failing over + } } /** Provide the platform specific adapter to use for Javalin, Helidon etc. */ @@ -82,19 +111,34 @@ public boolean process(Set annotations, RoundEnvironment readSecuritySchemes(round); } - for (final Element controller : round.getElementsAnnotatedWith(typeElement(ControllerPrism.PRISM_TYPE))) { + for (final var controller : + ElementFilter.typesIn( + round.getElementsAnnotatedWith(typeElement(ControllerPrism.PRISM_TYPE)))) { writeAdapter(controller); } if (round.processingOver()) { writeOpenAPI(); ProcessingContext.validateModule(); + + if (!APContext.isTestCompilation()) { + try { + Files.write( + APContext.getBuildResource(HTTP_CONTROLLERS_TXT), + controllerFQNs, + StandardOpenOption.CREATE, + StandardOpenOption.WRITE); + } catch (IOException e) { + // not worth failing over + } + } } return false; } private void readOpenApiDefinition(RoundEnvironment round) { - for (final Element element : round.getElementsAnnotatedWith(typeElement(OpenAPIDefinitionPrism.PRISM_TYPE))) { + for (final Element element : + round.getElementsAnnotatedWith(typeElement(OpenAPIDefinitionPrism.PRISM_TYPE))) { doc().readApiDefinition(element); } } @@ -103,16 +147,19 @@ private void readTagDefinitions(RoundEnvironment round) { for (final Element element : round.getElementsAnnotatedWith(typeElement(TagPrism.PRISM_TYPE))) { doc().addTagDefinition(element); } - for (final Element element : round.getElementsAnnotatedWith(typeElement(TagsPrism.PRISM_TYPE))) { + for (final Element element : + round.getElementsAnnotatedWith(typeElement(TagsPrism.PRISM_TYPE))) { doc().addTagsDefinition(element); } } private void readSecuritySchemes(RoundEnvironment round) { - for (final Element element : round.getElementsAnnotatedWith(typeElement(SecuritySchemePrism.PRISM_TYPE))) { + for (final Element element : + round.getElementsAnnotatedWith(typeElement(SecuritySchemePrism.PRISM_TYPE))) { doc().addSecurityScheme(element); } - for (final Element element : round.getElementsAnnotatedWith(typeElement(SecuritySchemesPrism.PRISM_TYPE))) { + for (final Element element : + round.getElementsAnnotatedWith(typeElement(SecuritySchemesPrism.PRISM_TYPE))) { doc().addSecuritySchemes(element); } } @@ -121,39 +168,46 @@ private void writeOpenAPI() { doc().writeApi(); } - private void writeAdapter(Element controller) { - if (controller instanceof TypeElement) { - final var packageFQN = elements().getPackageOf(controller).getQualifiedName().toString(); - final var contextPath = Util.combinePath(contextPathString, packagePath(packageFQN)); - final var reader = new ControllerReader((TypeElement) controller, contextPath); - reader.read(true); - try { - - writeControllerAdapter(reader); - TypeElement typeElement = (TypeElement) controller; - if (APContext.isTestCompilation() - && typeElement.getInterfaces().isEmpty() - && "java.lang.Object".equals(typeElement.getSuperclass().toString())) { - new TestClientWriter(reader).write(); - } + private void writeAdapter(TypeElement controller) { + final var packageFQN = elements().getPackageOf(controller).getQualifiedName().toString(); + final var contextPath = Util.combinePath(contextPathString, packagePath(packageFQN)); + final var reader = new ControllerReader(controller, contextPath); + reader.read(true); + try { + + writeControllerAdapter(reader); + controllerFQNs.add(controller.getQualifiedName().toString()); + + } catch (final Throwable e) { + logError(reader.beanType(), "Failed to write $Route class " + e); + } + } - } catch (final Throwable e) { - logError(reader.beanType(), "Failed to write $Route class " + e); + private void writeClientAdapter(TypeElement controller) { + final var packageFQN = elements().getPackageOf(controller).getQualifiedName().toString(); + final var contextPath = Util.combinePath(contextPathString, packagePath(packageFQN)); + final var reader = new ControllerReader(controller, contextPath); + reader.read(true); + try { + if (controller.getInterfaces().isEmpty() + && "java.lang.Object".equals(controller.getSuperclass().toString())) { + new TestClientWriter(reader).write(); } + writeControllerAdapter(reader); + + } catch (final Throwable e) { + logError(reader.beanType(), "Failed to write $Route class " + e); } } private String packagePath(String packageFQN) { return packagePaths.entrySet().stream() - .filter(k -> packageFQN.startsWith(k.getKey())) - .map(Entry::getValue) - .reduce(Util::combinePath) - .orElse(null); + .filter(k -> packageFQN.startsWith(k.getKey())) + .map(Entry::getValue) + .reduce(Util::combinePath) + .orElse(null); } - /** - * Write the adapter code for the given controller. - */ + /** Write the adapter code for the given controller. */ public abstract void writeControllerAdapter(ControllerReader reader) throws IOException; - } From 030324ed1731d387140509da6cdc1fdc509b723f Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Tue, 25 Mar 2025 21:40:58 -0400 Subject: [PATCH 1276/1323] modifiers --- .../avaje/http/generator/core/TestClientWriter.java | 11 +++++++++-- pom.xml | 2 +- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/TestClientWriter.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/TestClientWriter.java index 17f65b47c..df61a23ad 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/TestClientWriter.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/TestClientWriter.java @@ -7,6 +7,7 @@ import java.util.Set; import java.util.TreeSet; +import javax.lang.model.element.Modifier; import javax.lang.model.element.TypeElement; import javax.lang.model.type.TypeMirror; @@ -88,7 +89,12 @@ protected void writeImports() { private void writeClassStart() { writer.append(AT_GENERATED).eol(); writer.append("@Client(\"%s\")", reader.path()).eol(); - writer.append("public interface %s$TestAPI {", shortName).eol().eol(); + writer + .append( + "%sinterface %s$TestAPI {", + reader.beanType().getModifiers().contains(Modifier.PUBLIC) ? "public " : "", shortName) + .eol() + .eol(); } private void writeAddRoutes() { @@ -102,6 +108,7 @@ private void writeAddRoutes() { private void writeRoute(MethodReader method) { TypeMirror returnType = method.returnType(); var isJstache = ProcessingContext.isJstacheTemplate(returnType); + writer.append(" "); AnnotationCopier.copyAnnotations(writer, method.element(), true); var returnTypeStr = PrimitiveUtil.wrap(UType.parse(returnType).shortType()); @@ -112,7 +119,7 @@ private void writeRoute(MethodReader method) { } writer.append( - "HttpResponse<%s> %s(", isJstache ? "String" : returnTypeStr, method.simpleName()); + " HttpResponse<%s> %s(", isJstache ? "String" : returnTypeStr, method.simpleName()); boolean first = true; for (var param : method.params()) { diff --git a/pom.xml b/pom.xml index 0878f9095..9d0669f2d 100644 --- a/pom.xml +++ b/pom.xml @@ -22,7 +22,7 @@ 2.2.29 2.14.2 3.0-RC10 - 1.40 + 1.41 2025-03-18T18:53:23Z ${project.build.directory}${file.separator}module-info.shade From 13e6338e606b7a5216799ce86d3d3b7abdbdd105 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Tue, 25 Mar 2025 21:50:10 -0400 Subject: [PATCH 1277/1323] Update TestClientWriter.java --- .../java/io/avaje/http/generator/core/TestClientWriter.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/TestClientWriter.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/TestClientWriter.java index df61a23ad..0cd4dfa27 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/TestClientWriter.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/TestClientWriter.java @@ -106,6 +106,12 @@ private void writeAddRoutes() { } private void writeRoute(MethodReader method) { + + // TODO handle Contexts later + if (method.params().stream().anyMatch(p -> p.paramType() == ParamType.CONTEXT)) { + return; + } + TypeMirror returnType = method.returnType(); var isJstache = ProcessingContext.isJstacheTemplate(returnType); writer.append(" "); From 016faa9e6afb009f21ff38c7f517785fc95ee892 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Tue, 25 Mar 2025 22:04:51 -0400 Subject: [PATCH 1278/1323] Update BaseProcessor.java --- .../main/java/io/avaje/http/generator/core/BaseProcessor.java | 1 - 1 file changed, 1 deletion(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java index 07d8d76f0..43847c2fb 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java @@ -71,7 +71,6 @@ public synchronized void init(ProcessingEnvironment processingEnv) { Files.lines(txtFilePath).forEach(controllerFQNs::add); } if (APContext.isTestCompilation()) { - System.out.println("Trying to read: " + controllerFQNs + "from path:" + txtFilePath); controllerFQNs.stream().map(APContext::typeElement).forEach(this::writeClientAdapter); } } catch (IOException e) { From 71e6d5d7306f422fa5c5059a32b728c615bedce2 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Wed, 26 Mar 2025 14:58:25 -0400 Subject: [PATCH 1279/1323] use txt files to store info --- .gitignore | 4 ++- .../http/generator/core/AnnotationCopier.java | 3 +- .../http/generator/core/BaseProcessor.java | 31 +++++++++---------- .../http/generator/core/TestClientWriter.java | 20 ++++++++++-- 4 files changed, 36 insertions(+), 22 deletions(-) diff --git a/.gitignore b/.gitignore index 6eb138889..bfc8ee0c3 100644 --- a/.gitignore +++ b/.gitignore @@ -13,5 +13,7 @@ build/ *.Module dependency-reduced-pom.xml .DS_Store -tests/test-sigma/avaje-processors.txt +*avaje-processors.txt +*controllers.txt tests/test-sigma/io.avaje.jsonb.spi.JsonbExtension +tests/test-javalin-jsonb/*.txt diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/AnnotationCopier.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/AnnotationCopier.java index 306769d90..2bc1b14df 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/AnnotationCopier.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/AnnotationCopier.java @@ -33,7 +33,8 @@ static void copyAnnotations(Append writer, Element element, String indent, boole || type.contains("Consumes") || type.contains("InstrumentServerContext") || type.contains("Default") - || type.contains("OpenAPI")) { + || type.contains("OpenAPI") + || type.contains("Valid")) { continue; } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java index 43847c2fb..98db40c48 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java @@ -39,13 +39,12 @@ }) public abstract class BaseProcessor extends AbstractProcessor { - private static final String HTTP_CONTROLLERS_TXT = "controllers.txt"; - + private static final String HTTP_CONTROLLERS_TXT = "testAPI/controllers.txt"; protected String contextPathString; protected Map packagePaths = new HashMap<>(); - private final Set controllerFQNs = new HashSet<>(); + private final Set clientFQNs = new HashSet<>(); @Override public SourceVersion getSupportedSourceVersion() { @@ -68,10 +67,12 @@ public synchronized void init(ProcessingEnvironment processingEnv) { var txtFilePath = APContext.getBuildResource(HTTP_CONTROLLERS_TXT); if (txtFilePath.toFile().exists()) { - Files.lines(txtFilePath).forEach(controllerFQNs::add); + Files.lines(txtFilePath).forEach(clientFQNs::add); } if (APContext.isTestCompilation()) { - controllerFQNs.stream().map(APContext::typeElement).forEach(this::writeClientAdapter); + for (var path : clientFQNs) { + TestClientWriter.writeActual(path); + } } } catch (IOException e) { e.printStackTrace(); @@ -124,7 +125,7 @@ public boolean process(Set annotations, RoundEnvironment try { Files.write( APContext.getBuildResource(HTTP_CONTROLLERS_TXT), - controllerFQNs, + clientFQNs, StandardOpenOption.CREATE, StandardOpenOption.WRITE); } catch (IOException e) { @@ -175,26 +176,22 @@ private void writeAdapter(TypeElement controller) { try { writeControllerAdapter(reader); - controllerFQNs.add(controller.getQualifiedName().toString()); + writeClientAdapter(reader); } catch (final Throwable e) { logError(reader.beanType(), "Failed to write $Route class " + e); } } - private void writeClientAdapter(TypeElement controller) { - final var packageFQN = elements().getPackageOf(controller).getQualifiedName().toString(); - final var contextPath = Util.combinePath(contextPathString, packagePath(packageFQN)); - final var reader = new ControllerReader(controller, contextPath); - reader.read(true); + private void writeClientAdapter(ControllerReader reader) { + try { - if (controller.getInterfaces().isEmpty() - && "java.lang.Object".equals(controller.getSuperclass().toString())) { + if (reader.beanType().getInterfaces().isEmpty() + && "java.lang.Object".equals(reader.beanType().getSuperclass().toString())) { new TestClientWriter(reader).write(); + clientFQNs.add(reader.beanType().getQualifiedName().toString() + "$TestAPI"); } - writeControllerAdapter(reader); - - } catch (final Throwable e) { + } catch (final IOException e) { logError(reader.beanType(), "Failed to write $Route class " + e); } } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/TestClientWriter.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/TestClientWriter.java index 0cd4dfa27..c8a153fa8 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/TestClientWriter.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/TestClientWriter.java @@ -2,7 +2,9 @@ import static java.util.stream.Collectors.toList; +import java.io.FileWriter; import java.io.IOException; +import java.nio.file.Files; import java.util.List; import java.util.Set; import java.util.TreeSet; @@ -19,7 +21,6 @@ public class TestClientWriter { private String originName; private String shortName; private String packageName; - private String fullName; private Append writer; private List methods; @@ -30,7 +31,6 @@ public class TestClientWriter { this.originName = origin.getQualifiedName().toString(); this.shortName = origin.getSimpleName().toString(); this.packageName = initPackageName(originName); - this.fullName = packageName + "." + shortName + "$TestAPI"; this.methods = reader.methods().stream() .filter(MethodReader::isWebMethod) @@ -42,7 +42,11 @@ public class TestClientWriter { && m.webMethod() != CoreWebMethod.OTHER) .collect(toList()); if (methods.isEmpty()) return; - writer = new Append(APContext.createSourceFile(fullName, reader.beanType()).openWriter()); + + writer = + new Append( + new FileWriter( + APContext.getBuildResource("testAPI/" + originName + "$TestAPI.txt").toFile())); } protected String initPackageName(String originName) { @@ -144,4 +148,14 @@ private void writeRoute(MethodReader method) { writer.eol(); writer.eol(); } + + static void writeActual(String controller) throws IOException { + + try (var out = APContext.createSourceFile(controller).openOutputStream(); + var in = + Files.newInputStream(APContext.getBuildResource("testAPI/" + controller + ".txt")); ) { + + in.transferTo(out); + } + } } From ee29e03374090f6e708ac1127b7594b5434c58bd Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Wed, 26 Mar 2025 16:59:57 -0400 Subject: [PATCH 1280/1323] a test --- .gitignore | 2 ++ .../http/generator/core/BaseProcessor.java | 2 +- .../http/generator/core/TestClientWriter.java | 7 +++---- tests/test-jex/pom.xml | 16 ++++++++++++++++ .../org/example/web/HelloControllerTest.java | 18 +++++++++++++++++- tests/test-nima/pom.xml | 5 +++++ 6 files changed, 44 insertions(+), 6 deletions(-) diff --git a/.gitignore b/.gitignore index bfc8ee0c3..886650d31 100644 --- a/.gitignore +++ b/.gitignore @@ -16,4 +16,6 @@ dependency-reduced-pom.xml *avaje-processors.txt *controllers.txt tests/test-sigma/io.avaje.jsonb.spi.JsonbExtension +tests/test-sigma/*.txt tests/test-javalin-jsonb/*.txt +tests/test-nima-jsonb/*.txt diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java index 98db40c48..02bc89ec4 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java @@ -189,7 +189,7 @@ private void writeClientAdapter(ControllerReader reader) { if (reader.beanType().getInterfaces().isEmpty() && "java.lang.Object".equals(reader.beanType().getSuperclass().toString())) { new TestClientWriter(reader).write(); - clientFQNs.add(reader.beanType().getQualifiedName().toString() + "$TestAPI"); + clientFQNs.add(reader.beanType().getQualifiedName().toString() + "TestAPI"); } } catch (final IOException e) { logError(reader.beanType(), "Failed to write $Route class " + e); diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/TestClientWriter.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/TestClientWriter.java index c8a153fa8..a85c50a62 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/TestClientWriter.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/TestClientWriter.java @@ -46,7 +46,7 @@ public class TestClientWriter { writer = new Append( new FileWriter( - APContext.getBuildResource("testAPI/" + originName + "$TestAPI.txt").toFile())); + APContext.getBuildResource("testAPI/" + originName + "TestAPI.txt").toFile())); } protected String initPackageName(String originName) { @@ -95,7 +95,7 @@ private void writeClassStart() { writer.append("@Client(\"%s\")", reader.path()).eol(); writer .append( - "%sinterface %s$TestAPI {", + "%sinterface %sTestAPI {", reader.beanType().getModifiers().contains(Modifier.PUBLIC) ? "public " : "", shortName) .eol() .eol(); @@ -118,8 +118,7 @@ private void writeRoute(MethodReader method) { TypeMirror returnType = method.returnType(); var isJstache = ProcessingContext.isJstacheTemplate(returnType); - writer.append(" "); - AnnotationCopier.copyAnnotations(writer, method.element(), true); + AnnotationCopier.copyAnnotations(writer, method.element(), " ", true); var returnTypeStr = PrimitiveUtil.wrap(UType.parse(returnType).shortType()); diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 0d1614eca..585451e1f 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -96,6 +96,17 @@ test + + io.avaje + avaje-http-jex-generator + ${project.version} + + + + io.avaje + avaje-http-client-generator + ${project.version} + @@ -121,6 +132,11 @@ avaje-http-jex-generator ${project.version} + + io.avaje + avaje-http-client-generator + ${project.version} + io.avaje avaje-jsonb-generator diff --git a/tests/test-jex/src/test/java/org/example/web/HelloControllerTest.java b/tests/test-jex/src/test/java/org/example/web/HelloControllerTest.java index 499e6c1c5..bf332af61 100644 --- a/tests/test-jex/src/test/java/org/example/web/HelloControllerTest.java +++ b/tests/test-jex/src/test/java/org/example/web/HelloControllerTest.java @@ -16,7 +16,7 @@ @Import(Violation.class) class HelloControllerTest extends BaseWebTest { - final static HttpClient client = client(); + static final HttpClient client = client(); @Test void getHello() { @@ -26,8 +26,24 @@ void getHello() { assertEquals("rob", hello.name); } + @Test + void getHelloClient() { + final HelloDto hello = client.create(HelloControllerTestAPI.class).getHello().body(); + + assertEquals(42, hello.id); + assertEquals("rob", hello.name); + } + @Test void getPlain() { + final HttpResponse res = client.create(HelloControllerTestAPI.class).getText(); + + assertEquals("something", res.body()); + assertThat(res.headers().firstValue("content-type").orElseThrow()).startsWith("text/plain;"); + } + + @Test + void getPlainClient() { final HttpResponse res = client.request().path("plain").GET().asString(); assertEquals("something", res.body()); diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index 7e5a5ffc4..72aef8770 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -43,6 +43,11 @@ helidon-http-media-jsonb ${helidon.version} + + io.avaje + avaje-http-helidon-generator + ${project.version} + From a995be6ddba23ef01f183d3fdcc8d3a8298956d1 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Mon, 31 Mar 2025 08:18:17 +1300 Subject: [PATCH 1281/1323] [jex generation] Root path generated as "/" rather than "" --- .../io/avaje/http/generator/jex/ControllerMethodWriter.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java index c3244def0..5a9c43cd9 100644 --- a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java +++ b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java @@ -43,7 +43,10 @@ private void validateFilter() { void writeRouting() { final PathSegments segments = method.pathSegments(); - final String fullPath = segments.fullPath(); + String fullPath = segments.fullPath(); + if (fullPath.isEmpty()) { + fullPath = "/"; + } if (method.isErrorMethod()) { writer.append(" routing.error(%s.class, this::_%s", method.exceptionShortName(), method.simpleName()); From cf4cf41f89cd3aec657ea9a526d8ed9245201562 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Mon, 31 Mar 2025 08:31:34 +1300 Subject: [PATCH 1282/1323] Version 3.2 --- aws-cognito/http-client-authtoken/pom.xml | 2 +- htmx-api/pom.xml | 2 +- htmx-nima-jstache/pom.xml | 2 +- htmx-nima/pom.xml | 4 ++-- http-api-javalin/pom.xml | 2 +- http-api/pom.xml | 2 +- http-client-gson-adapter/pom.xml | 4 ++-- http-client-moshi-adapter/pom.xml | 4 ++-- http-client/pom.xml | 2 +- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 2 +- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-generator-sigma/pom.xml | 2 +- http-inject-plugin/pom.xml | 2 +- pom.xml | 4 ++-- tests/pom.xml | 2 +- tests/test-client-generation/pom.xml | 2 +- tests/test-client/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-htmx/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- tests/test-sigma/pom.xml | 2 +- 27 files changed, 31 insertions(+), 31 deletions(-) diff --git a/aws-cognito/http-client-authtoken/pom.xml b/aws-cognito/http-client-authtoken/pom.xml index 46f6c2c32..c68ea4c16 100644 --- a/aws-cognito/http-client-authtoken/pom.xml +++ b/aws-cognito/http-client-authtoken/pom.xml @@ -17,7 +17,7 @@ io.avaje avaje-http-client - 3.1 + 3.2 diff --git a/htmx-api/pom.xml b/htmx-api/pom.xml index c98c3784a..0ebd189ac 100644 --- a/htmx-api/pom.xml +++ b/htmx-api/pom.xml @@ -6,7 +6,7 @@ io.avaje avaje-http-parent - 3.1 + 3.2 avaje-htmx-api diff --git a/htmx-nima-jstache/pom.xml b/htmx-nima-jstache/pom.xml index 1a9dc0b53..503faf015 100644 --- a/htmx-nima-jstache/pom.xml +++ b/htmx-nima-jstache/pom.xml @@ -6,7 +6,7 @@ io.avaje avaje-http-parent - 3.1 + 3.2 avaje-htmx-nima-jstache diff --git a/htmx-nima/pom.xml b/htmx-nima/pom.xml index 449b7f7ac..6ee0b4a3c 100644 --- a/htmx-nima/pom.xml +++ b/htmx-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje avaje-http-parent - 3.1 + 3.2 avaje-htmx-nima @@ -21,7 +21,7 @@ io.avaje avaje-htmx-api - 3.1 + 3.2 io.helidon.webserver diff --git a/http-api-javalin/pom.xml b/http-api-javalin/pom.xml index 14160d3f9..f6a191ba0 100644 --- a/http-api-javalin/pom.xml +++ b/http-api-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.1 + 3.2 .. diff --git a/http-api/pom.xml b/http-api/pom.xml index b77407ef3..2df784e29 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.1 + 3.2 .. diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index a6091c561..f1ce23a62 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.1 + 3.2 avaje-http-client-gson @@ -20,7 +20,7 @@ io.avaje avaje-http-client - 3.1 + 3.2 provided diff --git a/http-client-moshi-adapter/pom.xml b/http-client-moshi-adapter/pom.xml index 0db7d6d70..c4fd304f9 100644 --- a/http-client-moshi-adapter/pom.xml +++ b/http-client-moshi-adapter/pom.xml @@ -3,7 +3,7 @@ io.avaje avaje-http-parent - 3.1 + 3.2 avaje-http-client-moshi @@ -19,7 +19,7 @@ io.avaje avaje-http-client - 3.1 + 3.2 provided diff --git a/http-client/pom.xml b/http-client/pom.xml index ed59be493..79034b6cc 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.1 + 3.2 avaje-http-client diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index 66b904d71..d7d2024d3 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.1 + 3.2 avaje-http-client-generator diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index b4fd94ea6..2901c5083 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.1 + 3.2 avaje-http-generator-core diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index 770f3353b..b06e245a5 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 3.1 + 3.2 avaje-http-helidon-generator diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index 36bd76609..5cc411981 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.1 + 3.2 avaje-http-javalin-generator diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index ae8b361a3..49aab1980 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.1 + 3.2 avaje-http-jex-generator diff --git a/http-generator-sigma/pom.xml b/http-generator-sigma/pom.xml index e0707617a..c6d96c610 100644 --- a/http-generator-sigma/pom.xml +++ b/http-generator-sigma/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.1 + 3.2 avaje-http-sigma-generator diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index 9f7119603..9b0ac980f 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.1 + 3.2 .. diff --git a/pom.xml b/pom.xml index 9d0669f2d..1358bebe5 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-parent - 3.1 + 3.2 pom @@ -23,7 +23,7 @@ 2.14.2 3.0-RC10 1.41 - 2025-03-18T18:53:23Z + 2025-03-30T19:22:50Z ${project.build.directory}${file.separator}module-info.shade diff --git a/tests/pom.xml b/tests/pom.xml index 678c06d5a..eb97c1619 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 3.1 + 3.2 tests diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index acd63b899..5e385ff6d 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 3.1 + 3.2 test-client-generation diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index 165a8d9b1..21664f78c 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 3.1 + 3.2 test-client diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 4d818e407..dbdb5184b 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 3.1 + 3.2 test-javalin-jsonb diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index e1157c0b6..00a15c067 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 3.1 + 3.2 test-javalin diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 585451e1f..f64ef9b52 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 3.1 + 3.2 test-jex diff --git a/tests/test-nima-htmx/pom.xml b/tests/test-nima-htmx/pom.xml index 6db46e960..79887f789 100644 --- a/tests/test-nima-htmx/pom.xml +++ b/tests/test-nima-htmx/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 3.1 + 3.2 test-nima-htmx diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 7ce565138..2ee19cff1 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 3.1 + 3.2 test-nima-jsonb diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index 72aef8770..1a69cb4b1 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 3.1 + 3.2 test-nima diff --git a/tests/test-sigma/pom.xml b/tests/test-sigma/pom.xml index 50cb45a93..e083bd4d8 100644 --- a/tests/test-sigma/pom.xml +++ b/tests/test-sigma/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 3.1 + 3.2 test-sigma From bd94426d0136243bdf996457f58013259b8dbf6c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 31 Mar 2025 19:34:13 +0000 Subject: [PATCH 1283/1323] Bump the dependencies group with 7 updates Bumps the dependencies group with 7 updates: | Package | From | To | | --- | --- | --- | | [io.avaje:avaje-inject](https://github.com/avaje/avaje-inject) | `11.3` | `11.4` | | io.avaje:avaje-inject-generator | `11.3` | `11.4` | | io.avaje:avaje-spi-service | `2.10` | `2.11` | | [io.avaje:avaje-prisms](https://github.com/avaje/avaje-prisms) | `1.41` | `1.42` | | [io.avaje:avaje-jex](https://github.com/avaje/avaje-jex) | `3.0-RC23` | `3.0` | | io.avaje:avaje-jex-htmx | `3.0-RC23` | `3.0` | | io.avaje:avaje-inject-maven-plugin | `11.3` | `11.4` | Updates `io.avaje:avaje-inject` from 11.3 to 11.4 - [Release notes](https://github.com/avaje/avaje-inject/releases) - [Commits](https://github.com/avaje/avaje-inject/compare/11.3...11.4) Updates `io.avaje:avaje-inject-generator` from 11.3 to 11.4 Updates `io.avaje:avaje-inject-generator` from 11.3 to 11.4 Updates `io.avaje:avaje-spi-service` from 2.10 to 2.11 Updates `io.avaje:avaje-prisms` from 1.41 to 1.42 - [Release notes](https://github.com/avaje/avaje-prisms/releases) - [Commits](https://github.com/avaje/avaje-prisms/compare/1.41...1.42) Updates `io.avaje:avaje-jex` from 3.0-RC23 to 3.0 - [Release notes](https://github.com/avaje/avaje-jex/releases) - [Commits](https://github.com/avaje/avaje-jex/commits/3.0) Updates `io.avaje:avaje-jex-htmx` from 3.0-RC23 to 3.0 Updates `io.avaje:avaje-inject-maven-plugin` from 11.3 to 11.4 Updates `io.avaje:avaje-jex-htmx` from 3.0-RC23 to 3.0 --- updated-dependencies: - dependency-name: io.avaje:avaje-inject dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.avaje:avaje-inject-generator dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.avaje:avaje-inject-generator dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.avaje:avaje-spi-service dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.avaje:avaje-prisms dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.avaje:avaje-jex dependency-type: direct:development dependency-group: dependencies - dependency-name: io.avaje:avaje-jex-htmx dependency-type: direct:production dependency-group: dependencies - dependency-name: io.avaje:avaje-inject-maven-plugin dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.avaje:avaje-jex-htmx dependency-type: direct:production dependency-group: dependencies ... Signed-off-by: dependabot[bot] --- htmx-nima-jstache/pom.xml | 4 ++-- http-client/pom.xml | 4 ++-- http-inject-plugin/pom.xml | 4 ++-- pom.xml | 2 +- tests/pom.xml | 4 ++-- tests/test-client-generation/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-htmx/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- 10 files changed, 14 insertions(+), 14 deletions(-) diff --git a/htmx-nima-jstache/pom.xml b/htmx-nima-jstache/pom.xml index 503faf015..65bc9ac91 100644 --- a/htmx-nima-jstache/pom.xml +++ b/htmx-nima-jstache/pom.xml @@ -39,14 +39,14 @@ io.avaje avaje-inject - 11.3 + 11.4 provided true io.avaje avaje-spi-service - 2.10 + 2.11 provided true diff --git a/http-client/pom.xml b/http-client/pom.xml index 79034b6cc..c492ca623 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -50,7 +50,7 @@ io.avaje avaje-inject - 11.3 + 11.4 true @@ -106,7 +106,7 @@ io.avaje avaje-inject-generator - 11.3 + 11.4 diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index 9b0ac980f..d857eecfb 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -19,7 +19,7 @@ io.avaje avaje-inject - 11.3 + 11.4 provided true @@ -33,7 +33,7 @@ io.avaje avaje-spi-service - 2.10 + 2.11 provided true diff --git a/pom.xml b/pom.xml index 1358bebe5..3c0f01e0c 100644 --- a/pom.xml +++ b/pom.xml @@ -22,7 +22,7 @@ 2.2.29 2.14.2 3.0-RC10 - 1.41 + 1.42 2025-03-30T19:22:50Z ${project.build.directory}${file.separator}module-info.shade diff --git a/tests/pom.xml b/tests/pom.xml index eb97c1619..ebe050cbf 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -15,8 +15,8 @@ 5.12.1 3.27.3 2.18.3 - 3.0-RC23 - 11.3 + 3.0 + 11.4 4.2.0 6.5.0 diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index 5e385ff6d..8daa31e24 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -141,7 +141,7 @@ io.avaje avaje-inject-maven-plugin - 11.3 + 11.4 process-sources diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index f64ef9b52..b778073b9 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -187,7 +187,7 @@ io.avaje avaje-inject-maven-plugin - 11.3 + 11.4 process-sources diff --git a/tests/test-nima-htmx/pom.xml b/tests/test-nima-htmx/pom.xml index 79887f789..61735f262 100644 --- a/tests/test-nima-htmx/pom.xml +++ b/tests/test-nima-htmx/pom.xml @@ -103,7 +103,7 @@ io.avaje avaje-inject-maven-plugin - 11.3 + 11.4 process-sources diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 2ee19cff1..9273c1796 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -120,7 +120,7 @@ io.avaje avaje-inject-maven-plugin - 11.3 + 11.4 process-sources diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index 1a69cb4b1..07cf2f10b 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -75,7 +75,7 @@ io.avaje avaje-inject-maven-plugin - 11.3 + 11.4 process-sources From d7b9e789bef9f42971e52dff6cc17c285b83de3f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 7 Apr 2025 20:54:30 +0000 Subject: [PATCH 1284/1323] Bump the dependencies group with 2 updates Bumps the dependencies group with 2 updates: io.swagger.core.v3:swagger-models and io.swagger.core.v3:swagger-annotations. Updates `io.swagger.core.v3:swagger-models` from 2.2.29 to 2.2.30 Updates `io.swagger.core.v3:swagger-annotations` from 2.2.29 to 2.2.30 Updates `io.swagger.core.v3:swagger-annotations` from 2.2.29 to 2.2.30 --- updated-dependencies: - dependency-name: io.swagger.core.v3:swagger-models dependency-version: 2.2.30 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: io.swagger.core.v3:swagger-annotations dependency-version: 2.2.30 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: io.swagger.core.v3:swagger-annotations dependency-version: 2.2.30 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-sigma/pom.xml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index 3c0f01e0c..3a27d42e3 100644 --- a/pom.xml +++ b/pom.xml @@ -19,7 +19,7 @@ true - 2.2.29 + 2.2.30 2.14.2 3.0-RC10 1.42 diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index dbdb5184b..2279dbf0c 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -13,7 +13,7 @@ true org.example.myapp.Main - 2.2.29 + 2.2.30 1.3.71 diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 00a15c067..e9ee8548e 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -12,7 +12,7 @@ true org.example.myapp.Main - 2.2.29 + 2.2.30 1.3.71 diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index b778073b9..ec28926b3 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -12,7 +12,7 @@ 21 true org.example.myapp.Main - 2.2.29 + 2.2.30 diff --git a/tests/test-sigma/pom.xml b/tests/test-sigma/pom.xml index e083bd4d8..5e78b3050 100644 --- a/tests/test-sigma/pom.xml +++ b/tests/test-sigma/pom.xml @@ -13,7 +13,7 @@ 17 true - 2.2.29 + 2.2.30 1.3.71 From 99ada45b800b2d22d04ac46c643ee7a95824e03e Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Mon, 7 Apr 2025 17:06:07 -0400 Subject: [PATCH 1285/1323] Update OpenAPISerializer.java --- .../io/avaje/http/generator/core/openapi/OpenAPISerializer.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/OpenAPISerializer.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/OpenAPISerializer.java index 0899323a7..7b6055eb6 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/OpenAPISerializer.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/OpenAPISerializer.java @@ -13,6 +13,8 @@ final class OpenAPISerializer { "BINARY_STRING_CONVERSION_PROPERTY", "COMPONENTS_SCHEMAS_REF", "APPLY_SCHEMA_RESOLUTION_PROPERTY", + "EXPLICIT_OBJECT_SCHEMA_PROPERTY", + "USE_ARBITRARY_SCHEMA_PROPERTY", "exampleSetFlag", "types", "specVersion"); From 6605476d2b3ce3d8facf98bd5c427721652949e4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 14 Apr 2025 20:08:59 +0000 Subject: [PATCH 1286/1323] Bump the dependencies group with 7 updates Bumps the dependencies group with 7 updates: | Package | From | To | | --- | --- | --- | | [io.javalin:javalin](https://github.com/javalin/javalin) | `6.5.0` | `6.6.0` | | [com.google.code.gson:gson](https://github.com/google/gson) | `2.12.1` | `2.13.0` | | io.avaje:avaje-spi-service | `2.11` | `2.12` | | [io.avaje:avaje-jex](https://github.com/avaje/avaje-jex) | `3.0` | `3.1` | | io.avaje:avaje-jex-htmx | `3.0` | `3.1` | | [org.junit.jupiter:junit-jupiter-api](https://github.com/junit-team/junit5) | `5.12.1` | `5.12.2` | | [org.junit.jupiter:junit-jupiter-engine](https://github.com/junit-team/junit5) | `5.12.1` | `5.12.2` | Updates `io.javalin:javalin` from 6.5.0 to 6.6.0 - [Release notes](https://github.com/javalin/javalin/releases) - [Commits](https://github.com/javalin/javalin/compare/javalin-parent-6.5.0...javalin-parent-6.6.0) Updates `com.google.code.gson:gson` from 2.12.1 to 2.13.0 - [Release notes](https://github.com/google/gson/releases) - [Changelog](https://github.com/google/gson/blob/main/CHANGELOG.md) - [Commits](https://github.com/google/gson/compare/gson-parent-2.12.1...gson-parent-2.13.0) Updates `io.avaje:avaje-spi-service` from 2.11 to 2.12 Updates `io.avaje:avaje-jex` from 3.0 to 3.1 - [Release notes](https://github.com/avaje/avaje-jex/releases) - [Commits](https://github.com/avaje/avaje-jex/compare/3.0...3.1) Updates `io.avaje:avaje-jex-htmx` from 3.0 to 3.1 Updates `io.avaje:avaje-jex-htmx` from 3.0 to 3.1 Updates `org.junit.jupiter:junit-jupiter-api` from 5.12.1 to 5.12.2 - [Release notes](https://github.com/junit-team/junit5/releases) - [Commits](https://github.com/junit-team/junit5/compare/r5.12.1...r5.12.2) Updates `org.junit.jupiter:junit-jupiter-engine` from 5.12.1 to 5.12.2 - [Release notes](https://github.com/junit-team/junit5/releases) - [Commits](https://github.com/junit-team/junit5/compare/r5.12.1...r5.12.2) Updates `org.junit.jupiter:junit-jupiter-engine` from 5.12.1 to 5.12.2 - [Release notes](https://github.com/junit-team/junit5/releases) - [Commits](https://github.com/junit-team/junit5/compare/r5.12.1...r5.12.2) --- updated-dependencies: - dependency-name: io.javalin:javalin dependency-version: 6.6.0 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: com.google.code.gson:gson dependency-version: 2.13.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.avaje:avaje-spi-service dependency-version: '2.12' dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.avaje:avaje-jex dependency-version: '3.1' dependency-type: direct:development update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.avaje:avaje-jex-htmx dependency-version: '3.1' dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.avaje:avaje-jex-htmx dependency-version: '3.1' dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: org.junit.jupiter:junit-jupiter-api dependency-version: 5.12.2 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: org.junit.jupiter:junit-jupiter-engine dependency-version: 5.12.2 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: org.junit.jupiter:junit-jupiter-engine dependency-version: 5.12.2 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: dependencies ... Signed-off-by: dependabot[bot] --- htmx-nima-jstache/pom.xml | 2 +- http-api/pom.xml | 2 +- http-client-gson-adapter/pom.xml | 2 +- http-client/pom.xml | 2 +- http-inject-plugin/pom.xml | 2 +- tests/pom.xml | 6 +++--- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/htmx-nima-jstache/pom.xml b/htmx-nima-jstache/pom.xml index 65bc9ac91..9fcbc6ae3 100644 --- a/htmx-nima-jstache/pom.xml +++ b/htmx-nima-jstache/pom.xml @@ -46,7 +46,7 @@ io.avaje avaje-spi-service - 2.11 + 2.12 provided true diff --git a/http-api/pom.xml b/http-api/pom.xml index 2df784e29..90fea9b1c 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -24,7 +24,7 @@ io.javalin javalin - 6.5.0 + 6.6.0 provided true diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index f1ce23a62..ab6f9962b 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -14,7 +14,7 @@ com.google.code.gson gson - 2.12.1 + 2.13.0 diff --git a/http-client/pom.xml b/http-client/pom.xml index c492ca623..98bc069e3 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -66,7 +66,7 @@ io.javalin javalin - 6.5.0 + 6.6.0 test diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index d857eecfb..9dd6109a5 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -33,7 +33,7 @@ io.avaje avaje-spi-service - 2.11 + 2.12 provided true diff --git a/tests/pom.xml b/tests/pom.xml index ebe050cbf..774bbcc07 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -12,13 +12,13 @@ true - 5.12.1 + 5.12.2 3.27.3 2.18.3 - 3.0 + 3.1 11.4 4.2.0 - 6.5.0 + 6.6.0 From 8618fa122dff86a6cbac3a6653f8ea5a0973fb13 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 21 Apr 2025 19:12:42 +0000 Subject: [PATCH 1287/1323] Bump the dependencies group with 5 updates Bumps the dependencies group with 5 updates: | Package | From | To | | --- | --- | --- | | [org.avaje:java11-oss](https://github.com/avaje-pom/java11-oss) | `4.5` | `5.1` | | [io.avaje:avaje-jsonb](https://github.com/avaje/avaje-jsonb) | `3.2` | `3.3` | | io.avaje:avaje-json-node | `3.2` | `3.3` | | io.avaje:avaje-jsonb-generator | `3.2` | `3.3` | | io.avaje:avaje-json-core | `3.2` | `3.3` | Updates `org.avaje:java11-oss` from 4.5 to 5.1 - [Release notes](https://github.com/avaje-pom/java11-oss/releases) - [Commits](https://github.com/avaje-pom/java11-oss/commits/5.1) Updates `io.avaje:avaje-jsonb` from 3.2 to 3.3 - [Release notes](https://github.com/avaje/avaje-jsonb/releases) - [Commits](https://github.com/avaje/avaje-jsonb/compare/3.2...3.3) Updates `io.avaje:avaje-json-node` from 3.2 to 3.3 Updates `io.avaje:avaje-jsonb-generator` from 3.2 to 3.3 Updates `io.avaje:avaje-json-core` from 3.2 to 3.3 --- updated-dependencies: - dependency-name: org.avaje:java11-oss dependency-version: '5.1' dependency-type: direct:production update-type: version-update:semver-major dependency-group: dependencies - dependency-name: io.avaje:avaje-jsonb dependency-version: '3.3' dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.avaje:avaje-json-node dependency-version: '3.3' dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.avaje:avaje-jsonb-generator dependency-version: '3.3' dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.avaje:avaje-json-core dependency-version: '3.3' dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies ... Signed-off-by: dependabot[bot] --- aws-cognito/http-client-authtoken/pom.xml | 6 +++--- http-client/pom.xml | 4 ++-- pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 4 ++-- tests/test-jex/pom.xml | 4 ++-- tests/test-nima-htmx/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 4 ++-- tests/test-sigma/pom.xml | 4 ++-- 8 files changed, 15 insertions(+), 15 deletions(-) diff --git a/aws-cognito/http-client-authtoken/pom.xml b/aws-cognito/http-client-authtoken/pom.xml index c68ea4c16..ab6948f33 100644 --- a/aws-cognito/http-client-authtoken/pom.xml +++ b/aws-cognito/http-client-authtoken/pom.xml @@ -6,7 +6,7 @@ org.avaje java11-oss - 4.5 + 5.1 io.avaje.aws @@ -23,14 +23,14 @@ io.avaje avaje-json-core - 3.2 + 3.3 io.avaje avaje-json-node - 3.2 + 3.3 test diff --git a/http-client/pom.xml b/http-client/pom.xml index 98bc069e3..4301f4904 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -36,14 +36,14 @@ io.avaje avaje-jsonb - 3.2 + 3.3 true io.avaje avaje-json-node - 3.2 + 3.3 test diff --git a/pom.xml b/pom.xml index 3a27d42e3..a8d902e43 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ org.avaje java11-oss - 4.5 + 5.1 io.avaje diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 2279dbf0c..224f5fc7e 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -74,13 +74,13 @@ io.avaje avaje-jsonb - 3.2 + 3.3 io.avaje avaje-jsonb-generator - 3.2 + 3.3 provided diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index ec28926b3..c4455eeed 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -74,7 +74,7 @@ io.avaje avaje-jsonb - 3.2 + 3.3 @@ -140,7 +140,7 @@ io.avaje avaje-jsonb-generator - 3.2 + 3.3 io.avaje diff --git a/tests/test-nima-htmx/pom.xml b/tests/test-nima-htmx/pom.xml index 61735f262..9d5565a7d 100644 --- a/tests/test-nima-htmx/pom.xml +++ b/tests/test-nima-htmx/pom.xml @@ -88,7 +88,7 @@ io.avaje avaje-jsonb-generator - 3.2 + 3.3 io.jstach diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 9273c1796..9d3245bfb 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -31,7 +31,7 @@ io.avaje avaje-jsonb - 3.2 + 3.3 io.helidon.webserver @@ -91,7 +91,7 @@ io.avaje avaje-jsonb-generator - 3.2 + 3.3 io.avaje diff --git a/tests/test-sigma/pom.xml b/tests/test-sigma/pom.xml index 5e78b3050..d41bc18dc 100644 --- a/tests/test-sigma/pom.xml +++ b/tests/test-sigma/pom.xml @@ -82,12 +82,12 @@ io.avaje avaje-jsonb - 3.2 + 3.3 io.avaje avaje-jsonb-generator - 3.2 + 3.3 provided From 940857dd3ab0f5e7faf246df9c97b98bb70533d3 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Wed, 23 Apr 2025 07:55:16 +1200 Subject: [PATCH 1288/1323] Support background token refresh when using AuthTokenProvider (#592) Supports refreshing an AuthToken in the background before it expires. By default, the background refresh is triggered 5 minutes before the expiration. --- .github/workflows/build.yml | 2 +- http-client/pom.xml | 56 +++++++++++++++++++ .../java/io/avaje/http/client/AuthToken.java | 11 ++++ .../java/io/avaje/http/client/BGInvoke.java | 25 +++++++++ .../avaje/http/client/DHttpClientBuilder.java | 9 +++ .../avaje/http/client/DHttpClientContext.java | 50 +++++++++++++++-- .../java/io/avaje/http/client/HttpClient.java | 18 ++++-- .../java21/io/avaje/http/client/BGInvoke.java | 12 ++++ .../io/avaje/http/client/AuthTokenTest.java | 12 ++++ .../http/client/DHttpClientContextTest.java | 3 +- .../http/client/DHttpClientRequestTest.java | 2 +- 11 files changed, 187 insertions(+), 13 deletions(-) create mode 100644 http-client/src/main/java/io/avaje/http/client/BGInvoke.java create mode 100644 http-client/src/main/java21/io/avaje/http/client/BGInvoke.java diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index dbe4de9c7..58dd2ccb4 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -10,7 +10,7 @@ jobs: strategy: fail-fast: false matrix: - java_version: [17, 21] + java_version: [21] os: [ubuntu-latest] steps: diff --git a/http-client/pom.xml b/http-client/pom.xml index 4301f4904..62674cd4e 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -94,6 +94,20 @@ + + + org.apache.maven.plugins + maven-jar-plugin + 3.3.0 + + + + true + + + + + org.apache.maven.plugins maven-compiler-plugin @@ -111,9 +125,51 @@ + + + base + + compile + + + 11 + + ${project.basedir}/src/main/java + + + + + + java21 + + compile + + + 21 + + ${project.basedir}/src/main/java21 + + ${project.build.outputDirectory}/META-INF/versions/21 + + + + + io.avaje + avaje-inject-maven-plugin + 11.4 + + + + process-sources + + provides + + + + diff --git a/http-client/src/main/java/io/avaje/http/client/AuthToken.java b/http-client/src/main/java/io/avaje/http/client/AuthToken.java index 7ff198273..4166dfb81 100644 --- a/http-client/src/main/java/io/avaje/http/client/AuthToken.java +++ b/http-client/src/main/java/io/avaje/http/client/AuthToken.java @@ -1,5 +1,6 @@ package io.avaje.http.client; +import java.time.Duration; import java.time.Instant; /** @@ -19,6 +20,11 @@ public interface AuthToken { */ boolean isExpired(); + /** + * Return the duration until expiry. + */ + Duration expiration(); + /** * Create an return a AuthToken with the given token and time it is valid until. */ @@ -51,5 +57,10 @@ public String token() { public boolean isExpired() { return Instant.now().isAfter(validUntil); } + + @Override + public Duration expiration() { + return Duration.between(Instant.now(), validUntil); + } } } diff --git a/http-client/src/main/java/io/avaje/http/client/BGInvoke.java b/http-client/src/main/java/io/avaje/http/client/BGInvoke.java new file mode 100644 index 000000000..c1d981e9f --- /dev/null +++ b/http-client/src/main/java/io/avaje/http/client/BGInvoke.java @@ -0,0 +1,25 @@ +package io.avaje.http.client; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; + +final class BGInvoke { + + static void invoke(Runnable task) { + ExecutorService executor = Executors.newSingleThreadExecutor(); + try { + executor.submit(task); + } finally { + executor.shutdown(); + try { + if (!executor.awaitTermination(60, TimeUnit.SECONDS)) { + executor.shutdownNow(); + } + } catch (InterruptedException e) { + executor.shutdownNow(); + Thread.currentThread().interrupt(); + } + } + } +} diff --git a/http-client/src/main/java/io/avaje/http/client/DHttpClientBuilder.java b/http-client/src/main/java/io/avaje/http/client/DHttpClientBuilder.java index 72e83fb1d..eb8e815aa 100644 --- a/http-client/src/main/java/io/avaje/http/client/DHttpClientBuilder.java +++ b/http-client/src/main/java/io/avaje/http/client/DHttpClientBuilder.java @@ -11,6 +11,7 @@ import java.net.CookieManager; import java.net.ProxySelector; import java.time.Duration; +import java.time.temporal.ChronoUnit; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -36,6 +37,7 @@ final class DHttpClientBuilder implements HttpClient.Builder, HttpClient.Builder private RetryHandler retryHandler; private Function errorHandler; private AuthTokenProvider authTokenProvider; + private Duration backgroundRefreshDuration = Duration.of(5, ChronoUnit.MINUTES); private CookieHandler cookieHandler = new CookieManager(); private java.net.http.HttpClient.Redirect redirect = java.net.http.HttpClient.Redirect.NORMAL; @@ -185,6 +187,7 @@ private DHttpClientContext buildClient() { errorHandler, buildListener(), authTokenProvider, + backgroundRefreshDuration, buildIntercept()); } @@ -257,6 +260,12 @@ public HttpClient.Builder authTokenProvider(AuthTokenProvider authTokenProvider) return this; } + @Override + public HttpClient.Builder backgroundTokenRefresh(Duration backgroundRefreshDuration) { + this.backgroundRefreshDuration = backgroundRefreshDuration; + return this; + } + @Override public HttpClient.Builder cookieHandler(CookieHandler cookieHandler) { this.cookieHandler = cookieHandler; diff --git a/http-client/src/main/java/io/avaje/http/client/DHttpClientContext.java b/http-client/src/main/java/io/avaje/http/client/DHttpClientContext.java index 64d9e3a62..3d9b66d3d 100644 --- a/http-client/src/main/java/io/avaje/http/client/DHttpClientContext.java +++ b/http-client/src/main/java/io/avaje/http/client/DHttpClientContext.java @@ -1,5 +1,7 @@ package io.avaje.http.client; +import io.avaje.applog.AppLog; + import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodType; import java.lang.reflect.Type; @@ -7,6 +9,7 @@ import java.net.http.HttpRequest; import java.net.http.HttpResponse; import java.time.Duration; +import java.time.Instant; import java.util.Collections; import java.util.List; import java.util.Map; @@ -18,8 +21,12 @@ import java.util.stream.Collectors; import java.util.stream.Stream; +import static java.lang.System.Logger.Level.WARNING; + final class DHttpClientContext implements HttpClient, SpiHttpClient { + private static final System.Logger log = AppLog.getLogger("io.avaje.http.client"); + static final String AUTHORIZATION = "Authorization"; private static final String BEARER = "Bearer "; @@ -33,6 +40,8 @@ final class DHttpClientContext implements HttpClient, SpiHttpClient { private final boolean withAuthToken; private final AuthTokenProvider authTokenProvider; private final AtomicReference tokenRef = new AtomicReference<>(); + private final AtomicReference backgroundRefreshLease = new AtomicReference<>(); + private final Duration backgroundRefreshDuration; private final LongAdder metricResTotal = new LongAdder(); private final LongAdder metricResError = new LongAdder(); @@ -50,6 +59,7 @@ final class DHttpClientContext implements HttpClient, SpiHttpClient { Function errorHandler, RequestListener requestListener, AuthTokenProvider authTokenProvider, + Duration backgroundRefreshDuration, RequestIntercept intercept) { this.httpClient = httpClient; this.baseUrl = baseUrl; @@ -59,6 +69,7 @@ final class DHttpClientContext implements HttpClient, SpiHttpClient { this.errorHandler = errorHandler; this.requestListener = requestListener; this.authTokenProvider = authTokenProvider; + this.backgroundRefreshDuration = backgroundRefreshDuration; this.withAuthToken = authTokenProvider != null; this.requestIntercept = intercept; } @@ -328,14 +339,45 @@ void beforeRequest(DHttpClientRequest request) { } private String authToken() { - AuthToken authToken = tokenRef.get(); - if (authToken == null || authToken.isExpired()) { - authToken = authTokenProvider.obtainToken(request().skipAuthToken()); - tokenRef.set(authToken); + final AuthToken authToken = tokenRef.get(); + if (authToken == null) { + return obtainNewAuthToken(); + } + final Duration expiration = authToken.expiration(); + if (expiration.isNegative()) { + return obtainNewAuthToken(); } + if (backgroundRefreshDuration != null && expiration.compareTo(backgroundRefreshDuration) < 0) { + backgroundTokenRequest(); + } + return authToken.token(); + } + + private String obtainNewAuthToken() { + final AuthToken authToken = authTokenProvider.obtainToken(request().skipAuthToken()); + tokenRef.set(authToken); return authToken.token(); } + private void backgroundTokenRequest() { + final Instant lease = backgroundRefreshLease.get(); + if (lease != null && Instant.now().isBefore(lease)) { + // a refresh is already in progress + return; + } + // other requests should not trigger a refresh for the next 10 seconds + backgroundRefreshLease.set(Instant.now().plusMillis(10_000)); + BGInvoke.invoke(this::backgroundNewTokenTask); + } + + private void backgroundNewTokenTask() { + try { + obtainNewAuthToken(); + } catch (Exception e) { + log.log(WARNING, "Error refreshing AuthToken in background", e); + } + } + String maxResponseBody(String body) { return body.length() > 1_000 ? body.substring(0, 1_000) + " ..." : body; } diff --git a/http-client/src/main/java/io/avaje/http/client/HttpClient.java b/http-client/src/main/java/io/avaje/http/client/HttpClient.java index 73cd70444..f00e33fa2 100644 --- a/http-client/src/main/java/io/avaje/http/client/HttpClient.java +++ b/http-client/src/main/java/io/avaje/http/client/HttpClient.java @@ -1,5 +1,9 @@ package io.avaje.http.client; +import io.avaje.inject.BeanScope; + +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLParameters; import java.net.Authenticator; import java.net.CookieHandler; import java.net.ProxySelector; @@ -8,11 +12,6 @@ import java.util.concurrent.Executor; import java.util.function.Function; -import javax.net.ssl.SSLContext; -import javax.net.ssl.SSLParameters; - -import io.avaje.inject.BeanScope; - /** * The HTTP client context that we use to build and process requests. * @@ -227,6 +226,15 @@ interface Builder { */ Builder authTokenProvider(AuthTokenProvider authTokenProvider); + /** + * Duration before token expiry where a background task will refresh the token. Defaults to 5 minutes. + *

    + * Set to null to disable background token refresh. + * + * @param backgroundTokenRefresh The duration before token expiry that triggers a background refresh. + */ + Builder backgroundTokenRefresh(Duration backgroundTokenRefresh); + /** * Set the underlying HttpClient to use. *

    diff --git a/http-client/src/main/java21/io/avaje/http/client/BGInvoke.java b/http-client/src/main/java21/io/avaje/http/client/BGInvoke.java new file mode 100644 index 000000000..39fc045f3 --- /dev/null +++ b/http-client/src/main/java21/io/avaje/http/client/BGInvoke.java @@ -0,0 +1,12 @@ +package io.avaje.http.client; + +import java.util.concurrent.Executors; + +final class BGInvoke { + + static void invoke(Runnable task) { + try (var executor = Executors.newVirtualThreadPerTaskExecutor()) { + executor.submit(task); + } + } +} diff --git a/http-client/src/test/java/io/avaje/http/client/AuthTokenTest.java b/http-client/src/test/java/io/avaje/http/client/AuthTokenTest.java index 530ad9cc4..7569f3c65 100644 --- a/http-client/src/test/java/io/avaje/http/client/AuthTokenTest.java +++ b/http-client/src/test/java/io/avaje/http/client/AuthTokenTest.java @@ -9,6 +9,9 @@ import java.net.http.HttpResponse; import java.time.Instant; +import java.time.temporal.ChronoUnit; + +import static org.assertj.core.api.Assertions.assertThat; public class AuthTokenTest { @@ -41,6 +44,15 @@ public AuthToken obtainToken(HttpClientRequest tokenRequest) { } } + @Test + void expiration() { + Instant plus = Instant.now().plus(120, ChronoUnit.SECONDS); + AuthToken authToken = AuthToken.of("foo", plus); + + assertThat(authToken.isExpired()).isFalse(); + assertThat(authToken.expiration().toSeconds()).isBetween(118L, 120L); + } + @Disabled @Test void sendEmail() { diff --git a/http-client/src/test/java/io/avaje/http/client/DHttpClientContextTest.java b/http-client/src/test/java/io/avaje/http/client/DHttpClientContextTest.java index 8fdea96cd..2e13c3a49 100644 --- a/http-client/src/test/java/io/avaje/http/client/DHttpClientContextTest.java +++ b/http-client/src/test/java/io/avaje/http/client/DHttpClientContextTest.java @@ -1,6 +1,5 @@ package io.avaje.http.client; -import org.example.github.BasicClientInterface; import org.junit.jupiter.api.Test; import java.nio.charset.StandardCharsets; @@ -9,7 +8,7 @@ class DHttpClientContextTest { - private final DHttpClientContext context = new DHttpClientContext(null, null, null, null, null, null, null, null, null); + private final DHttpClientContext context = new DHttpClientContext(null, null, null, null, null, null, null, null, null, null); @Test void gzip_gzipDecode() { diff --git a/http-client/src/test/java/io/avaje/http/client/DHttpClientRequestTest.java b/http-client/src/test/java/io/avaje/http/client/DHttpClientRequestTest.java index ac7e20619..cd0ff90b6 100644 --- a/http-client/src/test/java/io/avaje/http/client/DHttpClientRequestTest.java +++ b/http-client/src/test/java/io/avaje/http/client/DHttpClientRequestTest.java @@ -10,7 +10,7 @@ class DHttpClientRequestTest { - final DHttpClientContext context = new DHttpClientContext(null, null, null, null, null, null, null, null, null); + final DHttpClientContext context = new DHttpClientContext(null, null, null, null, null, null, null, null, null, null); @Test void suppressLogging_listenerEvent_expect_suppressedPayloadContent() { From 551a5cb8023ffeb0a5b6bf4291fbe51d2140787f Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Wed, 23 Apr 2025 06:43:29 -0400 Subject: [PATCH 1289/1323] Fix error handler controllers failing test-compilation (#593) Co-authored-by: Rob Bygrave --- .../http/generator/core/BaseProcessor.java | 4 +-- .../http/generator/core/TestClientWriter.java | 5 ++-- .../java/org/example/web/ErrorController.java | 29 +++++++++++++++++++ 3 files changed, 34 insertions(+), 4 deletions(-) create mode 100644 tests/test-jex/src/main/java/org/example/web/ErrorController.java diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java index 02bc89ec4..8ea2f1872 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/BaseProcessor.java @@ -187,8 +187,8 @@ private void writeClientAdapter(ControllerReader reader) { try { if (reader.beanType().getInterfaces().isEmpty() - && "java.lang.Object".equals(reader.beanType().getSuperclass().toString())) { - new TestClientWriter(reader).write(); + && "java.lang.Object".equals(reader.beanType().getSuperclass().toString()) + && new TestClientWriter(reader).write()) { clientFQNs.add(reader.beanType().getQualifiedName().toString() + "TestAPI"); } } catch (final IOException e) { diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/TestClientWriter.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/TestClientWriter.java index a85c50a62..4ea2c74cc 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/TestClientWriter.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/TestClientWriter.java @@ -54,12 +54,13 @@ protected String initPackageName(String originName) { return dp > -1 ? originName.substring(0, dp) : null; } - void write() { - if (methods.isEmpty()) return; + boolean write() { + if (methods.isEmpty()) return false; writePackage(); writeImports(); writeClassStart(); writeAddRoutes(); + return true; } protected void writePackage() { diff --git a/tests/test-jex/src/main/java/org/example/web/ErrorController.java b/tests/test-jex/src/main/java/org/example/web/ErrorController.java new file mode 100644 index 000000000..4ebeeaa61 --- /dev/null +++ b/tests/test-jex/src/main/java/org/example/web/ErrorController.java @@ -0,0 +1,29 @@ +package org.example.web; + +import io.avaje.http.api.Controller; +import io.avaje.http.api.ExceptionHandler; +import io.avaje.http.api.Filter; +import io.avaje.http.api.Produces; +import io.avaje.jex.http.Context; +import io.avaje.jex.http.HttpFilter.FilterChain; + +@Controller +public class ErrorController { + + @Filter + void filter(FilterChain chain) { + // do nothing + chain.proceed(); + } + + @ExceptionHandler + String exception(RuntimeException ex) { + return "Err: " + ex; + } + + @Produces(statusCode = 501) + @ExceptionHandler + HelloDto exceptionCtx(IllegalAccessException ex, Context ctx) { + return null; + } +} From 65b186ab58b87012e67b8fd1cd589c5130a7c4ed Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sun, 27 Apr 2025 17:47:56 -0400 Subject: [PATCH 1290/1323] Fix Helidon path openapi generation (#596) * Update OpenAPIController.java * add another openAPI test to javalin * fix helidon path openAPI generation --- .../core/openapi/MethodParamDocBuilder.java | 2 +- .../helidon/nima/ControllerWriter.java | 6 +- .../myapp/web/test/OpenAPIController.java | 11 +- .../src/test/resources/expectedOpenApi.json | 57 +++- tests/test-nima-jsonb/pom.xml | 13 + .../java/org/example/OpenAPIController.java | 113 ++++++++ .../http/generator/NimaProcessorTest.java | 35 +++ .../src/test/resources/expectedOpenApi.json | 259 ++++++++++++++++++ 8 files changed, 485 insertions(+), 11 deletions(-) create mode 100644 tests/test-nima-jsonb/src/main/java/org/example/OpenAPIController.java create mode 100644 tests/test-nima-jsonb/src/test/resources/expectedOpenApi.json diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/MethodParamDocBuilder.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/MethodParamDocBuilder.java index 80485ff09..21428679c 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/MethodParamDocBuilder.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/MethodParamDocBuilder.java @@ -81,7 +81,7 @@ private String requestMedia(Schema schema) { if (schema instanceof StringSchema) { return APP_TXT; } - boolean asForm = (paramType == ParamType.FORM); + boolean asForm = paramType == ParamType.FORM; return asForm ? APP_FORM : APP_JSON; } diff --git a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java index e47da1301..409f68422 100644 --- a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java +++ b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerWriter.java @@ -99,6 +99,9 @@ private void writeAddRoutes() { writeRoutes(methods); for (final ControllerMethodWriter methodWriter : methods) { methodWriter.writeHandler(isRequestScoped()); + if (!reader.isDocHidden()) { + methodWriter.buildApiDocumentation(); + } } } @@ -108,9 +111,6 @@ private void writeRoutes(List methods) { for (final ControllerMethodWriter methodWriter : methods) { methodWriter.writeRule(); - if (!reader.isDocHidden()) { - methodWriter.buildApiDocumentation(); - } } writer.append(" }").eol().eol(); } diff --git a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/OpenAPIController.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/OpenAPIController.java index 3912649e2..5b5aae937 100644 --- a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/OpenAPIController.java +++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/OpenAPIController.java @@ -3,7 +3,9 @@ import java.util.List; import io.avaje.http.api.Controller; +import io.avaje.http.api.Delete; import io.avaje.http.api.Get; +import io.avaje.http.api.Header; import io.avaje.http.api.MediaType; import io.avaje.http.api.OpenAPIResponse; import io.avaje.http.api.OpenAPIResponses; @@ -11,6 +13,7 @@ import io.avaje.http.api.Post; import io.avaje.http.api.Produces; import io.avaje.http.api.Put; +import io.avaje.http.api.QueryParam; import io.javalin.http.Context; import io.swagger.v3.oas.annotations.OpenAPIDefinition; import io.swagger.v3.oas.annotations.enums.SecuritySchemeIn; @@ -93,10 +96,16 @@ Person testPostList(List m) { @Produces(value = MediaType.TEXT_PLAIN, statusCode = 203) @OpenAPIResponse(responseCode = 204, type = String.class) String testDefaultStatus(Context ctx) { - if (ctx.contentType().equals(MediaType.APPLICATION_PDF)) { + if (MediaType.APPLICATION_PDF.equals(ctx.contentType())) { ctx.status(204); return ""; } return "only partial info"; } + + @Delete("/delete/{type}") + String testPathParam(String type, @QueryParam String lastName, @Header String header) { + + return "only partial info"; + } } diff --git a/tests/test-javalin-jsonb/src/test/resources/expectedOpenApi.json b/tests/test-javalin-jsonb/src/test/resources/expectedOpenApi.json index 2a354cb45..45df6422d 100644 --- a/tests/test-javalin-jsonb/src/test/resources/expectedOpenApi.json +++ b/tests/test-javalin-jsonb/src/test/resources/expectedOpenApi.json @@ -5,12 +5,12 @@ "description" : "Example Javalin controllers with Java and Maven", "version" : "" }, - "servers" : [ - { - "url" : "localhost:8080", - "description" : "local testing" - } - ], + "servers" : [ + { + "url" : "localhost:8080", + "description" : "local testing" + } + ], "tags" : [ { "name" : "tag1", @@ -18,6 +18,51 @@ } ], "paths" : { + "/openapi/delete/{type}" : { + "delete" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "parameters" : [ + { + "name" : "type", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "name" : "lastName", + "in" : "query", + "schema" : { + "type" : "string" + } + }, + { + "name" : "header", + "in" : "header", + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, "/openapi/get" : { "get" : { "tags" : [ diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 9d3245bfb..c5e19989b 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -13,11 +13,24 @@ 21 + 2.2.30 UTF-8 false + + io.swagger.core.v3 + swagger-annotations + ${swagger.version} + + + com.fasterxml.jackson.core + jackson-databind + ${jackson.version} + + + io.avaje avaje-inject diff --git a/tests/test-nima-jsonb/src/main/java/org/example/OpenAPIController.java b/tests/test-nima-jsonb/src/main/java/org/example/OpenAPIController.java new file mode 100644 index 000000000..caa77e14e --- /dev/null +++ b/tests/test-nima-jsonb/src/main/java/org/example/OpenAPIController.java @@ -0,0 +1,113 @@ +package org.example; + +import java.util.List; + +import io.avaje.http.api.Controller; +import io.avaje.http.api.Delete; +import io.avaje.http.api.Get; +import io.avaje.http.api.Header; +import io.avaje.http.api.MediaType; +import io.avaje.http.api.OpenAPIResponse; +import io.avaje.http.api.OpenAPIResponses; +import io.avaje.http.api.Path; +import io.avaje.http.api.Post; +import io.avaje.http.api.Produces; +import io.avaje.http.api.Put; +import io.avaje.http.api.QueryParam; +import io.helidon.webserver.http.ServerRequest; +import io.helidon.webserver.http.ServerResponse; +import io.swagger.v3.oas.annotations.OpenAPIDefinition; +import io.swagger.v3.oas.annotations.enums.SecuritySchemeIn; +import io.swagger.v3.oas.annotations.enums.SecuritySchemeType; +import io.swagger.v3.oas.annotations.info.Info; +import io.swagger.v3.oas.annotations.security.SecurityScheme; +import io.swagger.v3.oas.annotations.tags.Tag; + +@OpenAPIDefinition( + info = + @Info( + title = "Example service", + description = "Example Helidon controllers with Java and Maven")) +@Controller +@Path("openapi/") +@SecurityScheme( + type = SecuritySchemeType.APIKEY, + in = SecuritySchemeIn.QUERY, + name = "JWT", + paramName = "access_token", + description = + "JSON Web Tokens are an open, industry standard RFC 7519 method for representing claims securely between two parties.") +public class OpenAPIController { + + /** + * Example of Open API Get (up to the first period is the summary). When using Javalin Context + * only
    + * This Javadoc description is added to the generated openapi.json + * + * @return funny phrase (this part of the javadoc is added to the response desc) + */ + @Get("/get") + @Produces(MediaType.TEXT_PLAIN) + @OpenAPIResponse(responseCode = 200, type = String.class) + void ctxEndpoint(ServerRequest req, ServerResponse res) {} + + /** + * Standard Post. uses tag annotation to add tags to openapi json + * + * @param b the body (this is used for generated request body desc) + * @return the response body (from javadoc) + */ + @Post("/post") + @Tag(name = "tag1", description = "this is added to openapi tags") + @OpenAPIResponse(responseCode = 200, description = "overrides @return javadoc description") + @OpenAPIResponse(responseCode = 201) + @OpenAPIResponse( + responseCode = 400, + description = "User not found (Will not have an associated response schema)") + @OpenAPIResponse( + responseCode = 500, + description = "Some other Error (Will have this error class as the response class)", + type = ErrorResponse.class) + Person testPost(Person b) { + return new Person(0, "baby"); + } + + public static class ErrorResponse { + + public String id; + public String text; + } + + /** + * Standard Post. The Deprecated annotation adds "deprecacted:true" to the generated json + * + * @param m the body + * @return the response body (from javadoc) + */ + @Deprecated + @Post("/post1") + @OpenAPIResponses({ + @OpenAPIResponse(responseCode = 400, description = "User not found"), + @OpenAPIResponse( + responseCode = 500, + description = "Some other Error", + type = ErrorResponse.class) + }) + Person testPostList(List m) { + return new Person(0, "baby"); + } + + @Put("/put") + @Produces(value = MediaType.TEXT_PLAIN, statusCode = 203) + @OpenAPIResponse(responseCode = 204, type = String.class) + String testDefaultStatus() { + + return "only partial info"; + } + + @Delete("/delete/{type}") + String testPathParam(String type, @QueryParam String lastName, @Header String header) { + + return "only partial info"; + } +} diff --git a/tests/test-nima-jsonb/src/test/java/io/avaje/http/generator/NimaProcessorTest.java b/tests/test-nima-jsonb/src/test/java/io/avaje/http/generator/NimaProcessorTest.java index 8f22b8177..10aeb7379 100644 --- a/tests/test-nima-jsonb/src/test/java/io/avaje/http/generator/NimaProcessorTest.java +++ b/tests/test-nima-jsonb/src/test/java/io/avaje/http/generator/NimaProcessorTest.java @@ -21,6 +21,8 @@ import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; +import com.fasterxml.jackson.databind.ObjectMapper; + import io.avaje.http.generator.helidon.nima.HelidonProcessor; class NimaProcessorTest { @@ -76,4 +78,37 @@ private Iterable getSourceFiles(String source) throws Exception final Set fileKinds = Collections.singleton(Kind.SOURCE); return files.list(StandardLocation.SOURCE_PATH, "", fileKinds, true); } + + @Test + public void testOpenAPIGeneration() throws Exception { + final var source = Paths.get("src").toAbsolutePath().toString(); + // OpenAPIController + final var files = getSourceFiles(source); + + Iterable openAPIController = null; + for (final var file : files) { + if (file.isNameCompatible("OpenAPIController", Kind.SOURCE)) + openAPIController = List.of(file); + } + final var compiler = ToolProvider.getSystemJavaCompiler(); + + final var task = + compiler.getTask( + new PrintWriter(System.out), + null, + null, + List.of("--release=21"), + null, + openAPIController); + task.setProcessors(List.of(new HelidonProcessor())); + + assertThat(task.call()).isTrue(); + + final var mapper = new ObjectMapper(); + final var expectedOpenApiJson = + mapper.readTree(new File("src/test/resources/expectedOpenApi.json")); + final var generatedOpenApi = mapper.readTree(new File("openapi.json")); + + assert expectedOpenApiJson.equals(generatedOpenApi); + } } diff --git a/tests/test-nima-jsonb/src/test/resources/expectedOpenApi.json b/tests/test-nima-jsonb/src/test/resources/expectedOpenApi.json new file mode 100644 index 000000000..6a5e636e9 --- /dev/null +++ b/tests/test-nima-jsonb/src/test/resources/expectedOpenApi.json @@ -0,0 +1,259 @@ +{ + "openapi" : "3.0.1", + "info" : { + "title" : "Example service", + "description" : "Example Helidon controllers with Java and Maven", + "version" : "" + }, + "servers" : [ + { + "url" : "localhost:8080", + "description" : "local testing" + } + ], + "tags" : [ + { + "name" : "tag1", + "description" : "this is added to openapi tags" + } + ], + "paths" : { + "/openapi/delete/{type}" : { + "delete" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "parameters" : [ + { + "name" : "type", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "name" : "lastName", + "in" : "query", + "schema" : { + "type" : "string" + } + }, + { + "name" : "header", + "in" : "header", + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/openapi/get" : { + "get" : { + "tags" : [ + + ], + "summary" : "Example of Open API Get (up to the first period is the summary)", + "description" : "When using Javalin Context only This Javadoc description is added to the generated openapi.json", + "responses" : { + "200" : { + "description" : "funny phrase (this part of the javadoc is added to the response desc)", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/openapi/post" : { + "post" : { + "tags" : [ + "tag1" + ], + "summary" : "Standard Post", + "description" : "uses tag annotation to add tags to openapi json", + "requestBody" : { + "description" : "the body (this is used for generated request body desc)", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Person" + } + } + }, + "required" : true + }, + "responses" : { + "200" : { + "description" : "overrides @return javadoc description", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Person" + } + } + } + }, + "201" : { + "description" : "the response body (from javadoc)", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Person" + } + } + } + }, + "400" : { + "description" : "User not found (Will not have an associated response schema)" + }, + "500" : { + "description" : "Some other Error (Will have this error class as the response class)", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ErrorResponse" + } + } + } + } + } + } + }, + "/openapi/post1" : { + "post" : { + "tags" : [ + + ], + "summary" : "Standard Post", + "description" : "The Deprecated annotation adds \"deprecacted:true\" to the generated json", + "requestBody" : { + "description" : "the body", + "content" : { + "application/json" : { + "schema" : { + "type" : "array", + "items" : { + "$ref" : "#/components/schemas/Person" + } + } + } + }, + "required" : true + }, + "responses" : { + "400" : { + "description" : "User not found" + }, + "500" : { + "description" : "Some other Error", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ErrorResponse" + } + } + } + }, + "201" : { + "description" : "the response body (from javadoc)", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Person" + } + } + } + } + }, + "deprecated" : true + } + }, + "/openapi/put" : { + "put" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "responses" : { + "204" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + }, + "203" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + } + }, + "components" : { + "schemas" : { + "ErrorResponse" : { + "type" : "object", + "properties" : { + "id" : { + "type" : "string" + }, + "text" : { + "type" : "string" + } + } + }, + "Person" : { + "type" : "object", + "properties" : { + "id" : { + "type" : "integer", + "format" : "int64", + "nullable" : false + }, + "name" : { + "type" : "string" + } + } + } + }, + "securitySchemes" : { + "JWT" : { + "type" : "apiKey", + "description" : "JSON Web Tokens are an open, industry standard RFC 7519 method for representing claims securely between two parties.", + "name" : "access_token", + "in" : "query" + } + } + } +} \ No newline at end of file From c6fd88cfea86e501353af7620d7936d9dcb0e633 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Mon, 28 Apr 2025 22:51:46 -0400 Subject: [PATCH 1291/1323] 3.3-RC1 (#598) --- .gitignore | 1 + aws-cognito/http-client-authtoken/pom.xml | 2 +- htmx-api/pom.xml | 2 +- htmx-nima-jstache/pom.xml | 2 +- htmx-nima/pom.xml | 4 ++-- http-api-javalin/pom.xml | 2 +- http-api/pom.xml | 2 +- http-client-gson-adapter/pom.xml | 4 ++-- http-client-moshi-adapter/pom.xml | 4 ++-- http-client/pom.xml | 2 +- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 2 +- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-generator-sigma/pom.xml | 2 +- http-inject-plugin/pom.xml | 2 +- pom.xml | 4 ++-- tests/pom.xml | 2 +- tests/test-client-generation/pom.xml | 2 +- tests/test-client/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-htmx/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- tests/test-sigma/pom.xml | 2 +- 28 files changed, 32 insertions(+), 31 deletions(-) diff --git a/.gitignore b/.gitignore index 886650d31..e8262d9ff 100644 --- a/.gitignore +++ b/.gitignore @@ -19,3 +19,4 @@ tests/test-sigma/io.avaje.jsonb.spi.JsonbExtension tests/test-sigma/*.txt tests/test-javalin-jsonb/*.txt tests/test-nima-jsonb/*.txt +*.versionsBackup diff --git a/aws-cognito/http-client-authtoken/pom.xml b/aws-cognito/http-client-authtoken/pom.xml index ab6948f33..e3b09a6ec 100644 --- a/aws-cognito/http-client-authtoken/pom.xml +++ b/aws-cognito/http-client-authtoken/pom.xml @@ -17,7 +17,7 @@ io.avaje avaje-http-client - 3.2 + 3.3-RC1 diff --git a/htmx-api/pom.xml b/htmx-api/pom.xml index 0ebd189ac..d25a3721b 100644 --- a/htmx-api/pom.xml +++ b/htmx-api/pom.xml @@ -6,7 +6,7 @@ io.avaje avaje-http-parent - 3.2 + 3.3-RC1 avaje-htmx-api diff --git a/htmx-nima-jstache/pom.xml b/htmx-nima-jstache/pom.xml index 9fcbc6ae3..9de29727e 100644 --- a/htmx-nima-jstache/pom.xml +++ b/htmx-nima-jstache/pom.xml @@ -6,7 +6,7 @@ io.avaje avaje-http-parent - 3.2 + 3.3-RC1 avaje-htmx-nima-jstache diff --git a/htmx-nima/pom.xml b/htmx-nima/pom.xml index 6ee0b4a3c..ed882764d 100644 --- a/htmx-nima/pom.xml +++ b/htmx-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje avaje-http-parent - 3.2 + 3.3-RC1 avaje-htmx-nima @@ -21,7 +21,7 @@ io.avaje avaje-htmx-api - 3.2 + 3.3-RC1 io.helidon.webserver diff --git a/http-api-javalin/pom.xml b/http-api-javalin/pom.xml index f6a191ba0..55493fb52 100644 --- a/http-api-javalin/pom.xml +++ b/http-api-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.2 + 3.3-RC1 .. diff --git a/http-api/pom.xml b/http-api/pom.xml index 90fea9b1c..c64876c80 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.2 + 3.3-RC1 .. diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index ab6f9962b..95eb0a698 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.2 + 3.3-RC1 avaje-http-client-gson @@ -20,7 +20,7 @@ io.avaje avaje-http-client - 3.2 + 3.3-RC1 provided diff --git a/http-client-moshi-adapter/pom.xml b/http-client-moshi-adapter/pom.xml index c4fd304f9..10b1c0f67 100644 --- a/http-client-moshi-adapter/pom.xml +++ b/http-client-moshi-adapter/pom.xml @@ -3,7 +3,7 @@ io.avaje avaje-http-parent - 3.2 + 3.3-RC1 avaje-http-client-moshi @@ -19,7 +19,7 @@ io.avaje avaje-http-client - 3.2 + 3.3-RC1 provided diff --git a/http-client/pom.xml b/http-client/pom.xml index 62674cd4e..7d82817ed 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.2 + 3.3-RC1 avaje-http-client diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index d7d2024d3..9e4748622 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.2 + 3.3-RC1 avaje-http-client-generator diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 2901c5083..e32981597 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.2 + 3.3-RC1 avaje-http-generator-core diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index b06e245a5..e16aac01f 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 3.2 + 3.3-RC1 avaje-http-helidon-generator diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index 5cc411981..2482ebf9a 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.2 + 3.3-RC1 avaje-http-javalin-generator diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index 49aab1980..61bf1e9b9 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.2 + 3.3-RC1 avaje-http-jex-generator diff --git a/http-generator-sigma/pom.xml b/http-generator-sigma/pom.xml index c6d96c610..d01fd5790 100644 --- a/http-generator-sigma/pom.xml +++ b/http-generator-sigma/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.2 + 3.3-RC1 avaje-http-sigma-generator diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index 9dd6109a5..2834fc7e9 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.2 + 3.3-RC1 .. diff --git a/pom.xml b/pom.xml index a8d902e43..b7b019a62 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-parent - 3.2 + 3.3-RC1 pom @@ -23,7 +23,7 @@ 2.14.2 3.0-RC10 1.42 - 2025-03-30T19:22:50Z + 2025-04-27T22:02:10Z ${project.build.directory}${file.separator}module-info.shade diff --git a/tests/pom.xml b/tests/pom.xml index 774bbcc07..c023c1c13 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 3.2 + 3.3-RC1 tests diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index 8daa31e24..11b5565f2 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 3.2 + 3.3-RC1 test-client-generation diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index 21664f78c..9bdc729c3 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 3.2 + 3.3-RC1 test-client diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 224f5fc7e..5c3f801c1 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 3.2 + 3.3-RC1 test-javalin-jsonb diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index e9ee8548e..f13214958 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 3.2 + 3.3-RC1 test-javalin diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index c4455eeed..734972f16 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 3.2 + 3.3-RC1 test-jex diff --git a/tests/test-nima-htmx/pom.xml b/tests/test-nima-htmx/pom.xml index 9d5565a7d..405500527 100644 --- a/tests/test-nima-htmx/pom.xml +++ b/tests/test-nima-htmx/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 3.2 + 3.3-RC1 test-nima-htmx diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index c5e19989b..ddc120cd7 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 3.2 + 3.3-RC1 test-nima-jsonb diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index 07cf2f10b..3fd382be1 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 3.2 + 3.3-RC1 test-nima diff --git a/tests/test-sigma/pom.xml b/tests/test-sigma/pom.xml index d41bc18dc..b291caa9d 100644 --- a/tests/test-sigma/pom.xml +++ b/tests/test-sigma/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 3.2 + 3.3-RC1 test-sigma From f979dbcb24d35881218ed78730be3f26283e8f13 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 29 Apr 2025 19:15:11 +1200 Subject: [PATCH 1292/1323] No effective change - add more parameters to test openapi.json (#599) Followup PR to come related to incorrect generated openapi.json --- .../myapp/web/test/OpenAPIController.java | 3 +- .../src/main/resources/public/openapi.json | 59 ++ .../http/generator/JavalinProcessorTest.java | 6 +- .../src/test/resources/expectedOpenApi.json | 522 +++++++++--------- 4 files changed, 332 insertions(+), 258 deletions(-) diff --git a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/OpenAPIController.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/OpenAPIController.java index 5b5aae937..2086da866 100644 --- a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/OpenAPIController.java +++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/OpenAPIController.java @@ -104,8 +104,7 @@ String testDefaultStatus(Context ctx) { } @Delete("/delete/{type}") - String testPathParam(String type, @QueryParam String lastName, @Header String header) { - + String testPathParam(String type, @QueryParam String lastName, @QueryParam("q-2") String param2, @Header String contentLength, @Header("x-oh") String otherHeader) { return "only partial info"; } } diff --git a/tests/test-javalin-jsonb/src/main/resources/public/openapi.json b/tests/test-javalin-jsonb/src/main/resources/public/openapi.json index ff593dbf5..1506e2c4d 100644 --- a/tests/test-javalin-jsonb/src/main/resources/public/openapi.json +++ b/tests/test-javalin-jsonb/src/main/resources/public/openapi.json @@ -970,6 +970,65 @@ } } }, + "/openapi/delete/{type}" : { + "delete" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "parameters" : [ + { + "name" : "type", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "name" : "lastName", + "in" : "query", + "schema" : { + "type" : "string" + } + }, + { + "name" : "param2", + "in" : "query", + "schema" : { + "type" : "string" + } + }, + { + "name" : "contentLength", + "in" : "header", + "schema" : { + "type" : "string" + } + }, + { + "name" : "otherHeader", + "in" : "header", + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, "/openapi/get" : { "get" : { "tags" : [ diff --git a/tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/JavalinProcessorTest.java b/tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/JavalinProcessorTest.java index b2262c874..49d1c028b 100644 --- a/tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/JavalinProcessorTest.java +++ b/tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/JavalinProcessorTest.java @@ -170,9 +170,11 @@ public void testOpenAPIGeneration() throws Exception { final var mapper = new ObjectMapper(); final var expectedOpenApiJson = mapper.readTree(new File("src/test/resources/expectedOpenApi.json")); - final var generatedOpenApi = mapper.readTree(new File("openapi.json")); + File file = new File("openapi.json"); + // Files.copy(file.toPath(), Paths.get("other.json")); + final var generatedOpenApi = mapper.readTree(file); - assert expectedOpenApiJson.equals(generatedOpenApi); + assertThat(generatedOpenApi).isEqualTo(expectedOpenApiJson); } @Test diff --git a/tests/test-javalin-jsonb/src/test/resources/expectedOpenApi.json b/tests/test-javalin-jsonb/src/test/resources/expectedOpenApi.json index 45df6422d..407ae6305 100644 --- a/tests/test-javalin-jsonb/src/test/resources/expectedOpenApi.json +++ b/tests/test-javalin-jsonb/src/test/resources/expectedOpenApi.json @@ -1,259 +1,273 @@ { - "openapi" : "3.0.1", - "info" : { - "title" : "Example service", - "description" : "Example Javalin controllers with Java and Maven", - "version" : "" - }, - "servers" : [ - { - "url" : "localhost:8080", - "description" : "local testing" - } - ], - "tags" : [ - { - "name" : "tag1", - "description" : "this is added to openapi tags" - } - ], - "paths" : { - "/openapi/delete/{type}" : { - "delete" : { - "tags" : [ - - ], - "summary" : "", - "description" : "", - "parameters" : [ - { - "name" : "type", - "in" : "path", - "required" : true, - "schema" : { - "type" : "string" - } - }, - { - "name" : "lastName", - "in" : "query", - "schema" : { - "type" : "string" - } - }, - { - "name" : "header", - "in" : "header", - "schema" : { - "type" : "string" - } - } - ], - "responses" : { - "200" : { - "description" : "", - "content" : { - "application/json" : { - "schema" : { - "type" : "string" - } - } - } - } - } - } - }, - "/openapi/get" : { - "get" : { - "tags" : [ + "openapi" : "3.0.1", + "info" : { + "title" : "Example service", + "description" : "Example Javalin controllers with Java and Maven", + "version" : "" + }, + "servers" : [ + { + "url" : "localhost:8080", + "description" : "local testing" + } + ], + "tags" : [ + { + "name" : "tag1", + "description" : "this is added to openapi tags" + } + ], + "paths" : { + "/openapi/delete/{type}" : { + "delete" : { + "tags" : [ - ], - "summary" : "Example of Open API Get (up to the first period is the summary)", - "description" : "When using Javalin Context only This Javadoc description is added to the generated openapi.json", - "responses" : { - "200" : { - "description" : "funny phrase (this part of the javadoc is added to the response desc)", - "content" : { - "text/plain" : { - "schema" : { - "type" : "string" - } - } - } - } - } - } - }, - "/openapi/post" : { - "post" : { - "tags" : [ - "tag1" - ], - "summary" : "Standard Post", - "description" : "uses tag annotation to add tags to openapi json", - "requestBody" : { - "description" : "the body (this is used for generated request body desc)", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/Person" - } - } - }, - "required" : true - }, - "responses" : { - "200" : { - "description" : "overrides @return javadoc description", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/Person" - } - } - } - }, - "201" : { - "description" : "the response body (from javadoc)", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/Person" - } - } - } - }, - "400" : { - "description" : "User not found (Will not have an associated response schema)" - }, - "500" : { - "description" : "Some other Error (Will have this error class as the response class)", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ErrorResponse" - } - } - } - } - } - } - }, - "/openapi/post1" : { - "post" : { - "tags" : [ + ], + "summary" : "", + "description" : "", + "parameters" : [ + { + "name" : "type", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "name" : "lastName", + "in" : "query", + "schema" : { + "type" : "string" + } + }, + { + "name" : "param2", + "in" : "query", + "schema" : { + "type" : "string" + } + }, + { + "name" : "contentLength", + "in" : "header", + "schema" : { + "type" : "string" + } + }, + { + "name" : "otherHeader", + "in" : "header", + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/openapi/get" : { + "get" : { + "tags" : [ - ], - "summary" : "Standard Post", - "description" : "The Deprecated annotation adds \"deprecacted:true\" to the generated json", - "requestBody" : { - "description" : "the body", - "content" : { - "application/json" : { - "schema" : { - "type" : "array", - "items" : { - "$ref" : "#/components/schemas/Person" - } - } - } - }, - "required" : true - }, - "responses" : { - "400" : { - "description" : "User not found" - }, - "500" : { - "description" : "Some other Error", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ErrorResponse" - } - } - } - }, - "201" : { - "description" : "the response body (from javadoc)", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/Person" - } - } - } - } - }, - "deprecated" : true - } - }, - "/openapi/put" : { - "put" : { - "tags" : [ + ], + "summary" : "Example of Open API Get (up to the first period is the summary)", + "description" : "When using Javalin Context only This Javadoc description is added to the generated openapi.json", + "responses" : { + "200" : { + "description" : "funny phrase (this part of the javadoc is added to the response desc)", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, + "/openapi/post" : { + "post" : { + "tags" : [ + "tag1" + ], + "summary" : "Standard Post", + "description" : "uses tag annotation to add tags to openapi json", + "requestBody" : { + "description" : "the body (this is used for generated request body desc)", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Person" + } + } + }, + "required" : true + }, + "responses" : { + "200" : { + "description" : "overrides @return javadoc description", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Person" + } + } + } + }, + "201" : { + "description" : "the response body (from javadoc)", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Person" + } + } + } + }, + "400" : { + "description" : "User not found (Will not have an associated response schema)" + }, + "500" : { + "description" : "Some other Error (Will have this error class as the response class)", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ErrorResponse" + } + } + } + } + } + } + }, + "/openapi/post1" : { + "post" : { + "tags" : [ - ], - "summary" : "", - "description" : "", - "responses" : { - "204" : { - "description" : "", - "content" : { - "text/plain" : { - "schema" : { - "type" : "string" - } - } - } - }, - "203" : { - "description" : "", - "content" : { - "text/plain" : { - "schema" : { - "type" : "string" - } - } - } - } - } - } - } - }, - "components" : { - "schemas" : { - "ErrorResponse" : { - "type" : "object", - "properties" : { - "id" : { - "type" : "string" - }, - "text" : { - "type" : "string" - } - } - }, - "Person" : { - "type" : "object", - "properties" : { - "id" : { - "type" : "integer", - "format" : "int64", - "nullable" : false - }, - "name" : { - "type" : "string" - } - } - } - }, - "securitySchemes" : { - "JWT" : { - "type" : "apiKey", - "description" : "JSON Web Tokens are an open, industry standard RFC 7519 method for representing claims securely between two parties.", - "name" : "access_token", - "in" : "query" - } - } - } + ], + "summary" : "Standard Post", + "description" : "The Deprecated annotation adds \"deprecacted:true\" to the generated json", + "requestBody" : { + "description" : "the body", + "content" : { + "application/json" : { + "schema" : { + "type" : "array", + "items" : { + "$ref" : "#/components/schemas/Person" + } + } + } + }, + "required" : true + }, + "responses" : { + "400" : { + "description" : "User not found" + }, + "500" : { + "description" : "Some other Error", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ErrorResponse" + } + } + } + }, + "201" : { + "description" : "the response body (from javadoc)", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Person" + } + } + } + } + }, + "deprecated" : true + } + }, + "/openapi/put" : { + "put" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "responses" : { + "204" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + }, + "203" : { + "description" : "", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + } + }, + "components" : { + "schemas" : { + "ErrorResponse" : { + "type" : "object", + "properties" : { + "id" : { + "type" : "string" + }, + "text" : { + "type" : "string" + } + } + }, + "Person" : { + "type" : "object", + "properties" : { + "id" : { + "type" : "integer", + "format" : "int64", + "nullable" : false + }, + "name" : { + "type" : "string" + } + } + } + }, + "securitySchemes" : { + "JWT" : { + "type" : "apiKey", + "description" : "JSON Web Tokens are an open, industry standard RFC 7519 method for representing claims securely between two parties.", + "name" : "access_token", + "in" : "query" + } + } + } } From c25de392f0d3ad2e738d3d92f7c49d17d5d0a73a Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Wed, 30 Apr 2025 00:17:38 +1200 Subject: [PATCH 1293/1323] Fix generated openapi.json parameter names (#600) * Fix generated openapi.json parameter names * Fix generated openapi.json parameter names --- .../core/openapi/MethodParamDocBuilder.java | 2 +- .../src/main/resources/public/openapi.json | 12 ++++++------ .../src/test/resources/expectedOpenApi.json | 6 +++--- .../src/main/resources/public/openapi.json | 2 +- .../test-jex/src/main/resources/public/openapi.json | 4 ++-- .../src/test/resources/expectedOpenApi.json | 12 ++++++------ .../src/main/resources/public/openapi.json | 6 +++--- 7 files changed, 22 insertions(+), 22 deletions(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/MethodParamDocBuilder.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/MethodParamDocBuilder.java index 21428679c..286b19dab 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/MethodParamDocBuilder.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/MethodParamDocBuilder.java @@ -51,7 +51,7 @@ public void build() { } else { Parameter param = new Parameter(); - param.setName(varName); + param.setName(paramName); param.setDescription(javadoc.getParams().get(paramName)); Schema schema = ctx.toSchema(rawType, element); diff --git a/tests/test-javalin-jsonb/src/main/resources/public/openapi.json b/tests/test-javalin-jsonb/src/main/resources/public/openapi.json index 1506e2c4d..11c8d142b 100644 --- a/tests/test-javalin-jsonb/src/main/resources/public/openapi.json +++ b/tests/test-javalin-jsonb/src/main/resources/public/openapi.json @@ -393,7 +393,7 @@ } }, { - "name" : "myParam", + "name" : "my-param", "in" : "query", "schema" : { "type" : "string" @@ -779,7 +779,7 @@ } }, { - "name" : "head", + "name" : "Head", "in" : "header", "schema" : { "type" : "string" @@ -994,21 +994,21 @@ } }, { - "name" : "param2", + "name" : "q-2", "in" : "query", "schema" : { "type" : "string" } }, { - "name" : "contentLength", + "name" : "Content-Length", "in" : "header", "schema" : { "type" : "string" } }, { - "name" : "otherHeader", + "name" : "x-oh", "in" : "header", "schema" : { "type" : "string" @@ -1746,7 +1746,7 @@ "description" : "", "parameters" : [ { - "name" : "head", + "name" : "Head", "in" : "header", "schema" : { "type" : "string" diff --git a/tests/test-javalin-jsonb/src/test/resources/expectedOpenApi.json b/tests/test-javalin-jsonb/src/test/resources/expectedOpenApi.json index 407ae6305..f7833d6c4 100644 --- a/tests/test-javalin-jsonb/src/test/resources/expectedOpenApi.json +++ b/tests/test-javalin-jsonb/src/test/resources/expectedOpenApi.json @@ -42,21 +42,21 @@ } }, { - "name" : "param2", + "name" : "q-2", "in" : "query", "schema" : { "type" : "string" } }, { - "name" : "contentLength", + "name" : "Content-Length", "in" : "header", "schema" : { "type" : "string" } }, { - "name" : "otherHeader", + "name" : "x-oh", "in" : "header", "schema" : { "type" : "string" diff --git a/tests/test-javalin/src/main/resources/public/openapi.json b/tests/test-javalin/src/main/resources/public/openapi.json index e9b204041..cf36d6a33 100644 --- a/tests/test-javalin/src/main/resources/public/openapi.json +++ b/tests/test-javalin/src/main/resources/public/openapi.json @@ -363,7 +363,7 @@ } }, { - "name" : "myParam", + "name" : "my-param", "in" : "query", "schema" : { "type" : "string" diff --git a/tests/test-jex/src/main/resources/public/openapi.json b/tests/test-jex/src/main/resources/public/openapi.json index e31f0de26..61b8c2571 100644 --- a/tests/test-jex/src/main/resources/public/openapi.json +++ b/tests/test-jex/src/main/resources/public/openapi.json @@ -432,7 +432,7 @@ } }, { - "name" : "myParam", + "name" : "my-param", "in" : "query", "schema" : { "type" : "string" @@ -908,7 +908,7 @@ } }, { - "name" : "head", + "name" : "Head", "in" : "header", "schema" : { "type" : "string" diff --git a/tests/test-nima-jsonb/src/test/resources/expectedOpenApi.json b/tests/test-nima-jsonb/src/test/resources/expectedOpenApi.json index 6a5e636e9..38fc5b6e6 100644 --- a/tests/test-nima-jsonb/src/test/resources/expectedOpenApi.json +++ b/tests/test-nima-jsonb/src/test/resources/expectedOpenApi.json @@ -21,7 +21,7 @@ "/openapi/delete/{type}" : { "delete" : { "tags" : [ - + ], "summary" : "", "description" : "", @@ -42,7 +42,7 @@ } }, { - "name" : "header", + "name" : "Header", "in" : "header", "schema" : { "type" : "string" @@ -66,7 +66,7 @@ "/openapi/get" : { "get" : { "tags" : [ - + ], "summary" : "Example of Open API Get (up to the first period is the summary)", "description" : "When using Javalin Context only This Javadoc description is added to the generated openapi.json", @@ -142,7 +142,7 @@ "/openapi/post1" : { "post" : { "tags" : [ - + ], "summary" : "Standard Post", "description" : "The Deprecated annotation adds \"deprecacted:true\" to the generated json", @@ -191,7 +191,7 @@ "/openapi/put" : { "put" : { "tags" : [ - + ], "summary" : "", "description" : "", @@ -256,4 +256,4 @@ } } } -} \ No newline at end of file +} diff --git a/tests/test-sigma/src/main/resources/public/openapi.json b/tests/test-sigma/src/main/resources/public/openapi.json index 782c1c405..01e736b6e 100644 --- a/tests/test-sigma/src/main/resources/public/openapi.json +++ b/tests/test-sigma/src/main/resources/public/openapi.json @@ -393,7 +393,7 @@ } }, { - "name" : "myParam", + "name" : "my-param", "in" : "query", "schema" : { "type" : "string" @@ -779,7 +779,7 @@ } }, { - "name" : "head", + "name" : "Head", "in" : "header", "schema" : { "type" : "string" @@ -1584,7 +1584,7 @@ "description" : "", "parameters" : [ { - "name" : "head", + "name" : "Head", "in" : "header", "schema" : { "type" : "string" From 889626ddd8420c374c78ce0defe6b6841f9294b3 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Wed, 30 Apr 2025 00:19:57 +1200 Subject: [PATCH 1294/1323] Version 3.3-RC2 --- aws-cognito/http-client-authtoken/pom.xml | 2 +- htmx-api/pom.xml | 2 +- htmx-nima-jstache/pom.xml | 2 +- htmx-nima/pom.xml | 4 ++-- http-api-javalin/pom.xml | 2 +- http-api/pom.xml | 2 +- http-client-gson-adapter/pom.xml | 4 ++-- http-client-moshi-adapter/pom.xml | 4 ++-- http-client/pom.xml | 2 +- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 2 +- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-generator-sigma/pom.xml | 2 +- http-inject-plugin/pom.xml | 2 +- pom.xml | 4 ++-- tests/pom.xml | 2 +- tests/test-client-generation/pom.xml | 2 +- tests/test-client/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-htmx/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- tests/test-sigma/pom.xml | 2 +- 27 files changed, 31 insertions(+), 31 deletions(-) diff --git a/aws-cognito/http-client-authtoken/pom.xml b/aws-cognito/http-client-authtoken/pom.xml index e3b09a6ec..1aa05ba70 100644 --- a/aws-cognito/http-client-authtoken/pom.xml +++ b/aws-cognito/http-client-authtoken/pom.xml @@ -17,7 +17,7 @@ io.avaje avaje-http-client - 3.3-RC1 + 3.3-RC2 diff --git a/htmx-api/pom.xml b/htmx-api/pom.xml index d25a3721b..a64dffa63 100644 --- a/htmx-api/pom.xml +++ b/htmx-api/pom.xml @@ -6,7 +6,7 @@ io.avaje avaje-http-parent - 3.3-RC1 + 3.3-RC2 avaje-htmx-api diff --git a/htmx-nima-jstache/pom.xml b/htmx-nima-jstache/pom.xml index 9de29727e..153e16677 100644 --- a/htmx-nima-jstache/pom.xml +++ b/htmx-nima-jstache/pom.xml @@ -6,7 +6,7 @@ io.avaje avaje-http-parent - 3.3-RC1 + 3.3-RC2 avaje-htmx-nima-jstache diff --git a/htmx-nima/pom.xml b/htmx-nima/pom.xml index ed882764d..ebaa0112a 100644 --- a/htmx-nima/pom.xml +++ b/htmx-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje avaje-http-parent - 3.3-RC1 + 3.3-RC2 avaje-htmx-nima @@ -21,7 +21,7 @@ io.avaje avaje-htmx-api - 3.3-RC1 + 3.3-RC2 io.helidon.webserver diff --git a/http-api-javalin/pom.xml b/http-api-javalin/pom.xml index 55493fb52..a0a4569f5 100644 --- a/http-api-javalin/pom.xml +++ b/http-api-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.3-RC1 + 3.3-RC2 .. diff --git a/http-api/pom.xml b/http-api/pom.xml index c64876c80..480b7f11a 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.3-RC1 + 3.3-RC2 .. diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index 95eb0a698..8ee220ee5 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.3-RC1 + 3.3-RC2 avaje-http-client-gson @@ -20,7 +20,7 @@ io.avaje avaje-http-client - 3.3-RC1 + 3.3-RC2 provided diff --git a/http-client-moshi-adapter/pom.xml b/http-client-moshi-adapter/pom.xml index 10b1c0f67..3e612c715 100644 --- a/http-client-moshi-adapter/pom.xml +++ b/http-client-moshi-adapter/pom.xml @@ -3,7 +3,7 @@ io.avaje avaje-http-parent - 3.3-RC1 + 3.3-RC2 avaje-http-client-moshi @@ -19,7 +19,7 @@ io.avaje avaje-http-client - 3.3-RC1 + 3.3-RC2 provided diff --git a/http-client/pom.xml b/http-client/pom.xml index 7d82817ed..13463d575 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.3-RC1 + 3.3-RC2 avaje-http-client diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index 9e4748622..64c3fb6de 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.3-RC1 + 3.3-RC2 avaje-http-client-generator diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index e32981597..9214de172 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.3-RC1 + 3.3-RC2 avaje-http-generator-core diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index e16aac01f..0998b6e98 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 3.3-RC1 + 3.3-RC2 avaje-http-helidon-generator diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index 2482ebf9a..0ae42c52c 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.3-RC1 + 3.3-RC2 avaje-http-javalin-generator diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index 61bf1e9b9..33222400d 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.3-RC1 + 3.3-RC2 avaje-http-jex-generator diff --git a/http-generator-sigma/pom.xml b/http-generator-sigma/pom.xml index d01fd5790..9427337f1 100644 --- a/http-generator-sigma/pom.xml +++ b/http-generator-sigma/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.3-RC1 + 3.3-RC2 avaje-http-sigma-generator diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index 2834fc7e9..a3fb049fc 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.3-RC1 + 3.3-RC2 .. diff --git a/pom.xml b/pom.xml index b7b019a62..2c7d8f4f4 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-parent - 3.3-RC1 + 3.3-RC2 pom @@ -23,7 +23,7 @@ 2.14.2 3.0-RC10 1.42 - 2025-04-27T22:02:10Z + 2025-04-29T12:18:15Z ${project.build.directory}${file.separator}module-info.shade diff --git a/tests/pom.xml b/tests/pom.xml index c023c1c13..57ec9d2a6 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 3.3-RC1 + 3.3-RC2 tests diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index 11b5565f2..906b566db 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 3.3-RC1 + 3.3-RC2 test-client-generation diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index 9bdc729c3..964459db2 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 3.3-RC1 + 3.3-RC2 test-client diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 5c3f801c1..472eabc82 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 3.3-RC1 + 3.3-RC2 test-javalin-jsonb diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index f13214958..3914858e0 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 3.3-RC1 + 3.3-RC2 test-javalin diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 734972f16..b568b6089 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 3.3-RC1 + 3.3-RC2 test-jex diff --git a/tests/test-nima-htmx/pom.xml b/tests/test-nima-htmx/pom.xml index 405500527..b58e86930 100644 --- a/tests/test-nima-htmx/pom.xml +++ b/tests/test-nima-htmx/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 3.3-RC1 + 3.3-RC2 test-nima-htmx diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index ddc120cd7..378a50d67 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 3.3-RC1 + 3.3-RC2 test-nima-jsonb diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index 3fd382be1..35d514a2f 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 3.3-RC1 + 3.3-RC2 test-nima diff --git a/tests/test-sigma/pom.xml b/tests/test-sigma/pom.xml index b291caa9d..1168aa828 100644 --- a/tests/test-sigma/pom.xml +++ b/tests/test-sigma/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 3.3-RC1 + 3.3-RC2 test-sigma From afad6cb812ed5958c4795cc7b4edf6292163316b Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Tue, 29 Apr 2025 18:41:00 -0400 Subject: [PATCH 1295/1323] bump version --- aws-cognito/http-client-authtoken/pom.xml | 2 +- htmx-api/pom.xml | 2 +- htmx-nima-jstache/pom.xml | 2 +- htmx-nima/pom.xml | 4 ++-- http-api-javalin/pom.xml | 2 +- http-api/pom.xml | 2 +- http-client-gson-adapter/pom.xml | 4 ++-- http-client-moshi-adapter/pom.xml | 4 ++-- http-client/pom.xml | 2 +- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 2 +- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-generator-sigma/pom.xml | 2 +- http-inject-plugin/pom.xml | 2 +- pom.xml | 4 ++-- tests/pom.xml | 2 +- tests/test-client-generation/pom.xml | 2 +- tests/test-client/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-htmx/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- tests/test-sigma/pom.xml | 2 +- 27 files changed, 31 insertions(+), 31 deletions(-) diff --git a/aws-cognito/http-client-authtoken/pom.xml b/aws-cognito/http-client-authtoken/pom.xml index 1aa05ba70..b9371bfca 100644 --- a/aws-cognito/http-client-authtoken/pom.xml +++ b/aws-cognito/http-client-authtoken/pom.xml @@ -17,7 +17,7 @@ io.avaje avaje-http-client - 3.3-RC2 + 3.3 diff --git a/htmx-api/pom.xml b/htmx-api/pom.xml index a64dffa63..0ba9b615c 100644 --- a/htmx-api/pom.xml +++ b/htmx-api/pom.xml @@ -6,7 +6,7 @@ io.avaje avaje-http-parent - 3.3-RC2 + 3.3 avaje-htmx-api diff --git a/htmx-nima-jstache/pom.xml b/htmx-nima-jstache/pom.xml index 153e16677..d50450dc1 100644 --- a/htmx-nima-jstache/pom.xml +++ b/htmx-nima-jstache/pom.xml @@ -6,7 +6,7 @@ io.avaje avaje-http-parent - 3.3-RC2 + 3.3 avaje-htmx-nima-jstache diff --git a/htmx-nima/pom.xml b/htmx-nima/pom.xml index ebaa0112a..9fd20e166 100644 --- a/htmx-nima/pom.xml +++ b/htmx-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje avaje-http-parent - 3.3-RC2 + 3.3 avaje-htmx-nima @@ -21,7 +21,7 @@ io.avaje avaje-htmx-api - 3.3-RC2 + 3.3 io.helidon.webserver diff --git a/http-api-javalin/pom.xml b/http-api-javalin/pom.xml index a0a4569f5..45ca2597f 100644 --- a/http-api-javalin/pom.xml +++ b/http-api-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.3-RC2 + 3.3 .. diff --git a/http-api/pom.xml b/http-api/pom.xml index 480b7f11a..efe67cd78 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.3-RC2 + 3.3 .. diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index 8ee220ee5..539b28ac9 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.3-RC2 + 3.3 avaje-http-client-gson @@ -20,7 +20,7 @@ io.avaje avaje-http-client - 3.3-RC2 + 3.3 provided diff --git a/http-client-moshi-adapter/pom.xml b/http-client-moshi-adapter/pom.xml index 3e612c715..27c23afde 100644 --- a/http-client-moshi-adapter/pom.xml +++ b/http-client-moshi-adapter/pom.xml @@ -3,7 +3,7 @@ io.avaje avaje-http-parent - 3.3-RC2 + 3.3 avaje-http-client-moshi @@ -19,7 +19,7 @@ io.avaje avaje-http-client - 3.3-RC2 + 3.3 provided diff --git a/http-client/pom.xml b/http-client/pom.xml index 13463d575..15f4881b5 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.3-RC2 + 3.3 avaje-http-client diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index 64c3fb6de..f52666d40 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.3-RC2 + 3.3 avaje-http-client-generator diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 9214de172..a8aeca6e8 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.3-RC2 + 3.3 avaje-http-generator-core diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index 0998b6e98..d0d525a04 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 3.3-RC2 + 3.3 avaje-http-helidon-generator diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index 0ae42c52c..cd90d3c27 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.3-RC2 + 3.3 avaje-http-javalin-generator diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index 33222400d..5a8bcffff 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.3-RC2 + 3.3 avaje-http-jex-generator diff --git a/http-generator-sigma/pom.xml b/http-generator-sigma/pom.xml index 9427337f1..0b8946b2d 100644 --- a/http-generator-sigma/pom.xml +++ b/http-generator-sigma/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.3-RC2 + 3.3 avaje-http-sigma-generator diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index a3fb049fc..d31387c5c 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.3-RC2 + 3.3 .. diff --git a/pom.xml b/pom.xml index 2c7d8f4f4..20ca7c21a 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ io.avaje avaje-http-parent - 3.3-RC2 + 3.3 pom @@ -23,7 +23,7 @@ 2.14.2 3.0-RC10 1.42 - 2025-04-29T12:18:15Z + 2025-04-29T22:40:45Z ${project.build.directory}${file.separator}module-info.shade diff --git a/tests/pom.xml b/tests/pom.xml index 57ec9d2a6..892fc4516 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 3.3-RC2 + 3.3 tests diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index 906b566db..b636fc322 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 3.3-RC2 + 3.3 test-client-generation diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index 964459db2..74969e355 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 3.3-RC2 + 3.3 test-client diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 472eabc82..37aef61a0 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 3.3-RC2 + 3.3 test-javalin-jsonb diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 3914858e0..ba0fd66ec 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 3.3-RC2 + 3.3 test-javalin diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index b568b6089..7dcadbc19 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 3.3-RC2 + 3.3 test-jex diff --git a/tests/test-nima-htmx/pom.xml b/tests/test-nima-htmx/pom.xml index b58e86930..ab15ab3e1 100644 --- a/tests/test-nima-htmx/pom.xml +++ b/tests/test-nima-htmx/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 3.3-RC2 + 3.3 test-nima-htmx diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 378a50d67..6ba69d383 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 3.3-RC2 + 3.3 test-nima-jsonb diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index 35d514a2f..d982ebe5f 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 3.3-RC2 + 3.3 test-nima diff --git a/tests/test-sigma/pom.xml b/tests/test-sigma/pom.xml index 1168aa828..9737654b6 100644 --- a/tests/test-sigma/pom.xml +++ b/tests/test-sigma/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 3.3-RC2 + 3.3 test-sigma From 0e54d39c0f9564913c0c12aafc0aaeffabf4cf72 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 6 May 2025 07:01:45 +0000 Subject: [PATCH 1296/1323] Bump the dependencies group across 1 directory with 20 updates Bumps the dependencies group with 20 updates in the / directory: | Package | From | To | | --- | --- | --- | | [com.fasterxml.jackson.core:jackson-databind](https://github.com/FasterXML/jackson) | `2.18.3` | `2.19.0` | | [io.avaje:avaje-jsonb](https://github.com/avaje/avaje-jsonb) | `3.3` | `3.4` | | io.avaje:avaje-json-node | `3.3` | `3.4` | | [io.avaje:avaje-inject](https://github.com/avaje/avaje-inject) | `11.4` | `11.5` | | io.avaje:avaje-inject-generator | `11.4` | `11.5` | | [org.apache.maven.plugins:maven-jar-plugin](https://github.com/apache/maven-jar-plugin) | `3.3.0` | `3.4.2` | | io.avaje:avaje-inject-maven-plugin | `11.4` | `11.5` | | [com.google.code.gson:gson](https://github.com/google/gson) | `2.13.0` | `2.13.1` | | [io.avaje:avaje-validator](https://github.com/avaje/avaje-validator) | `2.9` | `2.11` | | io.avaje:avaje-validator-constraints | `2.9` | `2.11` | | io.avaje:avaje-validator-generator | `2.9` | `2.11` | | io.avaje:avaje-jsonb-generator | `3.3` | `3.4` | | [io.avaje:avaje-jex](https://github.com/avaje/avaje-jex) | `3.1` | `3.2` | | io.avaje:avaje-jex-htmx | `3.1` | `3.2` | | io.helidon.webserver:helidon-webserver | `4.2.0` | `4.2.1` | | io.helidon.webserver:helidon-webserver-security | `4.2.0` | `4.2.1` | | io.helidon.http.media:helidon-http-media-jsonb | `4.2.0` | `4.2.1` | | io.avaje:avaje-nima | `1.2` | `1.3` | | io.avaje:avaje-nima-test | `1.2` | `1.3` | | io.avaje:avaje-json-core | `3.3` | `3.4` | Updates `com.fasterxml.jackson.core:jackson-databind` from 2.18.3 to 2.19.0 - [Commits](https://github.com/FasterXML/jackson/commits) Updates `io.avaje:avaje-jsonb` from 3.3 to 3.4 - [Release notes](https://github.com/avaje/avaje-jsonb/releases) - [Commits](https://github.com/avaje/avaje-jsonb/compare/3.3...3.4) Updates `io.avaje:avaje-json-node` from 3.3 to 3.4 Updates `io.avaje:avaje-inject` from 11.4 to 11.5 - [Release notes](https://github.com/avaje/avaje-inject/releases) - [Commits](https://github.com/avaje/avaje-inject/compare/11.4...11.5) Updates `io.avaje:avaje-inject-generator` from 11.4 to 11.5 Updates `io.avaje:avaje-inject-generator` from 11.4 to 11.5 Updates `org.apache.maven.plugins:maven-jar-plugin` from 3.3.0 to 3.4.2 - [Release notes](https://github.com/apache/maven-jar-plugin/releases) - [Commits](https://github.com/apache/maven-jar-plugin/compare/maven-jar-plugin-3.3.0...maven-jar-plugin-3.4.2) Updates `io.avaje:avaje-inject-maven-plugin` from 11.4 to 11.5 Updates `com.google.code.gson:gson` from 2.13.0 to 2.13.1 - [Release notes](https://github.com/google/gson/releases) - [Changelog](https://github.com/google/gson/blob/main/CHANGELOG.md) - [Commits](https://github.com/google/gson/compare/gson-parent-2.13.0...gson-parent-2.13.1) Updates `io.avaje:avaje-validator` from 2.9 to 2.11 - [Release notes](https://github.com/avaje/avaje-validator/releases) - [Commits](https://github.com/avaje/avaje-validator/compare/2.9...2.11) Updates `io.avaje:avaje-validator-constraints` from 2.9 to 2.11 Updates `io.avaje:avaje-validator-generator` from 2.9 to 2.11 Updates `io.avaje:avaje-jsonb-generator` from 3.3 to 3.4 Updates `io.avaje:avaje-jex` from 3.1 to 3.2 - [Release notes](https://github.com/avaje/avaje-jex/releases) - [Commits](https://github.com/avaje/avaje-jex/compare/3.1...3.2) Updates `io.avaje:avaje-jex-htmx` from 3.1 to 3.2 Updates `io.helidon.webserver:helidon-webserver` from 4.2.0 to 4.2.1 Updates `io.helidon.webserver:helidon-webserver-security` from 4.2.0 to 4.2.1 Updates `io.helidon.http.media:helidon-http-media-jsonb` from 4.2.0 to 4.2.1 Updates `io.helidon.webserver:helidon-webserver-security` from 4.2.0 to 4.2.1 Updates `io.helidon.http.media:helidon-http-media-jsonb` from 4.2.0 to 4.2.1 Updates `io.avaje:avaje-jex-htmx` from 3.1 to 3.2 Updates `io.avaje:avaje-nima` from 1.2 to 1.3 Updates `io.avaje:avaje-nima-test` from 1.2 to 1.3 Updates `io.avaje:avaje-json-core` from 3.3 to 3.4 --- updated-dependencies: - dependency-name: com.fasterxml.jackson.core:jackson-databind dependency-version: 2.19.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.avaje:avaje-jsonb dependency-version: '3.4' dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.avaje:avaje-json-node dependency-version: '3.4' dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.avaje:avaje-inject dependency-version: '11.5' dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.avaje:avaje-inject-generator dependency-version: '11.5' dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.avaje:avaje-inject-generator dependency-version: '11.5' dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: org.apache.maven.plugins:maven-jar-plugin dependency-version: 3.4.2 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.avaje:avaje-inject-maven-plugin dependency-version: '11.5' dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: com.google.code.gson:gson dependency-version: 2.13.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: io.avaje:avaje-validator dependency-version: '2.11' dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.avaje:avaje-validator-constraints dependency-version: '2.11' dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.avaje:avaje-validator-generator dependency-version: '2.11' dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.avaje:avaje-jsonb-generator dependency-version: '3.4' dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.avaje:avaje-jex dependency-version: '3.2' dependency-type: direct:development update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.avaje:avaje-jex-htmx dependency-version: '3.2' dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.helidon.webserver:helidon-webserver dependency-version: 4.2.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: io.helidon.webserver:helidon-webserver-security dependency-version: 4.2.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: io.helidon.http.media:helidon-http-media-jsonb dependency-version: 4.2.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: io.helidon.webserver:helidon-webserver-security dependency-version: 4.2.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: io.helidon.http.media:helidon-http-media-jsonb dependency-version: 4.2.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: io.avaje:avaje-jex-htmx dependency-version: '3.2' dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.avaje:avaje-nima dependency-version: '1.3' dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.avaje:avaje-nima-test dependency-version: '1.3' dependency-type: direct:development update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.avaje:avaje-json-core dependency-version: '3.4' dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies ... Signed-off-by: dependabot[bot] --- aws-cognito/http-client-authtoken/pom.xml | 4 ++-- htmx-nima-jstache/pom.xml | 2 +- htmx-nima/pom.xml | 2 +- http-client-gson-adapter/pom.xml | 2 +- http-client/pom.xml | 14 +++++++------- http-inject-plugin/pom.xml | 2 +- tests/pom.xml | 14 +++++++------- tests/test-client-generation/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 4 ++-- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 8 ++++---- tests/test-nima-htmx/pom.xml | 8 ++++---- tests/test-nima-jsonb/pom.xml | 8 ++++---- tests/test-nima/pom.xml | 2 +- tests/test-sigma/pom.xml | 4 ++-- 15 files changed, 39 insertions(+), 39 deletions(-) diff --git a/aws-cognito/http-client-authtoken/pom.xml b/aws-cognito/http-client-authtoken/pom.xml index b9371bfca..fc01f57eb 100644 --- a/aws-cognito/http-client-authtoken/pom.xml +++ b/aws-cognito/http-client-authtoken/pom.xml @@ -23,14 +23,14 @@ io.avaje avaje-json-core - 3.3 + 3.4 io.avaje avaje-json-node - 3.3 + 3.4 test diff --git a/htmx-nima-jstache/pom.xml b/htmx-nima-jstache/pom.xml index d50450dc1..2fa90dad4 100644 --- a/htmx-nima-jstache/pom.xml +++ b/htmx-nima-jstache/pom.xml @@ -39,7 +39,7 @@ io.avaje avaje-inject - 11.4 + 11.5 provided true diff --git a/htmx-nima/pom.xml b/htmx-nima/pom.xml index 9fd20e166..9dd08aac4 100644 --- a/htmx-nima/pom.xml +++ b/htmx-nima/pom.xml @@ -26,7 +26,7 @@ io.helidon.webserver helidon-webserver - 4.2.0 + 4.2.1
    diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index 539b28ac9..fb061a565 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -14,7 +14,7 @@ com.google.code.gson gson - 2.13.0 + 2.13.1 diff --git a/http-client/pom.xml b/http-client/pom.xml index 15f4881b5..21ff6895b 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -29,28 +29,28 @@ com.fasterxml.jackson.core jackson-databind - 2.18.3 + 2.19.0 true io.avaje avaje-jsonb - 3.3 + 3.4 true io.avaje avaje-json-node - 3.3 + 3.4 test io.avaje avaje-inject - 11.4 + 11.5 true @@ -98,7 +98,7 @@ org.apache.maven.plugins maven-jar-plugin - 3.3.0 + 3.4.2 @@ -120,7 +120,7 @@ io.avaje avaje-inject-generator - 11.4 + 11.5 @@ -159,7 +159,7 @@ io.avaje avaje-inject-maven-plugin - 11.4 + 11.5 diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index d31387c5c..efc9b89c9 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -19,7 +19,7 @@ io.avaje avaje-inject - 11.4 + 11.5 provided true diff --git a/tests/pom.xml b/tests/pom.xml index 892fc4516..803ae013b 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -14,10 +14,10 @@ true 5.12.2 3.27.3 - 2.18.3 - 3.1 - 11.4 - 4.2.0 + 2.19.0 + 3.2 + 11.5 + 4.2.1 6.6.0 @@ -48,19 +48,19 @@ io.avaje avaje-validator - 2.9 + 2.11 io.avaje avaje-validator-constraints - 2.9 + 2.11 io.avaje avaje-validator-generator - 2.9 + 2.11 diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index b636fc322..d6f251b4e 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -141,7 +141,7 @@ io.avaje avaje-inject-maven-plugin - 11.4 + 11.5 process-sources diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 37aef61a0..e2d996969 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -74,13 +74,13 @@ io.avaje avaje-jsonb - 3.3 + 3.4 io.avaje avaje-jsonb-generator - 3.3 + 3.4 provided diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index ba0fd66ec..8dea312ee 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -57,7 +57,7 @@ io.avaje avaje-validator - 2.9 + 2.11 diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 7dcadbc19..d014578b0 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -74,7 +74,7 @@ io.avaje avaje-jsonb - 3.3 + 3.4 @@ -140,12 +140,12 @@ io.avaje avaje-jsonb-generator - 3.3 + 3.4 io.avaje avaje-validator-generator - 2.9 + 2.11 io.jstach @@ -187,7 +187,7 @@ io.avaje avaje-inject-maven-plugin - 11.4 + 11.5 process-sources diff --git a/tests/test-nima-htmx/pom.xml b/tests/test-nima-htmx/pom.xml index ab15ab3e1..1b257abc1 100644 --- a/tests/test-nima-htmx/pom.xml +++ b/tests/test-nima-htmx/pom.xml @@ -47,7 +47,7 @@ io.avaje avaje-nima - 1.2 + 1.3 @@ -60,7 +60,7 @@ io.avaje avaje-nima-test - 1.2 + 1.3 test @@ -88,7 +88,7 @@ io.avaje avaje-jsonb-generator - 3.3 + 3.4 io.jstach @@ -103,7 +103,7 @@ io.avaje avaje-inject-maven-plugin - 11.4 + 11.5 process-sources diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 6ba69d383..e03e22c8b 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -44,7 +44,7 @@ io.avaje avaje-jsonb - 3.3 + 3.4 io.helidon.webserver @@ -104,12 +104,12 @@ io.avaje avaje-jsonb-generator - 3.3 + 3.4 io.avaje avaje-validator-generator - 2.9 + 2.11 io.jstach @@ -133,7 +133,7 @@ io.avaje avaje-inject-maven-plugin - 11.4 + 11.5 process-sources diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index d982ebe5f..1b17a0b9a 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -75,7 +75,7 @@ io.avaje avaje-inject-maven-plugin - 11.4 + 11.5 process-sources diff --git a/tests/test-sigma/pom.xml b/tests/test-sigma/pom.xml index 9737654b6..85b2db2d8 100644 --- a/tests/test-sigma/pom.xml +++ b/tests/test-sigma/pom.xml @@ -82,12 +82,12 @@ io.avaje avaje-jsonb - 3.3 + 3.4 io.avaje avaje-jsonb-generator - 3.3 + 3.4 provided From a152fc602e68be5ef2d470754f36daf11ab530f5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 May 2025 19:46:57 +0000 Subject: [PATCH 1297/1323] Bump the dependencies group with 6 updates Bumps the dependencies group with 6 updates: | Package | From | To | | --- | --- | --- | | io.avaje:avaje-spi-service | `2.12` | `2.13` | | io.helidon.webserver:helidon-webserver | `4.2.1` | `4.2.2` | | io.helidon.webserver:helidon-webserver-security | `4.2.1` | `4.2.2` | | io.helidon.http.media:helidon-http-media-jsonb | `4.2.1` | `4.2.2` | | io.avaje:avaje-nima | `1.3` | `1.4` | | io.avaje:avaje-nima-test | `1.3` | `1.4` | Updates `io.avaje:avaje-spi-service` from 2.12 to 2.13 Updates `io.helidon.webserver:helidon-webserver` from 4.2.1 to 4.2.2 Updates `io.helidon.webserver:helidon-webserver-security` from 4.2.1 to 4.2.2 Updates `io.helidon.http.media:helidon-http-media-jsonb` from 4.2.1 to 4.2.2 Updates `io.helidon.webserver:helidon-webserver-security` from 4.2.1 to 4.2.2 Updates `io.helidon.http.media:helidon-http-media-jsonb` from 4.2.1 to 4.2.2 Updates `io.avaje:avaje-nima` from 1.3 to 1.4 Updates `io.avaje:avaje-nima-test` from 1.3 to 1.4 --- updated-dependencies: - dependency-name: io.avaje:avaje-spi-service dependency-version: '2.13' dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.helidon.webserver:helidon-webserver dependency-version: 4.2.2 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: io.helidon.webserver:helidon-webserver-security dependency-version: 4.2.2 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: io.helidon.http.media:helidon-http-media-jsonb dependency-version: 4.2.2 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: io.helidon.webserver:helidon-webserver-security dependency-version: 4.2.2 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: io.helidon.http.media:helidon-http-media-jsonb dependency-version: 4.2.2 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: io.avaje:avaje-nima dependency-version: '1.4' dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.avaje:avaje-nima-test dependency-version: '1.4' dependency-type: direct:development update-type: version-update:semver-minor dependency-group: dependencies ... Signed-off-by: dependabot[bot] --- htmx-nima-jstache/pom.xml | 2 +- htmx-nima/pom.xml | 2 +- http-inject-plugin/pom.xml | 2 +- tests/pom.xml | 2 +- tests/test-nima-htmx/pom.xml | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/htmx-nima-jstache/pom.xml b/htmx-nima-jstache/pom.xml index 2fa90dad4..34d8a9c63 100644 --- a/htmx-nima-jstache/pom.xml +++ b/htmx-nima-jstache/pom.xml @@ -46,7 +46,7 @@ io.avaje avaje-spi-service - 2.12 + 2.13 provided true diff --git a/htmx-nima/pom.xml b/htmx-nima/pom.xml index 9dd08aac4..172255d4b 100644 --- a/htmx-nima/pom.xml +++ b/htmx-nima/pom.xml @@ -26,7 +26,7 @@ io.helidon.webserver helidon-webserver - 4.2.1 + 4.2.2 diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index efc9b89c9..72e8a06a7 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -33,7 +33,7 @@ io.avaje avaje-spi-service - 2.12 + 2.13 provided true diff --git a/tests/pom.xml b/tests/pom.xml index 803ae013b..968300108 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -17,7 +17,7 @@ 2.19.0 3.2 11.5 - 4.2.1 + 4.2.2 6.6.0 diff --git a/tests/test-nima-htmx/pom.xml b/tests/test-nima-htmx/pom.xml index 1b257abc1..d1e3fa946 100644 --- a/tests/test-nima-htmx/pom.xml +++ b/tests/test-nima-htmx/pom.xml @@ -47,7 +47,7 @@ io.avaje avaje-nima - 1.3 + 1.4 @@ -60,7 +60,7 @@ io.avaje avaje-nima-test - 1.3 + 1.4 test From c870bab5ccab0eee996bd5556a92be71ff735851 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 May 2025 19:11:33 +0000 Subject: [PATCH 1298/1323] Bump the dependencies group with 7 updates Bumps the dependencies group with 7 updates: | Package | From | To | | --- | --- | --- | | io.avaje:junit | `1.5` | `1.6` | | io.swagger.core.v3:swagger-models | `2.2.30` | `2.2.32` | | io.swagger.core.v3:swagger-annotations | `2.2.30` | `2.2.32` | | [io.rest-assured:rest-assured](https://github.com/rest-assured/rest-assured) | `5.5.1` | `5.5.2` | | [com.squareup.retrofit2:retrofit](https://github.com/square/retrofit) | `2.11.0` | `3.0.0` | | [com.squareup.retrofit2:converter-gson](https://github.com/square/retrofit) | `2.11.0` | `3.0.0` | | [com.squareup.retrofit2:converter-scalars](https://github.com/square/retrofit) | `2.11.0` | `3.0.0` | Updates `io.avaje:junit` from 1.5 to 1.6 Updates `io.swagger.core.v3:swagger-models` from 2.2.30 to 2.2.32 Updates `io.swagger.core.v3:swagger-annotations` from 2.2.30 to 2.2.32 Updates `io.swagger.core.v3:swagger-annotations` from 2.2.30 to 2.2.32 Updates `io.rest-assured:rest-assured` from 5.5.1 to 5.5.2 - [Changelog](https://github.com/rest-assured/rest-assured/blob/master/changelog.txt) - [Commits](https://github.com/rest-assured/rest-assured/compare/rest-assured-5.5.1...rest-assured-5.5.2) Updates `com.squareup.retrofit2:retrofit` from 2.11.0 to 3.0.0 - [Release notes](https://github.com/square/retrofit/releases) - [Changelog](https://github.com/square/retrofit/blob/trunk/CHANGELOG.md) - [Commits](https://github.com/square/retrofit/compare/2.11.0...3.0.0) Updates `com.squareup.retrofit2:converter-gson` from 2.11.0 to 3.0.0 - [Release notes](https://github.com/square/retrofit/releases) - [Changelog](https://github.com/square/retrofit/blob/trunk/CHANGELOG.md) - [Commits](https://github.com/square/retrofit/compare/2.11.0...3.0.0) Updates `com.squareup.retrofit2:converter-scalars` from 2.11.0 to 3.0.0 - [Release notes](https://github.com/square/retrofit/releases) - [Changelog](https://github.com/square/retrofit/blob/trunk/CHANGELOG.md) - [Commits](https://github.com/square/retrofit/compare/2.11.0...3.0.0) --- updated-dependencies: - dependency-name: io.avaje:junit dependency-version: '1.6' dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.swagger.core.v3:swagger-models dependency-version: 2.2.32 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: io.swagger.core.v3:swagger-annotations dependency-version: 2.2.32 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: io.swagger.core.v3:swagger-annotations dependency-version: 2.2.32 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: io.rest-assured:rest-assured dependency-version: 5.5.2 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: com.squareup.retrofit2:retrofit dependency-version: 3.0.0 dependency-type: direct:production update-type: version-update:semver-major dependency-group: dependencies - dependency-name: com.squareup.retrofit2:converter-gson dependency-version: 3.0.0 dependency-type: direct:production update-type: version-update:semver-major dependency-group: dependencies - dependency-name: com.squareup.retrofit2:converter-scalars dependency-version: 3.0.0 dependency-type: direct:production update-type: version-update:semver-major dependency-group: dependencies ... Signed-off-by: dependabot[bot] --- aws-cognito/http-client-authtoken/pom.xml | 2 +- http-client-moshi-adapter/pom.xml | 2 +- pom.xml | 4 ++-- tests/test-client-generation/pom.xml | 6 +++--- tests/test-client/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 6 +++--- tests/test-javalin/pom.xml | 6 +++--- tests/test-jex/pom.xml | 4 ++-- tests/test-nima-jsonb/pom.xml | 4 ++-- tests/test-sigma/pom.xml | 4 ++-- 10 files changed, 20 insertions(+), 20 deletions(-) diff --git a/aws-cognito/http-client-authtoken/pom.xml b/aws-cognito/http-client-authtoken/pom.xml index fc01f57eb..6923b7b5e 100644 --- a/aws-cognito/http-client-authtoken/pom.xml +++ b/aws-cognito/http-client-authtoken/pom.xml @@ -37,7 +37,7 @@ io.avaje junit - 1.5 + 1.6 test diff --git a/http-client-moshi-adapter/pom.xml b/http-client-moshi-adapter/pom.xml index 27c23afde..b33c4e4a8 100644 --- a/http-client-moshi-adapter/pom.xml +++ b/http-client-moshi-adapter/pom.xml @@ -28,7 +28,7 @@ io.avaje junit - 1.5 + 1.6 test diff --git a/pom.xml b/pom.xml index 20ca7c21a..aa434e417 100644 --- a/pom.xml +++ b/pom.xml @@ -19,7 +19,7 @@ true - 2.2.30 + 2.2.32 2.14.2 3.0-RC10 1.42 @@ -31,7 +31,7 @@ io.avaje junit - 1.5 + 1.6 test diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index d6f251b4e..8410d6c9c 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -50,19 +50,19 @@ com.squareup.retrofit2 retrofit - 2.11.0 + 3.0.0 com.squareup.retrofit2 converter-gson - 2.11.0 + 3.0.0 com.squareup.retrofit2 converter-scalars - 2.11.0 + 3.0.0 diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index 74969e355..526908105 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -45,7 +45,7 @@ io.avaje junit - 1.5 + 1.6 test diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index e2d996969..7461fa9a1 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -13,7 +13,7 @@ true org.example.myapp.Main - 2.2.30 + 2.2.32 1.3.71 @@ -88,14 +88,14 @@ io.avaje junit - 1.5 + 1.6 test io.rest-assured rest-assured - 5.5.1 + 5.5.2 test diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 8dea312ee..69fec9c4a 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -12,7 +12,7 @@ true org.example.myapp.Main - 2.2.30 + 2.2.32 1.3.71 @@ -86,14 +86,14 @@ io.avaje junit - 1.5 + 1.6 test io.rest-assured rest-assured - 5.5.1 + 5.5.2 test diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index d014578b0..0dfc9907c 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -12,7 +12,7 @@ 21 true org.example.myapp.Main - 2.2.30 + 2.2.32 @@ -85,7 +85,7 @@ io.avaje junit - 1.5 + 1.6 test diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index e03e22c8b..055c5d613 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -13,7 +13,7 @@ 21 - 2.2.30 + 2.2.32 UTF-8 false @@ -71,7 +71,7 @@ io.avaje junit - 1.5 + 1.6 test diff --git a/tests/test-sigma/pom.xml b/tests/test-sigma/pom.xml index 85b2db2d8..f644951ba 100644 --- a/tests/test-sigma/pom.xml +++ b/tests/test-sigma/pom.xml @@ -13,7 +13,7 @@ 17 true - 2.2.30 + 2.2.32 1.3.71 @@ -95,7 +95,7 @@ io.avaje junit - 1.5 + 1.6 test From a50d91f0cf6f012fdfa3b5e8cfd3aea5a4fff982 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Fri, 23 May 2025 02:45:10 +1200 Subject: [PATCH 1299/1323] [client] support custom classloader (#607) --- .../src/main/java/io/avaje/http/client/DHttpApi.java | 11 ++++++++--- .../java/io/avaje/http/client/DHttpClientContext.java | 5 +++++ .../main/java/io/avaje/http/client/HttpClient.java | 10 ++++++++++ .../test/java/io/avaje/http/client/DHttpApiTest.java | 6 +++--- 4 files changed, 26 insertions(+), 6 deletions(-) diff --git a/http-client/src/main/java/io/avaje/http/client/DHttpApi.java b/http-client/src/main/java/io/avaje/http/client/DHttpApi.java index 0f157c2bf..c0a95450c 100644 --- a/http-client/src/main/java/io/avaje/http/client/DHttpApi.java +++ b/http-client/src/main/java/io/avaje/http/client/DHttpApi.java @@ -19,11 +19,11 @@ final class DHttpApi { private final Map, HttpApiProvider> providerMap = new HashMap<>(); DHttpApi() { - init(); + this(Thread.currentThread().getContextClassLoader()); } - void init() { - for (final var apiProvider : ServiceLoader.load(GeneratedComponent.class)) { + DHttpApi(ClassLoader classLoader) { + for (final var apiProvider : ServiceLoader.load(GeneratedComponent.class, classLoader)) { apiProvider.register(providerMap); } log.log(DEBUG, "providers for {0}", providerMap.keySet()); @@ -46,4 +46,9 @@ T provideFor(Class type, HttpClient httpClient) { static T get(Class type, HttpClient httpClient) { return INSTANCE.provideFor(type, httpClient); } + + static T get(Class clientInterface, HttpClient httpClient, ClassLoader classLoader) { + return new DHttpApi(classLoader).provideFor(clientInterface, httpClient); + } + } diff --git a/http-client/src/main/java/io/avaje/http/client/DHttpClientContext.java b/http-client/src/main/java/io/avaje/http/client/DHttpClientContext.java index 3d9b66d3d..54ac9cf19 100644 --- a/http-client/src/main/java/io/avaje/http/client/DHttpClientContext.java +++ b/http-client/src/main/java/io/avaje/http/client/DHttpClientContext.java @@ -79,6 +79,11 @@ public T create(Class clientInterface) { return DHttpApi.get(clientInterface, this); } + @Override + public T create(Class clientInterface, ClassLoader classLoader) { + return DHttpApi.get(clientInterface, this, classLoader); + } + @Override public HttpClientRequest request() { return retryHandler == null diff --git a/http-client/src/main/java/io/avaje/http/client/HttpClient.java b/http-client/src/main/java/io/avaje/http/client/HttpClient.java index f00e33fa2..2543d967d 100644 --- a/http-client/src/main/java/io/avaje/http/client/HttpClient.java +++ b/http-client/src/main/java/io/avaje/http/client/HttpClient.java @@ -62,6 +62,16 @@ static Builder builder() { */ T create(Class clientInterface); + /** + * Return the http client API implementation using the given ClassLoader. + * + * @param clientInterface A @Client interface with annotated API methods. + * @param classLoader The ClassLoader to use to service load the implementation + * @param The service type. + * @return The http client API implementation. + */ + T create(Class clientInterface, ClassLoader classLoader); + /** * Create a new request. */ diff --git a/http-client/src/test/java/io/avaje/http/client/DHttpApiTest.java b/http-client/src/test/java/io/avaje/http/client/DHttpApiTest.java index 90ee7ca38..36fe3f554 100644 --- a/http-client/src/test/java/io/avaje/http/client/DHttpApiTest.java +++ b/http-client/src/test/java/io/avaje/http/client/DHttpApiTest.java @@ -18,14 +18,14 @@ class DHttpApiTest { @Test void test_github_listRepos() { - final var clientContext = HttpClient.builder() + final var client = HttpClient.builder() .baseUrl("https://api.github.com") .bodyAdapter(new JacksonBodyAdapter()) .build(); DHttpApi httpApi = new DHttpApi(); httpApi.addProvider(Simple.class, Simple$HttpClient::new); - final Simple simple = httpApi.provideFor(Simple.class, clientContext); + final Simple simple = httpApi.provideFor(Simple.class, client); final List repos = simple.listRepos("rbygrave", "junk"); assertThat(repos).isNotEmpty(); @@ -44,7 +44,7 @@ void jsonb_github_listRepos() { .bodyAdapter(new JsonbBodyAdapter(jsonb)) .build(); - DHttpApi httpApi = new DHttpApi(); + DHttpApi httpApi = new DHttpApi(Thread.currentThread().getContextClassLoader()); httpApi.addProvider(Simple.class, Simple$HttpClient::new); final Simple simple = httpApi.provideFor(Simple.class, client); From 0c91dad782cc14a36838b3682229c2e2efb0646d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 May 2025 19:52:57 +0000 Subject: [PATCH 1300/1323] Bump io.rest-assured:rest-assured in the dependencies group Bumps the dependencies group with 1 update: [io.rest-assured:rest-assured](https://github.com/rest-assured/rest-assured). Updates `io.rest-assured:rest-assured` from 5.5.2 to 5.5.5 - [Changelog](https://github.com/rest-assured/rest-assured/blob/master/changelog.txt) - [Commits](https://github.com/rest-assured/rest-assured/compare/rest-assured-5.5.2...rest-assured-5.5.5) --- updated-dependencies: - dependency-name: io.rest-assured:rest-assured dependency-version: 5.5.5 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies ... Signed-off-by: dependabot[bot] --- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 7461fa9a1..2e8a24091 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -95,7 +95,7 @@ io.rest-assured rest-assured - 5.5.2 + 5.5.5 test diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 69fec9c4a..04139566a 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -93,7 +93,7 @@ io.rest-assured rest-assured - 5.5.2 + 5.5.5 test From cb1bf4778223eaeaad008b62b877112436a33fda Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Wed, 28 May 2025 14:34:30 -0400 Subject: [PATCH 1301/1323] [client] add descriptive error msg --- .../src/main/java/io/avaje/http/api/Generated.java | 7 ++++--- .../main/java/io/avaje/http/client/DHttpApi.java | 13 +++++++++---- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/http-api/src/main/java/io/avaje/http/api/Generated.java b/http-api/src/main/java/io/avaje/http/api/Generated.java index 11f41f7f5..4ffd5205a 100644 --- a/http-api/src/main/java/io/avaje/http/api/Generated.java +++ b/http-api/src/main/java/io/avaje/http/api/Generated.java @@ -1,8 +1,9 @@ package io.avaje.http.api; -/** - * Marker for generated code. - */ +import java.lang.annotation.Documented; + +/** Marker for generated code. */ +@Documented public @interface Generated { /** diff --git a/http-client/src/main/java/io/avaje/http/client/DHttpApi.java b/http-client/src/main/java/io/avaje/http/client/DHttpApi.java index c0a95450c..3189b4fb0 100644 --- a/http-client/src/main/java/io/avaje/http/client/DHttpApi.java +++ b/http-client/src/main/java/io/avaje/http/client/DHttpApi.java @@ -1,13 +1,13 @@ package io.avaje.http.client; -import io.avaje.applog.AppLog; -import io.avaje.http.client.HttpClient.GeneratedComponent; +import static java.lang.System.Logger.Level.DEBUG; import java.util.HashMap; import java.util.Map; import java.util.ServiceLoader; -import static java.lang.System.Logger.Level.*; +import io.avaje.applog.AppLog; +import io.avaje.http.client.HttpClient.GeneratedComponent; /** Service loads the HttpApiProvider for HttpApi. */ final class DHttpApi { @@ -37,7 +37,12 @@ void addProvider(Class type, HttpApiProvider apiProvider) { T provideFor(Class type, HttpClient httpClient) { final var apiProvider = (HttpApiProvider) providerMap.get(type); if (apiProvider == null) { - throw new IllegalArgumentException("No registered HttpApiProvider for type: " + type); + throw new IllegalArgumentException( + "No registered HttpApiProvider for type: " + + type + + "\nPossible Causes: \n" + + "1. Missing @Client annotation on the type.\n" + + "2. The avaje-http-client-generator depedency was not available during compilation\n"); } return apiProvider.provide(httpClient); } From a076595410b0809a0a429eb8c32d613704d6d83e Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Wed, 28 May 2025 11:45:03 -0700 Subject: [PATCH 1302/1323] Update DHttpApi.java --- http-client/src/main/java/io/avaje/http/client/DHttpApi.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/http-client/src/main/java/io/avaje/http/client/DHttpApi.java b/http-client/src/main/java/io/avaje/http/client/DHttpApi.java index 3189b4fb0..dc03993fd 100644 --- a/http-client/src/main/java/io/avaje/http/client/DHttpApi.java +++ b/http-client/src/main/java/io/avaje/http/client/DHttpApi.java @@ -41,7 +41,7 @@ T provideFor(Class type, HttpClient httpClient) { "No registered HttpApiProvider for type: " + type + "\nPossible Causes: \n" - + "1. Missing @Client annotation on the type.\n" + + "1. Missing @Client or @Client.Import annotation.\n" + "2. The avaje-http-client-generator depedency was not available during compilation\n"); } return apiProvider.provide(httpClient); From 426eda314e2c56311388aa38ac9769da19b9c15c Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Wed, 28 May 2025 11:45:25 -0700 Subject: [PATCH 1303/1323] Update DHttpApi.java --- http-client/src/main/java/io/avaje/http/client/DHttpApi.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/http-client/src/main/java/io/avaje/http/client/DHttpApi.java b/http-client/src/main/java/io/avaje/http/client/DHttpApi.java index dc03993fd..19ce2a98c 100644 --- a/http-client/src/main/java/io/avaje/http/client/DHttpApi.java +++ b/http-client/src/main/java/io/avaje/http/client/DHttpApi.java @@ -42,7 +42,7 @@ T provideFor(Class type, HttpClient httpClient) { + type + "\nPossible Causes: \n" + "1. Missing @Client or @Client.Import annotation.\n" - + "2. The avaje-http-client-generator depedency was not available during compilation\n"); + + "2. The avaje-http-client-generator dependency was not available during compilation\n"); } return apiProvider.provide(httpClient); } From 3fb797cd255c2df142ab580716c9b410981e027a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Jun 2025 19:42:51 +0000 Subject: [PATCH 1304/1323] Bump the dependencies group with 6 updates Bumps the dependencies group with 6 updates: | Package | From | To | | --- | --- | --- | | [io.avaje:avaje-jsonb](https://github.com/avaje/avaje-jsonb) | `3.4` | `3.5` | | io.avaje:avaje-json-node | `3.4` | `3.5` | | io.avaje:avaje-jsonb-generator | `3.4` | `3.5` | | [org.junit.jupiter:junit-jupiter-api](https://github.com/junit-team/junit5) | `5.12.2` | `5.13.0` | | [org.junit.jupiter:junit-jupiter-engine](https://github.com/junit-team/junit5) | `5.12.2` | `5.13.0` | | io.avaje:avaje-json-core | `3.4` | `3.5` | Updates `io.avaje:avaje-jsonb` from 3.4 to 3.5 - [Release notes](https://github.com/avaje/avaje-jsonb/releases) - [Commits](https://github.com/avaje/avaje-jsonb/compare/3.4...3.5) Updates `io.avaje:avaje-json-node` from 3.4 to 3.5 Updates `io.avaje:avaje-jsonb-generator` from 3.4 to 3.5 Updates `org.junit.jupiter:junit-jupiter-api` from 5.12.2 to 5.13.0 - [Release notes](https://github.com/junit-team/junit5/releases) - [Commits](https://github.com/junit-team/junit5/compare/r5.12.2...r5.13.0) Updates `org.junit.jupiter:junit-jupiter-engine` from 5.12.2 to 5.13.0 - [Release notes](https://github.com/junit-team/junit5/releases) - [Commits](https://github.com/junit-team/junit5/compare/r5.12.2...r5.13.0) Updates `org.junit.jupiter:junit-jupiter-engine` from 5.12.2 to 5.13.0 - [Release notes](https://github.com/junit-team/junit5/releases) - [Commits](https://github.com/junit-team/junit5/compare/r5.12.2...r5.13.0) Updates `io.avaje:avaje-json-core` from 3.4 to 3.5 --- updated-dependencies: - dependency-name: io.avaje:avaje-jsonb dependency-version: '3.5' dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.avaje:avaje-json-node dependency-version: '3.5' dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.avaje:avaje-jsonb-generator dependency-version: '3.5' dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: org.junit.jupiter:junit-jupiter-api dependency-version: 5.13.0 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: org.junit.jupiter:junit-jupiter-engine dependency-version: 5.13.0 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: org.junit.jupiter:junit-jupiter-engine dependency-version: 5.13.0 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.avaje:avaje-json-core dependency-version: '3.5' dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies ... Signed-off-by: dependabot[bot] --- aws-cognito/http-client-authtoken/pom.xml | 4 ++-- http-client/pom.xml | 4 ++-- tests/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 4 ++-- tests/test-jex/pom.xml | 4 ++-- tests/test-nima-htmx/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 4 ++-- tests/test-sigma/pom.xml | 4 ++-- 8 files changed, 14 insertions(+), 14 deletions(-) diff --git a/aws-cognito/http-client-authtoken/pom.xml b/aws-cognito/http-client-authtoken/pom.xml index 6923b7b5e..ecb1b2871 100644 --- a/aws-cognito/http-client-authtoken/pom.xml +++ b/aws-cognito/http-client-authtoken/pom.xml @@ -23,14 +23,14 @@ io.avaje avaje-json-core - 3.4 + 3.5 io.avaje avaje-json-node - 3.4 + 3.5 test diff --git a/http-client/pom.xml b/http-client/pom.xml index 21ff6895b..d9a155ee0 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -36,14 +36,14 @@ io.avaje avaje-jsonb - 3.4 + 3.5 true io.avaje avaje-json-node - 3.4 + 3.5 test diff --git a/tests/pom.xml b/tests/pom.xml index 968300108..83629da5b 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -12,7 +12,7 @@ true - 5.12.2 + 5.13.0 3.27.3 2.19.0 3.2 diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 2e8a24091..aa122cc99 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -74,13 +74,13 @@ io.avaje avaje-jsonb - 3.4 + 3.5 io.avaje avaje-jsonb-generator - 3.4 + 3.5 provided diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 0dfc9907c..77ce328c4 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -74,7 +74,7 @@ io.avaje avaje-jsonb - 3.4 + 3.5 @@ -140,7 +140,7 @@ io.avaje avaje-jsonb-generator - 3.4 + 3.5 io.avaje diff --git a/tests/test-nima-htmx/pom.xml b/tests/test-nima-htmx/pom.xml index d1e3fa946..38e6b7b65 100644 --- a/tests/test-nima-htmx/pom.xml +++ b/tests/test-nima-htmx/pom.xml @@ -88,7 +88,7 @@ io.avaje avaje-jsonb-generator - 3.4 + 3.5 io.jstach diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 055c5d613..cd9e3ee8c 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -44,7 +44,7 @@ io.avaje avaje-jsonb - 3.4 + 3.5 io.helidon.webserver @@ -104,7 +104,7 @@ io.avaje avaje-jsonb-generator - 3.4 + 3.5 io.avaje diff --git a/tests/test-sigma/pom.xml b/tests/test-sigma/pom.xml index f644951ba..fbb13ab61 100644 --- a/tests/test-sigma/pom.xml +++ b/tests/test-sigma/pom.xml @@ -82,12 +82,12 @@ io.avaje avaje-jsonb - 3.4 + 3.5 io.avaje avaje-jsonb-generator - 3.4 + 3.5 provided From 5d7bd7905d622c8cd91c5c2449b2a317fe1df1c3 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 3 Jun 2025 07:55:55 +1200 Subject: [PATCH 1305/1323] [helidon] Bug fix for list of query parameters or form parameters when parameters is empty (#610) * [helidon] Add test only for list of query parameters One or multiple params passes. Adding a test for NO parameters will fail. * [helidon] Fix for list of query parameters or form parameters Add the test and fix for this case. --- .../helidon/nima/NimaPlatformAdapter.java | 4 +- tests/test-nima/pom.xml | 6 +++ .../java/org/example/HelloController.java | 8 ++++ .../test/java/org/example/BaseWebTest.java | 47 +++++++++++++++++++ .../java/org/example/HelloControllerTest.java | 46 ++++++++++++++++++ 5 files changed, 109 insertions(+), 2 deletions(-) create mode 100644 tests/test-nima/src/test/java/org/example/BaseWebTest.java create mode 100644 tests/test-nima/src/test/java/org/example/HelloControllerTest.java diff --git a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/NimaPlatformAdapter.java b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/NimaPlatformAdapter.java index a33ce1dfa..61bc63f52 100644 --- a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/NimaPlatformAdapter.java +++ b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/NimaPlatformAdapter.java @@ -118,8 +118,8 @@ public void writeReadMapParameter(Append writer, ParamType paramType) { @Override public void writeReadCollectionParameter(Append writer, ParamType paramType, String paramName) { switch (paramType) { - case QUERYPARAM -> writer.append("queryParams.all(\"%s\")", paramName); - case FORMPARAM -> writer.append("formParams.all(\"%s\")", paramName); + case QUERYPARAM -> writer.append("queryParams.all(\"%s\", () -> java.util.List.of())", paramName); + case FORMPARAM -> writer.append("formParams.all(\"%s\", () -> java.util.List.of())", paramName); case HEADER -> writer.append( "req.headers().all(\"%s\", () -> java.util.List.of())", paramName); diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index 1b17a0b9a..aff2380dc 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -48,6 +48,12 @@ avaje-http-helidon-generator ${project.version} + + io.avaje + avaje-http-client + ${project.version} + test + diff --git a/tests/test-nima/src/main/java/org/example/HelloController.java b/tests/test-nima/src/main/java/org/example/HelloController.java index ae147fc9a..8ae7994fe 100644 --- a/tests/test-nima/src/main/java/org/example/HelloController.java +++ b/tests/test-nima/src/main/java/org/example/HelloController.java @@ -6,6 +6,8 @@ import io.avaje.http.api.Get; import io.avaje.http.api.Produces; +import java.util.List; + @Controller public class HelloController { @@ -33,4 +35,10 @@ String name(String name, String sortBy, @Default("0") long max) { Person getP(@BeanParam Person person) { return person; } + + @Produces("text/plain") + @Get("listParams") + String listParam(List codes) { + return "codes:" + codes; + } } diff --git a/tests/test-nima/src/test/java/org/example/BaseWebTest.java b/tests/test-nima/src/test/java/org/example/BaseWebTest.java new file mode 100644 index 000000000..20e42a00d --- /dev/null +++ b/tests/test-nima/src/test/java/org/example/BaseWebTest.java @@ -0,0 +1,47 @@ +package org.example; + +import io.avaje.http.client.HttpClient; +import io.avaje.inject.BeanScope; +import io.helidon.webserver.WebServer; +import io.helidon.webserver.http.HttpFeature; +import io.helidon.webserver.http.HttpRouting; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; + +import java.time.Duration; +import java.util.List; + +public class BaseWebTest { + + static WebServer webServer; + + public static String baseUrl; + + + @BeforeAll + public static void init() { + List routes = BeanScope.builder().build().list(HttpFeature.class); + final var builder = HttpRouting.builder(); + routes.forEach(builder::addFeature); + + webServer = WebServer.builder().addRouting(builder) + .port(9067) + .build() + .start(); + + baseUrl = "http://localhost:9067"; + } + + @AfterAll + public static void shutdown() { + webServer.stop(); + } + + public static HttpClient client() { + return HttpClient.builder() + .baseUrl(baseUrl) + .requestTimeout(Duration.ofMinutes(2)) + //.bodyAdapter(new JacksonBodyAdapter()) + .build(); + } +} diff --git a/tests/test-nima/src/test/java/org/example/HelloControllerTest.java b/tests/test-nima/src/test/java/org/example/HelloControllerTest.java new file mode 100644 index 000000000..784493440 --- /dev/null +++ b/tests/test-nima/src/test/java/org/example/HelloControllerTest.java @@ -0,0 +1,46 @@ +package org.example; + +import org.junit.jupiter.api.Test; +import java.net.http.HttpResponse; + + +import static org.assertj.core.api.Assertions.assertThat; + +class HelloControllerTest extends BaseWebTest { + + @Test + void listParamOne() { + HttpResponse res = client().request() + .path("listParams") + .queryParam("codes", "123") + .GET() + .asPlainString(); + + assertThat(res.statusCode()).isEqualTo(200); + assertThat(res.body()).isEqualTo("codes:[123]"); + } + + @Test + void listParamMultiple() { + HttpResponse res = client().request() + .path("listParams") + .queryParam("codes", "123") + .queryParam("codes", "456") + .GET() + .asPlainString(); + + assertThat(res.statusCode()).isEqualTo(200); + assertThat(res.body()).isEqualTo("codes:[123, 456]"); + } + + @Test + void listParamEmpty() { + HttpResponse res = client().request() + .path("listParams") + .GET() + .asPlainString(); + + assertThat(res.statusCode()).isEqualTo(200); + assertThat(res.body()).isEqualTo("codes:[]"); + } +} From 9a7d32c9e10b8808151df8dbe3e51da0828ffbf9 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Wed, 4 Jun 2025 07:43:23 +1200 Subject: [PATCH 1306/1323] Version 3.4-RC1 --- aws-cognito/http-client-authtoken/pom.xml | 2 +- htmx-api/pom.xml | 6 ++---- htmx-nima-jstache/pom.xml | 3 ++- htmx-nima/pom.xml | 5 +++-- http-api-javalin/pom.xml | 3 ++- http-api/pom.xml | 3 ++- http-client-gson-adapter/pom.xml | 5 +++-- http-client-moshi-adapter/pom.xml | 26 ++++++++--------------- http-client/pom.xml | 3 ++- http-generator-client/pom.xml | 3 ++- http-generator-core/pom.xml | 3 ++- http-generator-helidon/pom.xml | 3 ++- http-generator-javalin/pom.xml | 5 +++-- http-generator-jex/pom.xml | 11 +++++----- http-generator-sigma/pom.xml | 3 ++- http-inject-plugin/pom.xml | 3 ++- pom.xml | 5 +++-- tests/pom.xml | 2 +- tests/test-client-generation/pom.xml | 2 +- tests/test-client/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-htmx/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- tests/test-sigma/pom.xml | 2 +- 27 files changed, 58 insertions(+), 54 deletions(-) diff --git a/aws-cognito/http-client-authtoken/pom.xml b/aws-cognito/http-client-authtoken/pom.xml index ecb1b2871..8a6ad5720 100644 --- a/aws-cognito/http-client-authtoken/pom.xml +++ b/aws-cognito/http-client-authtoken/pom.xml @@ -17,7 +17,7 @@ io.avaje avaje-http-client - 3.3 + 3.4-RC1 diff --git a/htmx-api/pom.xml b/htmx-api/pom.xml index 0ba9b615c..acc36cb23 100644 --- a/htmx-api/pom.xml +++ b/htmx-api/pom.xml @@ -6,13 +6,11 @@ io.avaje avaje-http-parent - 3.3 + 3.4-RC1 avaje-htmx-api - - - + avaje-htmx-api diff --git a/htmx-nima-jstache/pom.xml b/htmx-nima-jstache/pom.xml index 34d8a9c63..f402aee74 100644 --- a/htmx-nima-jstache/pom.xml +++ b/htmx-nima-jstache/pom.xml @@ -6,10 +6,11 @@ io.avaje avaje-http-parent - 3.3 + 3.4-RC1 avaje-htmx-nima-jstache + avaje-htmx-nima-jstache 21 diff --git a/htmx-nima/pom.xml b/htmx-nima/pom.xml index 172255d4b..2026d5df1 100644 --- a/htmx-nima/pom.xml +++ b/htmx-nima/pom.xml @@ -6,10 +6,11 @@ io.avaje avaje-http-parent - 3.3 + 3.4-RC1 avaje-htmx-nima + avaje-htmx-nima 21 @@ -21,7 +22,7 @@ io.avaje avaje-htmx-api - 3.3 + 3.4-RC1 io.helidon.webserver diff --git a/http-api-javalin/pom.xml b/http-api-javalin/pom.xml index 45ca2597f..a95960c30 100644 --- a/http-api-javalin/pom.xml +++ b/http-api-javalin/pom.xml @@ -4,11 +4,12 @@ io.avaje avaje-http-parent - 3.3 + 3.4-RC1 .. avaje-http-api-javalin + avaje-http-api-javalin scm:git:git@github.com:avaje/avaje-http.git diff --git a/http-api/pom.xml b/http-api/pom.xml index efe67cd78..156038a0d 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,11 +4,12 @@ io.avaje avaje-http-parent - 3.3 + 3.4-RC1 .. avaje-http-api + avaje-http-api scm:git:git@github.com:avaje/avaje-http.git diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index fb061a565..b878e4924 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,10 +4,11 @@ io.avaje avaje-http-parent - 3.3 + 3.4-RC1 avaje-http-client-gson + avaje-http-client-gson @@ -20,7 +21,7 @@ io.avaje avaje-http-client - 3.3 + 3.4-RC1 provided diff --git a/http-client-moshi-adapter/pom.xml b/http-client-moshi-adapter/pom.xml index b33c4e4a8..1d4bb95bc 100644 --- a/http-client-moshi-adapter/pom.xml +++ b/http-client-moshi-adapter/pom.xml @@ -3,33 +3,25 @@ io.avaje avaje-http-parent - 3.3 + 3.4-RC1 avaje-http-client-moshi + avaje-http-client-moshi - - com.squareup.moshi - moshi - 1.15.2 - true - - - io.avaje - avaje-http-client - 3.3 - provided + com.squareup.moshi + moshi + 1.15.2 + true - - io.avaje - junit - 1.6 - test + avaje-http-client + 3.4-RC1 + provided diff --git a/http-client/pom.xml b/http-client/pom.xml index d9a155ee0..c8f0916cc 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,10 +4,11 @@ io.avaje avaje-http-parent - 3.3 + 3.4-RC1 avaje-http-client + avaje-http-client scm:git:git@github.com:avaje/avaje-http-client.git diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index f52666d40..6fb68e01f 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -4,10 +4,11 @@ io.avaje avaje-http-parent - 3.3 + 3.4-RC1 avaje-http-client-generator + avaje-http-client-generator 11 diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index a8aeca6e8..ee33f67fe 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -4,10 +4,11 @@ io.avaje avaje-http-parent - 3.3 + 3.4-RC1 avaje-http-generator-core + avaje-http-generator-core diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index d0d525a04..806749237 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -4,10 +4,11 @@ avaje-http-parent io.avaje - 3.3 + 3.4-RC1 avaje-http-helidon-generator + avaje-http-helidon-generator 21 diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index cd90d3c27..2f56448f0 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -4,10 +4,11 @@ io.avaje avaje-http-parent - 3.3 + 3.4-RC1 avaje-http-javalin-generator + avaje-http-javalin-generator @@ -23,7 +24,7 @@ ${avaje.prisms.version} provided - + io.avaje avaje-http-api-javalin diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index 5a8bcffff..b2f8ad603 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -4,15 +4,16 @@ io.avaje avaje-http-parent - 3.3 + 3.4-RC1 avaje-http-jex-generator - + avaje-http-jex-generator + 21 - + @@ -20,13 +21,13 @@ avaje-http-generator-core ${project.version} - + io.avaje avaje-prisms ${avaje.prisms.version} provided - + diff --git a/http-generator-sigma/pom.xml b/http-generator-sigma/pom.xml index 0b8946b2d..f620399db 100644 --- a/http-generator-sigma/pom.xml +++ b/http-generator-sigma/pom.xml @@ -4,10 +4,11 @@ io.avaje avaje-http-parent - 3.3 + 3.4-RC1 avaje-http-sigma-generator + avaje-http-sigma-generator 17 diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index 72e8a06a7..8b2262485 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -4,11 +4,12 @@ io.avaje avaje-http-parent - 3.3 + 3.4-RC1 .. avaje-http-inject-plugin + avaje-http-inject-plugin scm:git:git@github.com:avaje/avaje-http.git diff --git a/pom.xml b/pom.xml index aa434e417..d1103ce9e 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,8 @@ io.avaje avaje-http-parent - 3.3 + avaje-http-parent + 3.4-RC1 pom @@ -23,7 +24,7 @@ 2.14.2 3.0-RC10 1.42 - 2025-04-29T22:40:45Z + 2025-06-03T19:27:32Z ${project.build.directory}${file.separator}module-info.shade diff --git a/tests/pom.xml b/tests/pom.xml index 83629da5b..0b3fde79e 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 3.3 + 3.4-RC1 tests diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index 8410d6c9c..0de754290 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 3.3 + 3.4-RC1 test-client-generation diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index 526908105..5c9e47097 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 3.3 + 3.4-RC1 test-client diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index aa122cc99..a972306e7 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 3.3 + 3.4-RC1 test-javalin-jsonb diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 04139566a..fa109f15f 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 3.3 + 3.4-RC1 test-javalin diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 77ce328c4..c8813d939 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 3.3 + 3.4-RC1 test-jex diff --git a/tests/test-nima-htmx/pom.xml b/tests/test-nima-htmx/pom.xml index 38e6b7b65..fab0b541b 100644 --- a/tests/test-nima-htmx/pom.xml +++ b/tests/test-nima-htmx/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 3.3 + 3.4-RC1 test-nima-htmx diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index cd9e3ee8c..de7e220b8 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 3.3 + 3.4-RC1 test-nima-jsonb diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index aff2380dc..a205d530d 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 3.3 + 3.4-RC1 test-nima diff --git a/tests/test-sigma/pom.xml b/tests/test-sigma/pom.xml index fbb13ab61..4fdefbca8 100644 --- a/tests/test-sigma/pom.xml +++ b/tests/test-sigma/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 3.3 + 3.4-RC1 test-sigma From 875d9e67059b548adf91e23850f2af7abecc7099 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Jun 2025 19:41:32 +0000 Subject: [PATCH 1307/1323] Bump the dependencies group with 5 updates Bumps the dependencies group with 5 updates: | Package | From | To | | --- | --- | --- | | io.helidon.webserver:helidon-webserver | `4.2.2` | `4.2.3` | | io.helidon.webserver:helidon-webserver-security | `4.2.2` | `4.2.3` | | io.helidon.http.media:helidon-http-media-jsonb | `4.2.2` | `4.2.3` | | [org.junit.jupiter:junit-jupiter-api](https://github.com/junit-team/junit5) | `5.13.0` | `5.13.1` | | [org.junit.jupiter:junit-jupiter-engine](https://github.com/junit-team/junit5) | `5.13.0` | `5.13.1` | Updates `io.helidon.webserver:helidon-webserver` from 4.2.2 to 4.2.3 Updates `io.helidon.webserver:helidon-webserver-security` from 4.2.2 to 4.2.3 Updates `io.helidon.http.media:helidon-http-media-jsonb` from 4.2.2 to 4.2.3 Updates `io.helidon.webserver:helidon-webserver-security` from 4.2.2 to 4.2.3 Updates `io.helidon.http.media:helidon-http-media-jsonb` from 4.2.2 to 4.2.3 Updates `org.junit.jupiter:junit-jupiter-api` from 5.13.0 to 5.13.1 - [Release notes](https://github.com/junit-team/junit5/releases) - [Commits](https://github.com/junit-team/junit5/compare/r5.13.0...r5.13.1) Updates `org.junit.jupiter:junit-jupiter-engine` from 5.13.0 to 5.13.1 - [Release notes](https://github.com/junit-team/junit5/releases) - [Commits](https://github.com/junit-team/junit5/compare/r5.13.0...r5.13.1) Updates `org.junit.jupiter:junit-jupiter-engine` from 5.13.0 to 5.13.1 - [Release notes](https://github.com/junit-team/junit5/releases) - [Commits](https://github.com/junit-team/junit5/compare/r5.13.0...r5.13.1) --- updated-dependencies: - dependency-name: io.helidon.webserver:helidon-webserver dependency-version: 4.2.3 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: io.helidon.webserver:helidon-webserver-security dependency-version: 4.2.3 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: io.helidon.http.media:helidon-http-media-jsonb dependency-version: 4.2.3 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: io.helidon.webserver:helidon-webserver-security dependency-version: 4.2.3 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: io.helidon.http.media:helidon-http-media-jsonb dependency-version: 4.2.3 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: org.junit.jupiter:junit-jupiter-api dependency-version: 5.13.1 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: org.junit.jupiter:junit-jupiter-engine dependency-version: 5.13.1 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: org.junit.jupiter:junit-jupiter-engine dependency-version: 5.13.1 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: dependencies ... Signed-off-by: dependabot[bot] --- htmx-nima/pom.xml | 2 +- tests/pom.xml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/htmx-nima/pom.xml b/htmx-nima/pom.xml index 2026d5df1..73777c40f 100644 --- a/htmx-nima/pom.xml +++ b/htmx-nima/pom.xml @@ -27,7 +27,7 @@ io.helidon.webserver helidon-webserver - 4.2.2 + 4.2.3 diff --git a/tests/pom.xml b/tests/pom.xml index 0b3fde79e..fe31b3c30 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -12,12 +12,12 @@ true - 5.13.0 + 5.13.1 3.27.3 2.19.0 3.2 11.5 - 4.2.2 + 4.2.3 6.6.0 From 3e1b7626b5bf87267d883d3c1d5f72603f8876ed Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Jun 2025 20:39:45 +0000 Subject: [PATCH 1308/1323] Bump the dependencies group with 3 updates Bumps the dependencies group with 3 updates: [com.fasterxml.jackson.core:jackson-databind](https://github.com/FasterXML/jackson), io.swagger.core.v3:swagger-models and io.swagger.core.v3:swagger-annotations. Updates `com.fasterxml.jackson.core:jackson-databind` from 2.19.0 to 2.19.1 - [Commits](https://github.com/FasterXML/jackson/commits) Updates `io.swagger.core.v3:swagger-models` from 2.2.32 to 2.2.33 Updates `io.swagger.core.v3:swagger-annotations` from 2.2.32 to 2.2.33 Updates `io.swagger.core.v3:swagger-annotations` from 2.2.32 to 2.2.33 --- updated-dependencies: - dependency-name: com.fasterxml.jackson.core:jackson-databind dependency-version: 2.19.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: io.swagger.core.v3:swagger-models dependency-version: 2.2.33 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: io.swagger.core.v3:swagger-annotations dependency-version: 2.2.33 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: io.swagger.core.v3:swagger-annotations dependency-version: 2.2.33 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies ... Signed-off-by: dependabot[bot] --- http-client/pom.xml | 2 +- pom.xml | 2 +- tests/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-sigma/pom.xml | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/http-client/pom.xml b/http-client/pom.xml index c8f0916cc..d7b642846 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -30,7 +30,7 @@ com.fasterxml.jackson.core jackson-databind - 2.19.0 + 2.19.1 true diff --git a/pom.xml b/pom.xml index d1103ce9e..ebeb2a695 100644 --- a/pom.xml +++ b/pom.xml @@ -20,7 +20,7 @@ true - 2.2.32 + 2.2.33 2.14.2 3.0-RC10 1.42 diff --git a/tests/pom.xml b/tests/pom.xml index fe31b3c30..e2f5f5e2a 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -14,7 +14,7 @@ true 5.13.1 3.27.3 - 2.19.0 + 2.19.1 3.2 11.5 4.2.3 diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index a972306e7..8698893a3 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -13,7 +13,7 @@ true org.example.myapp.Main - 2.2.32 + 2.2.33 1.3.71 diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index fa109f15f..796509215 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -12,7 +12,7 @@ true org.example.myapp.Main - 2.2.32 + 2.2.33 1.3.71 diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index c8813d939..ff146cbb1 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -12,7 +12,7 @@ 21 true org.example.myapp.Main - 2.2.32 + 2.2.33 diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index de7e220b8..0af08b583 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -13,7 +13,7 @@ 21 - 2.2.32 + 2.2.33 UTF-8 false diff --git a/tests/test-sigma/pom.xml b/tests/test-sigma/pom.xml index 4fdefbca8..e91e4635f 100644 --- a/tests/test-sigma/pom.xml +++ b/tests/test-sigma/pom.xml @@ -13,7 +13,7 @@ 17 true - 2.2.32 + 2.2.33 1.3.71 From 3de47c3fbc3ab72863d9a851bbfe99728ba42748 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 23 Jun 2025 20:56:23 +0000 Subject: [PATCH 1309/1323] Bump the dependencies group with 4 updates Bumps the dependencies group with 4 updates: [io.javalin:javalin](https://github.com/javalin/javalin), io.swagger.core.v3:swagger-models, io.swagger.core.v3:swagger-annotations and [io.repaint.maven:tiles-maven-plugin](https://github.com/repaint-io/maven-tiles). Updates `io.javalin:javalin` from 6.6.0 to 6.7.0 - [Release notes](https://github.com/javalin/javalin/releases) - [Commits](https://github.com/javalin/javalin/compare/javalin-parent-6.6.0...javalin-parent-6.7.0) Updates `io.swagger.core.v3:swagger-models` from 2.2.33 to 2.2.34 Updates `io.swagger.core.v3:swagger-annotations` from 2.2.33 to 2.2.34 Updates `io.swagger.core.v3:swagger-annotations` from 2.2.33 to 2.2.34 Updates `io.repaint.maven:tiles-maven-plugin` from 2.40 to 2.41 - [Release notes](https://github.com/repaint-io/maven-tiles/releases) - [Changelog](https://github.com/repaint-io/maven-tiles/blob/master/CHANGELOG.adoc) - [Commits](https://github.com/repaint-io/maven-tiles/compare/tiles-maven-plugin-2.40...tiles-maven-plugin-2.41) --- updated-dependencies: - dependency-name: io.javalin:javalin dependency-version: 6.7.0 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.swagger.core.v3:swagger-models dependency-version: 2.2.34 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: io.swagger.core.v3:swagger-annotations dependency-version: 2.2.34 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: io.swagger.core.v3:swagger-annotations dependency-version: 2.2.34 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: io.repaint.maven:tiles-maven-plugin dependency-version: '2.41' dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies ... Signed-off-by: dependabot[bot] --- http-api/pom.xml | 2 +- http-client/pom.xml | 2 +- pom.xml | 2 +- tests/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 4 ++-- tests/test-javalin/pom.xml | 4 ++-- tests/test-jex/pom.xml | 4 ++-- tests/test-nima-jsonb/pom.xml | 4 ++-- tests/test-sigma/pom.xml | 4 ++-- 9 files changed, 14 insertions(+), 14 deletions(-) diff --git a/http-api/pom.xml b/http-api/pom.xml index 156038a0d..389e6b145 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -25,7 +25,7 @@ io.javalin javalin - 6.6.0 + 6.7.0 provided true diff --git a/http-client/pom.xml b/http-client/pom.xml index d7b642846..17a22d0fe 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -67,7 +67,7 @@ io.javalin javalin - 6.6.0 + 6.7.0 test diff --git a/pom.xml b/pom.xml index ebeb2a695..7594a8e68 100644 --- a/pom.xml +++ b/pom.xml @@ -20,7 +20,7 @@ true - 2.2.33 + 2.2.34 2.14.2 3.0-RC10 1.42 diff --git a/tests/pom.xml b/tests/pom.xml index e2f5f5e2a..b292043c3 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -18,7 +18,7 @@ 3.2 11.5 4.2.3 - 6.6.0 + 6.7.0 diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 8698893a3..ff8cd333b 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -13,7 +13,7 @@ true org.example.myapp.Main - 2.2.33 + 2.2.34 1.3.71 @@ -130,7 +130,7 @@ io.repaint.maven tiles-maven-plugin - 2.40 + 2.41 true diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 796509215..92f8012d0 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -12,7 +12,7 @@ true org.example.myapp.Main - 2.2.33 + 2.2.34 1.3.71 @@ -128,7 +128,7 @@ io.repaint.maven tiles-maven-plugin - 2.40 + 2.41 true diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index ff146cbb1..7c8671215 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -12,7 +12,7 @@ 21 true org.example.myapp.Main - 2.2.33 + 2.2.34 @@ -174,7 +174,7 @@ io.repaint.maven tiles-maven-plugin - 2.40 + 2.41 true diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 0af08b583..4a487bab2 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -13,7 +13,7 @@ 21 - 2.2.33 + 2.2.34 UTF-8 false @@ -122,7 +122,7 @@ io.repaint.maven tiles-maven-plugin - 2.40 + 2.41 true diff --git a/tests/test-sigma/pom.xml b/tests/test-sigma/pom.xml index e91e4635f..51747c0be 100644 --- a/tests/test-sigma/pom.xml +++ b/tests/test-sigma/pom.xml @@ -13,7 +13,7 @@ 17 true - 2.2.33 + 2.2.34 1.3.71 @@ -122,7 +122,7 @@ io.repaint.maven tiles-maven-plugin - 2.40 + 2.41 true From 6093f410b4ba4cdc085531f228f7a48d7236d1f6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 30 Jun 2025 22:41:22 +0000 Subject: [PATCH 1310/1323] Bump the dependencies group with 3 updates Bumps the dependencies group with 3 updates: [io.avaje:avaje-applog](https://github.com/avaje/avaje-applog), [org.junit.jupiter:junit-jupiter-api](https://github.com/junit-team/junit-framework) and [org.junit.jupiter:junit-jupiter-engine](https://github.com/junit-team/junit-framework). Updates `io.avaje:avaje-applog` from 1.0 to 1.1 - [Release notes](https://github.com/avaje/avaje-applog/releases) - [Commits](https://github.com/avaje/avaje-applog/compare/avaje-applog-1.0...1.1) Updates `org.junit.jupiter:junit-jupiter-api` from 5.13.1 to 5.13.2 - [Release notes](https://github.com/junit-team/junit-framework/releases) - [Commits](https://github.com/junit-team/junit-framework/compare/r5.13.1...r5.13.2) Updates `org.junit.jupiter:junit-jupiter-engine` from 5.13.1 to 5.13.2 - [Release notes](https://github.com/junit-team/junit-framework/releases) - [Commits](https://github.com/junit-team/junit-framework/compare/r5.13.1...r5.13.2) Updates `org.junit.jupiter:junit-jupiter-engine` from 5.13.1 to 5.13.2 - [Release notes](https://github.com/junit-team/junit-framework/releases) - [Commits](https://github.com/junit-team/junit-framework/compare/r5.13.1...r5.13.2) --- updated-dependencies: - dependency-name: io.avaje:avaje-applog dependency-version: '1.1' dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: org.junit.jupiter:junit-jupiter-api dependency-version: 5.13.2 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: org.junit.jupiter:junit-jupiter-engine dependency-version: 5.13.2 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: org.junit.jupiter:junit-jupiter-engine dependency-version: 5.13.2 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: dependencies ... Signed-off-by: dependabot[bot] --- http-client/pom.xml | 2 +- tests/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/http-client/pom.xml b/http-client/pom.xml index 17a22d0fe..71e999203 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -24,7 +24,7 @@ io.avaje avaje-applog - 1.0 + 1.1 diff --git a/tests/pom.xml b/tests/pom.xml index b292043c3..93d804d2b 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -12,7 +12,7 @@ true - 5.13.1 + 5.13.2 3.27.3 2.19.1 3.2 From 3809a26df822b6d8880c990d52c2a7de71fc5355 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 30 Jun 2025 22:46:22 +0000 Subject: [PATCH 1311/1323] Bump io.avaje:avaje-applog from 1.1 to 1.2 in the dependencies group Bumps the dependencies group with 1 update: [io.avaje:avaje-applog](https://github.com/avaje/avaje-applog). Updates `io.avaje:avaje-applog` from 1.1 to 1.2 - [Release notes](https://github.com/avaje/avaje-applog/releases) - [Commits](https://github.com/avaje/avaje-applog/compare/1.1...1.2) --- updated-dependencies: - dependency-name: io.avaje:avaje-applog dependency-version: '1.2' dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies ... Signed-off-by: dependabot[bot] --- http-client/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/http-client/pom.xml b/http-client/pom.xml index 71e999203..4519ac50a 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -24,7 +24,7 @@ io.avaje avaje-applog - 1.1 + 1.2 From 3f441be81b700f1efe4918c5fda54edb0e6d91d3 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Mon, 7 Jul 2025 16:13:52 -0400 Subject: [PATCH 1312/1323] [http-client] combine generated consecutive path literals (#617) * combine path literals --- .../generator/client/ClientMethodWriter.java | 61 +++++++++++++++---- .../generator/client/clients/ApiClient.java | 3 + .../client/clients/PrivateClient2.java | 1 - 3 files changed, 51 insertions(+), 14 deletions(-) diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java index 6d193dedc..b1be334ed 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java @@ -1,10 +1,11 @@ package io.avaje.http.generator.client; -import io.avaje.http.generator.core.*; -import io.avaje.http.generator.core.PathSegments.Segment; +import static io.avaje.http.generator.core.ProcessingContext.isAssignable2Interface; +import static io.avaje.http.generator.core.ProcessingContext.logError; +import static io.avaje.http.generator.core.ProcessingContext.typeElement; +import static java.util.stream.Collectors.toList; +import static java.util.stream.Collectors.toMap; -import javax.lang.model.element.TypeElement; -import javax.lang.model.util.ElementFilter; import java.util.List; import java.util.Map; import java.util.Map.Entry; @@ -13,9 +14,23 @@ import java.util.stream.Collectors; import java.util.stream.Stream; -import static io.avaje.http.generator.core.ProcessingContext.*; -import static java.util.stream.Collectors.toList; -import static java.util.stream.Collectors.toMap; +import javax.lang.model.element.TypeElement; +import javax.lang.model.util.ElementFilter; + +import io.avaje.http.generator.core.APContext; +import io.avaje.http.generator.core.Append; +import io.avaje.http.generator.core.BeanParamReader; +import io.avaje.http.generator.core.ControllerReader; +import io.avaje.http.generator.core.MethodParam; +import io.avaje.http.generator.core.MethodReader; +import io.avaje.http.generator.core.ParamType; +import io.avaje.http.generator.core.PathSegments; +import io.avaje.http.generator.core.PathSegments.Segment; +import io.avaje.http.generator.core.ProcessingContext; +import io.avaje.http.generator.core.RequestTimeoutPrism; +import io.avaje.http.generator.core.UType; +import io.avaje.http.generator.core.Util; +import io.avaje.http.generator.core.WebMethod; /** * Write code to register Web route for a given controller method. @@ -399,16 +414,36 @@ private void writePaths(Set segments) { if (!segments.isEmpty()) { writer.append(" "); } - for (PathSegments.Segment segment : segments) { + + StringBuilder combinedLiterals = new StringBuilder(); + + for (var segment : segments) { if (segment.isLiteral()) { - writer.append(".path(\"").append(segment.literalSection()).append("\")"); - } else if (segment.isProperty()) { - writer.append(".path(").append(segmentPropertyMap.get(segment.name())).append(")"); + // Accumulate literal segments with "/" delimiter + if (combinedLiterals.length() > 0) { + combinedLiterals.append("/"); + } + combinedLiterals.append(segment.literalSection()); } else { - writer.append(".path(").append(segment.name()).append(")"); - // TODO: matrix params + // If we have accumulated literals, write them out first + if (combinedLiterals.length() > 0) { + writer.append(".path(\"").append(combinedLiterals.toString()).append("\")"); + combinedLiterals.setLength(0); // Clear the buffer + } + // Write the non-literal segment + if (segment.isProperty()) { + writer.append(".path(").append(segmentPropertyMap.get(segment.name())).append(")"); + } else { + writer.append(".path(").append(segment.name()).append(")"); + } } } + + // Write any remaining accumulated literals + if (combinedLiterals.length() > 0) { + writer.append(".path(\"").append(combinedLiterals.toString()).append("\")"); + } + if (!segments.isEmpty()) { writer.eol(); } diff --git a/http-generator-client/src/test/java/io/avaje/http/generator/client/clients/ApiClient.java b/http-generator-client/src/test/java/io/avaje/http/generator/client/clients/ApiClient.java index 2cf137130..7c3d57baa 100644 --- a/http-generator-client/src/test/java/io/avaje/http/generator/client/clients/ApiClient.java +++ b/http-generator-client/src/test/java/io/avaje/http/generator/client/clients/ApiClient.java @@ -12,4 +12,7 @@ public interface ApiClient { @Get("/mapped") String mapped(@Header("Accept") String accept) throws MappedException; + + @Get("/consecutive/paths/{accept}/generate") + String consecutive(String accept); } diff --git a/http-generator-client/src/test/java/io/avaje/http/generator/client/clients/PrivateClient2.java b/http-generator-client/src/test/java/io/avaje/http/generator/client/clients/PrivateClient2.java index 407fa636e..443dc7623 100644 --- a/http-generator-client/src/test/java/io/avaje/http/generator/client/clients/PrivateClient2.java +++ b/http-generator-client/src/test/java/io/avaje/http/generator/client/clients/PrivateClient2.java @@ -9,5 +9,4 @@ public interface PrivateClient2 { @Get("/private") String apiCall(@Header("Accept") String accept); - } From e26161dda0018cbf6d88ba98f33b5cc96a211f5c Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sun, 13 Jul 2025 17:05:40 -0400 Subject: [PATCH 1313/1323] [Client] fix async generic responses (#618) Fixes error where `asyncBean(Type)` didn't not return an `java.net.http.HttpResponse` instance --- .../avaje/http/client/DHttpClientRequest.java | 23 ++----------------- 1 file changed, 2 insertions(+), 21 deletions(-) diff --git a/http-client/src/main/java/io/avaje/http/client/DHttpClientRequest.java b/http-client/src/main/java/io/avaje/http/client/DHttpClientRequest.java index 00f536b27..fc740b2d8 100644 --- a/http-client/src/main/java/io/avaje/http/client/DHttpClientRequest.java +++ b/http-client/src/main/java/io/avaje/http/client/DHttpClientRequest.java @@ -644,35 +644,16 @@ protected HttpResponse asyncVoid(HttpResponse response) { return new HttpWrapperResponse<>(response); } - protected HttpResponse asyncBean(Class type, HttpResponse response) { + protected HttpResponse asyncBean(Type type, HttpResponse response) { afterAsyncEncoded(response); return new HttpWrapperResponse<>(context.readBean(type, encodedResponseBody), httpResponse); } - protected E asyncBean(Type type, HttpResponse response) { - afterAsyncEncoded(response); - return context.readBean(type, encodedResponseBody); - } - - protected HttpResponse> asyncList(Class type, HttpResponse response) { - afterAsyncEncoded(response); - return new HttpWrapperResponse<>(context.readList(type, encodedResponseBody), httpResponse); - } - protected HttpResponse> asyncList(Type type, HttpResponse response) { afterAsyncEncoded(response); return new HttpWrapperResponse<>(context.readList(type, encodedResponseBody), httpResponse); } - protected HttpResponse> asyncStream(Class type, HttpResponse> response) { - responseTimeNanos = System.nanoTime() - startAsyncNanos; - httpResponse = response; - context.afterResponse(this); - checkResponse(response); - final BodyReader bodyReader = context.beanReader(type); - return new HttpWrapperResponse<>(response.body().map(bodyReader::readBody), httpResponse); - } - protected HttpResponse> asyncStream(Type type, HttpResponse> response) { responseTimeNanos = System.nanoTime() - startAsyncNanos; httpResponse = response; @@ -853,7 +834,7 @@ public String responseBody() { return context.maxResponseBody(new String(encodedResponseBody.content(), StandardCharsets.UTF_8)); } else if (httpResponse != null && loggableResponseBody) { final var responseBody = httpResponse.body(); - return (responseBody == null) ? null : context.maxResponseBody(responseBody.toString()); + return responseBody == null ? null : context.maxResponseBody(responseBody.toString()); } return null; } From 8f6d2981292ac620b3dbc4e6377df50670900a6c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 13 Jul 2025 21:38:55 +0000 Subject: [PATCH 1314/1323] Bump the dependencies group with 5 updates Bumps the dependencies group with 5 updates: | Package | From | To | | --- | --- | --- | | [io.avaje:avaje-validator](https://github.com/avaje/avaje-validator) | `2.11` | `2.12` | | io.avaje:avaje-validator-constraints | `2.11` | `2.12` | | io.avaje:avaje-validator-generator | `2.11` | `2.12` | | [org.junit.jupiter:junit-jupiter-api](https://github.com/junit-team/junit-framework) | `5.13.2` | `5.13.3` | | [org.junit.jupiter:junit-jupiter-engine](https://github.com/junit-team/junit-framework) | `5.13.2` | `5.13.3` | Updates `io.avaje:avaje-validator` from 2.11 to 2.12 - [Release notes](https://github.com/avaje/avaje-validator/releases) - [Commits](https://github.com/avaje/avaje-validator/compare/2.11...2.12) Updates `io.avaje:avaje-validator-constraints` from 2.11 to 2.12 Updates `io.avaje:avaje-validator-generator` from 2.11 to 2.12 Updates `org.junit.jupiter:junit-jupiter-api` from 5.13.2 to 5.13.3 - [Release notes](https://github.com/junit-team/junit-framework/releases) - [Commits](https://github.com/junit-team/junit-framework/compare/r5.13.2...r5.13.3) Updates `org.junit.jupiter:junit-jupiter-engine` from 5.13.2 to 5.13.3 - [Release notes](https://github.com/junit-team/junit-framework/releases) - [Commits](https://github.com/junit-team/junit-framework/compare/r5.13.2...r5.13.3) Updates `org.junit.jupiter:junit-jupiter-engine` from 5.13.2 to 5.13.3 - [Release notes](https://github.com/junit-team/junit-framework/releases) - [Commits](https://github.com/junit-team/junit-framework/compare/r5.13.2...r5.13.3) --- updated-dependencies: - dependency-name: io.avaje:avaje-validator dependency-version: '2.12' dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.avaje:avaje-validator-constraints dependency-version: '2.12' dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.avaje:avaje-validator-generator dependency-version: '2.12' dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: org.junit.jupiter:junit-jupiter-api dependency-version: 5.13.3 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: org.junit.jupiter:junit-jupiter-engine dependency-version: 5.13.3 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: org.junit.jupiter:junit-jupiter-engine dependency-version: 5.13.3 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: dependencies ... Signed-off-by: dependabot[bot] --- tests/pom.xml | 8 ++++---- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/pom.xml b/tests/pom.xml index 93d804d2b..b20177b71 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -12,7 +12,7 @@ true - 5.13.2 + 5.13.3 3.27.3 2.19.1 3.2 @@ -48,19 +48,19 @@ io.avaje avaje-validator - 2.11 + 2.12 io.avaje avaje-validator-constraints - 2.11 + 2.12 io.avaje avaje-validator-generator - 2.11 + 2.12 diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 92f8012d0..5fdfd8b7d 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -57,7 +57,7 @@ io.avaje avaje-validator - 2.11 + 2.12 diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 7c8671215..6c77a33ef 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -145,7 +145,7 @@ io.avaje avaje-validator-generator - 2.11 + 2.12 io.jstach diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 4a487bab2..2242d88be 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -109,7 +109,7 @@ io.avaje avaje-validator-generator - 2.11 + 2.12 io.jstach From d6ba156b20fa009e41555a18f59dd19dba827053 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sun, 13 Jul 2025 19:20:20 -0400 Subject: [PATCH 1315/1323] 3.4-RC2 (#620) --- aws-cognito/http-client-authtoken/pom.xml | 2 +- htmx-api/pom.xml | 2 +- htmx-nima-jstache/pom.xml | 2 +- htmx-nima/pom.xml | 4 ++-- http-api-javalin/pom.xml | 2 +- http-api/pom.xml | 2 +- http-client-gson-adapter/pom.xml | 4 ++-- http-client-moshi-adapter/pom.xml | 4 ++-- http-client/pom.xml | 2 +- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 2 +- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-generator-sigma/pom.xml | 2 +- http-inject-plugin/pom.xml | 2 +- pom.xml | 4 ++-- tests/pom.xml | 2 +- tests/test-client-generation/pom.xml | 2 +- tests/test-client/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-htmx/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- tests/test-sigma/pom.xml | 2 +- 27 files changed, 31 insertions(+), 31 deletions(-) diff --git a/aws-cognito/http-client-authtoken/pom.xml b/aws-cognito/http-client-authtoken/pom.xml index 8a6ad5720..1d31458bc 100644 --- a/aws-cognito/http-client-authtoken/pom.xml +++ b/aws-cognito/http-client-authtoken/pom.xml @@ -17,7 +17,7 @@ io.avaje avaje-http-client - 3.4-RC1 + 3.4-RC2 diff --git a/htmx-api/pom.xml b/htmx-api/pom.xml index acc36cb23..e4b1c46b0 100644 --- a/htmx-api/pom.xml +++ b/htmx-api/pom.xml @@ -6,7 +6,7 @@ io.avaje avaje-http-parent - 3.4-RC1 + 3.4-RC2 avaje-htmx-api diff --git a/htmx-nima-jstache/pom.xml b/htmx-nima-jstache/pom.xml index f402aee74..b6dcba6a5 100644 --- a/htmx-nima-jstache/pom.xml +++ b/htmx-nima-jstache/pom.xml @@ -6,7 +6,7 @@ io.avaje avaje-http-parent - 3.4-RC1 + 3.4-RC2 avaje-htmx-nima-jstache diff --git a/htmx-nima/pom.xml b/htmx-nima/pom.xml index 73777c40f..23efa4913 100644 --- a/htmx-nima/pom.xml +++ b/htmx-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje avaje-http-parent - 3.4-RC1 + 3.4-RC2 avaje-htmx-nima @@ -22,7 +22,7 @@ io.avaje avaje-htmx-api - 3.4-RC1 + 3.4-RC2 io.helidon.webserver diff --git a/http-api-javalin/pom.xml b/http-api-javalin/pom.xml index a95960c30..badeea79a 100644 --- a/http-api-javalin/pom.xml +++ b/http-api-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.4-RC1 + 3.4-RC2 .. diff --git a/http-api/pom.xml b/http-api/pom.xml index 389e6b145..dbda1ef1c 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.4-RC1 + 3.4-RC2 .. diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index b878e4924..12f7a1165 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.4-RC1 + 3.4-RC2 avaje-http-client-gson @@ -21,7 +21,7 @@ io.avaje avaje-http-client - 3.4-RC1 + 3.4-RC2 provided diff --git a/http-client-moshi-adapter/pom.xml b/http-client-moshi-adapter/pom.xml index 1d4bb95bc..757c97422 100644 --- a/http-client-moshi-adapter/pom.xml +++ b/http-client-moshi-adapter/pom.xml @@ -3,7 +3,7 @@ io.avaje avaje-http-parent - 3.4-RC1 + 3.4-RC2 avaje-http-client-moshi avaje-http-client-moshi @@ -20,7 +20,7 @@ io.avaje avaje-http-client - 3.4-RC1 + 3.4-RC2 provided diff --git a/http-client/pom.xml b/http-client/pom.xml index 4519ac50a..6a8b94a68 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.4-RC1 + 3.4-RC2 avaje-http-client diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index 6fb68e01f..582aede2c 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.4-RC1 + 3.4-RC2 avaje-http-client-generator diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index ee33f67fe..c960ebd64 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.4-RC1 + 3.4-RC2 avaje-http-generator-core diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index 806749237..a01c5579f 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 3.4-RC1 + 3.4-RC2 avaje-http-helidon-generator diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index 2f56448f0..6443fefce 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.4-RC1 + 3.4-RC2 avaje-http-javalin-generator diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index b2f8ad603..45c9ed050 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.4-RC1 + 3.4-RC2 avaje-http-jex-generator diff --git a/http-generator-sigma/pom.xml b/http-generator-sigma/pom.xml index f620399db..896ee5ced 100644 --- a/http-generator-sigma/pom.xml +++ b/http-generator-sigma/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.4-RC1 + 3.4-RC2 avaje-http-sigma-generator diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index 8b2262485..cf35a23a3 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.4-RC1 + 3.4-RC2 .. diff --git a/pom.xml b/pom.xml index 7594a8e68..34fd9867b 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ io.avaje avaje-http-parent avaje-http-parent - 3.4-RC1 + 3.4-RC2 pom @@ -24,7 +24,7 @@ 2.14.2 3.0-RC10 1.42 - 2025-06-03T19:27:32Z + 2025-07-13T21:41:04Z ${project.build.directory}${file.separator}module-info.shade diff --git a/tests/pom.xml b/tests/pom.xml index b20177b71..fc437c3bc 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 3.4-RC1 + 3.4-RC2 tests diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index 0de754290..b058fdca1 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 3.4-RC1 + 3.4-RC2 test-client-generation diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index 5c9e47097..fa259aaf6 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 3.4-RC1 + 3.4-RC2 test-client diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index ff8cd333b..7d1fff9be 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 3.4-RC1 + 3.4-RC2 test-javalin-jsonb diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 5fdfd8b7d..64ebd76ed 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 3.4-RC1 + 3.4-RC2 test-javalin diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 6c77a33ef..e2f2889ea 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 3.4-RC1 + 3.4-RC2 test-jex diff --git a/tests/test-nima-htmx/pom.xml b/tests/test-nima-htmx/pom.xml index fab0b541b..939055105 100644 --- a/tests/test-nima-htmx/pom.xml +++ b/tests/test-nima-htmx/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 3.4-RC1 + 3.4-RC2 test-nima-htmx diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 2242d88be..f45190844 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 3.4-RC1 + 3.4-RC2 test-nima-jsonb diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index a205d530d..927449611 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 3.4-RC1 + 3.4-RC2 test-nima diff --git a/tests/test-sigma/pom.xml b/tests/test-sigma/pom.xml index 51747c0be..af09b21d2 100644 --- a/tests/test-sigma/pom.xml +++ b/tests/test-sigma/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 3.4-RC1 + 3.4-RC2 test-sigma From 61be57eb9747f73a9a47542925f1b7261722e55e Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 15 Jul 2025 22:34:10 +1200 Subject: [PATCH 1316/1323] Add JsonB stream support (#621) * Add JsonB stream support This is initially using JSON Array content rather than application/x-json-stream * JsonB stream support - use streamAsLines() and application/stream+json * [Jex] JsonB stream support for Jex using application/stream+json * Extract defaultMediaType() helper method * Bump to jsonb 3.6-RC2 --- aws-cognito/http-client-authtoken/pom.xml | 4 +- http-client/pom.xml | 4 +- .../avaje/http/generator/core/JsonBUtil.java | 6 +- .../generator/core/openapi/MediaType.java | 1 + .../helidon/nima/ControllerMethodWriter.java | 27 ++++++--- .../generator/jex/ControllerMethodWriter.java | 36 +++++++----- .../avaje/http/generator/jex/JexAdapter.java | 7 ++- tests/test-javalin-jsonb/pom.xml | 4 +- tests/test-jex/pom.xml | 4 +- .../java/org/example/web/HelloController.java | 6 ++ .../main/java/org/example/web/HelloDto.java | 8 +++ .../org/example/web/myapp/BarController.java | 6 ++ .../org/example/web/myapp/BarInterface.java | 4 ++ .../src/main/resources/public/openapi.json | 58 +++++++++++++++++++ .../org/example/web/HelloControllerTest.java | 13 +++++ tests/test-nima-htmx/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 4 +- .../java/org/example/HelloController.java | 10 ++++ .../java/org/example/HelloControllerTest.java | 56 ++++++++++++++++++ tests/test-sigma/pom.xml | 11 ++-- 20 files changed, 231 insertions(+), 40 deletions(-) create mode 100644 tests/test-nima-jsonb/src/test/java/org/example/HelloControllerTest.java diff --git a/aws-cognito/http-client-authtoken/pom.xml b/aws-cognito/http-client-authtoken/pom.xml index 1d31458bc..a8160b4f1 100644 --- a/aws-cognito/http-client-authtoken/pom.xml +++ b/aws-cognito/http-client-authtoken/pom.xml @@ -23,14 +23,14 @@ io.avaje avaje-json-core - 3.5 + 3.6-RC2 io.avaje avaje-json-node - 3.5 + 3.6-RC2 test diff --git a/http-client/pom.xml b/http-client/pom.xml index 6a8b94a68..5d4e75885 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -37,14 +37,14 @@ io.avaje avaje-jsonb - 3.5 + 3.6-RC2 true io.avaje avaje-json-node - 3.5 + 3.6-RC2 test diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java index cf40c9076..e6ec01773 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/JsonBUtil.java @@ -109,9 +109,13 @@ public static void writeJsonbType(UType type, Append writer) { writeType(type.paramRaw(), writer); writer.append(".map()"); break; + case "java.util.stream.Stream": + writeType(type.paramRaw(), writer); + writer.append(".streamAsLines()"); + break; default: { if (type.mainType().contains("java.util")) { - throw new UnsupportedOperationException("Only java.util Map, Set and List are supported JsonB Controller Collection Types"); + throw new UnsupportedOperationException("Only java.util Map, Set, List and Stream are supported JsonB Controller Collection Types"); } writeType(type, writer); } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/MediaType.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/MediaType.java index e4af9c899..b6fbc36db 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/MediaType.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/MediaType.java @@ -2,6 +2,7 @@ public enum MediaType { APPLICATION_JSON("application/json"), + APPLICATION_STREAM_JSON("application/stream+json"), TEXT_PLAIN("text/plain"), TEXT_HTML("text/html"), HTML_UTF8("text/html;charset=UTF8"), diff --git a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java index 94343488c..8aa616ec2 100644 --- a/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java +++ b/http-generator-helidon/src/main/java/io/avaje/http/generator/helidon/nima/ControllerMethodWriter.java @@ -258,15 +258,14 @@ void writeHandler(boolean requestScoped) { writer.append(indent).append("res.send(content);").eol(); } else { - writeContextReturn(indent); + final var uType = UType.parse(method.returnType()); + writeContextReturn(indent, streamingResponse(uType)); if (responseMode == ResponseMode.InputStream) { - final var uType = UType.parse(method.returnType()); writer.append(indent).append("result.transferTo(res.outputStream());", uType.shortName()).eol(); } else if (responseMode == ResponseMode.Json) { if (returnTypeString()) { writer.append(indent).append("res.send(result); // send raw JSON").eol(); } else { - final var uType = UType.parse(method.returnType()); writer.append(indent).append("%sJsonType.toJson(result, JsonOutput.of(res));", uType.shortName()).eol(); } } else { @@ -280,6 +279,10 @@ void writeHandler(boolean requestScoped) { writer.append(" }").eol().eol(); } + private static boolean streamingResponse(UType uType) { + return uType.mainType().equals("java.util.stream.Stream"); + } + enum ResponseMode { Void, Json, @@ -381,25 +384,35 @@ private boolean usesQueryParams() { } private void writeContextReturn(String indent) { + writeContextReturn(indent, false); + } + + private void writeContextReturn(String indent, boolean streaming) { final var producesOp = Optional.ofNullable(method.produces()); if (producesOp.isEmpty() && !useJsonB && !useJstachio) { return; } - final var produces = - producesOp - .map(MediaType::parse) - .orElse(useJstachio ? MediaType.HTML_UTF8 : MediaType.APPLICATION_JSON); + final var produces = producesOp + .map(MediaType::parse) + .orElse(defaultMediaType(streaming)); final var contentTypeString = "res.headers().contentType(MediaTypes."; writer.append(indent); switch (produces) { case HTML_UTF8 -> writer.append("res.headers().contentType(HTML_UTF8);").eol(); case APPLICATION_JSON -> writer.append(contentTypeString).append("APPLICATION_JSON);").eol(); + case APPLICATION_STREAM_JSON -> writer.append(contentTypeString).append("APPLICATION_STREAM_JSON);").eol(); case TEXT_HTML -> writer.append(contentTypeString).append("TEXT_HTML);").eol(); case TEXT_PLAIN -> writer.append(contentTypeString).append("TEXT_PLAIN);").eol(); case UNKNOWN -> writer.append(contentTypeString + "create(\"%s\"));", producesOp.orElse("UNKNOWN")).eol(); } } + private MediaType defaultMediaType(boolean streaming) { + return useJstachio + ? MediaType.HTML_UTF8 + : streaming ? MediaType.APPLICATION_STREAM_JSON : MediaType.APPLICATION_JSON; + } + private String lookupStatusCode(int statusCode) { return statusMap.getOrDefault(statusCode, String.valueOf(statusCode)); } diff --git a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java index 5a9c43cd9..1a12143a5 100644 --- a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java +++ b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/ControllerMethodWriter.java @@ -208,7 +208,7 @@ private void write(boolean requestScoped) { writer.append(");").eol(); writer.append(" var cacheContent = contentCache.content(key);").eol(); writer.append(" if (cacheContent != null) {").eol(); - writeContextReturn(responseMode, "cacheContent"); + writeContextReturn(responseMode, "cacheContent", ""); writer.append(" return;").eol(); writer.append(" }").eol(); } @@ -258,18 +258,15 @@ private void write(boolean requestScoped) { if (withContentCache) { writer.append(indent).append("contentCache.contentPut(key, content);").eol(); } - writer.append(indent); - writeContextReturn(responseMode, "content"); + writeContextReturn(responseMode, "content", indent); } case Jstachio -> { var renderer = ProcessingContext.jstacheRenderer(method.returnType()); writer.append(indent).append("var content = %s(result);", renderer).eol(); - writer.append(indent); - writeContextReturn(responseMode, "content"); + writeContextReturn(responseMode, "content", indent); } default -> { - writer.append(indent); - writeContextReturn(responseMode, "result"); + writeContextReturn(responseMode, "result", indent); } } if (includeNoContent) { @@ -278,7 +275,8 @@ private void write(boolean requestScoped) { } } - private void writeContextReturn(ResponseMode responseMode, String resultVariable) { + private void writeContextReturn(ResponseMode responseMode, String resultVariable, String indent) { + writer.append(indent); final UType type = UType.parse(method.returnType()); if ("java.util.concurrent.CompletableFuture".equals(type.mainType())) { logError(method.element(), "CompletableFuture is not a supported return type."); @@ -293,7 +291,7 @@ private void writeContextReturn(ResponseMode responseMode, String resultVariable } switch (responseMode) { case Void -> {} - case Json -> writeJsonReturn(produces); + case Json -> writeJsonReturn(produces, indent); case Text -> writer.append("ctx.text(%s);", resultVariable); case Templating -> writer.append("ctx.html(%s);", resultVariable); default -> writer.append("ctx.contentType(\"%s\").write(%s);", produces, resultVariable); @@ -301,22 +299,34 @@ private void writeContextReturn(ResponseMode responseMode, String resultVariable writer.eol(); } - private void writeJsonReturn(String produces) { + private void writeJsonReturn(String produces, String indent) { + var uType = UType.parse(method.returnType()); + boolean streaming = useJsonB && streamingContent(uType); if (produces == null) { - produces = MediaType.APPLICATION_JSON.getValue(); + produces = streaming + ? MediaType.APPLICATION_STREAM_JSON.getValue() + : MediaType.APPLICATION_JSON.getValue(); } - var uType = UType.parse(method.returnType()); if ("java.lang.String".equals(method.returnType().toString())) { writer.append("ctx.contentType(\"%s\").write(result); // raw json", produces); return; } if (useJsonB) { - writer.append("ctx.jsonb(%sJsonType, result);", uType.shortName()); + if (streaming) { + writer.append("ctx.contentType(\"%s\");", produces).eol(); + writer.append(indent).append("%sJsonType.toJson(result, io.avaje.jex.core.json.JsonbOutput.of(ctx));", uType.shortName()); + } else { + writer.append("ctx.jsonb(%sJsonType, result);", uType.shortName()); + } } else { writer.append("ctx.json(result);"); } } + private static boolean streamingContent(UType uType) { + return uType.mainType().equals("java.util.stream.Stream"); + } + private static boolean isExceptionOrFilterChain(MethodParam param) { return isAssignable2Interface(param.utype().mainType(), "java.lang.Exception") || "HttpFilter.FilterChain".equals(param.shortType()); diff --git a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/JexAdapter.java b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/JexAdapter.java index 531365e01..4627b9f4b 100644 --- a/http-generator-jex/src/main/java/io/avaje/http/generator/jex/JexAdapter.java +++ b/http-generator-jex/src/main/java/io/avaje/http/generator/jex/JexAdapter.java @@ -49,7 +49,6 @@ public String bodyAsClass(UType type) { public static String writeJsonbType(UType type) { var writer = new StringBuilder(); - switch (type.mainType()) { case "java.util.List": writeType(type.paramRaw(), writer); @@ -63,10 +62,14 @@ public static String writeJsonbType(UType type) { writeType(type.paramRaw(), writer); writer.append(".map()"); break; + case "java.util.stream.Stream": + writeType(type.paramRaw(), writer); + writer.append(".stream()"); + break; default: { if (type.mainType().contains("java.util")) { throw new UnsupportedOperationException( - "Only java.util Map, Set and List are supported JsonB Controller Collection Types"); + "Only java.util Map, Set, List and Stream are supported JsonB Controller Collection Types"); } writeType(type, writer); } diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 7d1fff9be..7993f1007 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -74,13 +74,13 @@ io.avaje avaje-jsonb - 3.5 + 3.6-RC2 io.avaje avaje-jsonb-generator - 3.5 + 3.6-RC2 provided diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index e2f2889ea..1a16252ce 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -74,7 +74,7 @@ io.avaje avaje-jsonb - 3.5 + 3.6-RC2 @@ -140,7 +140,7 @@ io.avaje avaje-jsonb-generator - 3.5 + 3.6-RC2 io.avaje diff --git a/tests/test-jex/src/main/java/org/example/web/HelloController.java b/tests/test-jex/src/main/java/org/example/web/HelloController.java index 8f56f008f..f3b892edd 100644 --- a/tests/test-jex/src/main/java/org/example/web/HelloController.java +++ b/tests/test-jex/src/main/java/org/example/web/HelloController.java @@ -1,6 +1,7 @@ package org.example.web; import java.math.BigInteger; +import java.util.stream.Stream; import io.avaje.http.api.Controller; import io.avaje.http.api.Default; @@ -16,6 +17,11 @@ @Path("/") public class HelloController { + @Get("stream") + Stream stream() { + return Stream.of(new HelloDto(1,"a"), new HelloDto(2, "b")); + } + @Get HelloDto getHello() { HelloDto dto = new HelloDto(); diff --git a/tests/test-jex/src/main/java/org/example/web/HelloDto.java b/tests/test-jex/src/main/java/org/example/web/HelloDto.java index ce271eb27..9f0841c8d 100644 --- a/tests/test-jex/src/main/java/org/example/web/HelloDto.java +++ b/tests/test-jex/src/main/java/org/example/web/HelloDto.java @@ -11,4 +11,12 @@ public class HelloDto { @NotNull public String name; public ServerType serverType; + + public HelloDto() { + } + + public HelloDto(int id, String name) { + this.id = id; + this.name = name; + } } diff --git a/tests/test-jex/src/main/java/org/example/web/myapp/BarController.java b/tests/test-jex/src/main/java/org/example/web/myapp/BarController.java index 868061d45..0ae7b6e2a 100644 --- a/tests/test-jex/src/main/java/org/example/web/myapp/BarController.java +++ b/tests/test-jex/src/main/java/org/example/web/myapp/BarController.java @@ -4,6 +4,7 @@ import java.util.ArrayList; import java.util.List; +import java.util.stream.Stream; @Controller public class BarController implements BarInterface { @@ -21,6 +22,11 @@ public List findByCode(String code) { return new ArrayList<>(); } + @Override + public Stream findByCodeStream(String code) { + return Stream.of(); + } + @Override public String barMessage() { return "Hello"; diff --git a/tests/test-jex/src/main/java/org/example/web/myapp/BarInterface.java b/tests/test-jex/src/main/java/org/example/web/myapp/BarInterface.java index 34dde1b63..d30e5231c 100644 --- a/tests/test-jex/src/main/java/org/example/web/myapp/BarInterface.java +++ b/tests/test-jex/src/main/java/org/example/web/myapp/BarInterface.java @@ -8,6 +8,7 @@ import io.swagger.v3.oas.annotations.responses.ApiResponse; import java.util.List; +import java.util.stream.Stream; @Path("/bars") public interface BarInterface { @@ -19,6 +20,9 @@ public interface BarInterface { @Get("/find/:code") List findByCode(String code); + @Get("/find/:code/stream") + Stream findByCodeStream(String code); + @Produces(MediaType.TEXT_PLAIN) @Get String barMessage(); diff --git a/tests/test-jex/src/main/resources/public/openapi.json b/tests/test-jex/src/main/resources/public/openapi.json index 61b8c2571..958aef2a5 100644 --- a/tests/test-jex/src/main/resources/public/openapi.json +++ b/tests/test-jex/src/main/resources/public/openapi.json @@ -109,6 +109,37 @@ } } }, + "/bars/find/{code}/stream" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "parameters" : [ + { + "name" : "code", + "in" : "path", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Bar>" + } + } + } + } + } + } + }, "/bars/{id}" : { "get" : { "tags" : [ @@ -1272,6 +1303,27 @@ } } }, + "/stream" : { + "get" : { + "tags" : [ + + ], + "summary" : "", + "description" : "", + "responses" : { + "200" : { + "description" : "", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/HelloDto>" + } + } + } + } + } + } + }, "/test/enumQuery" : { "get" : { "tags" : [ @@ -1495,6 +1547,9 @@ } } }, + "Bar>" : { + "type" : "object" + }, "Baz" : { "type" : "object", "properties" : { @@ -1536,6 +1591,9 @@ } } }, + "HelloDto>" : { + "type" : "object" + }, "HelloForm" : { "required" : [ "name" diff --git a/tests/test-jex/src/test/java/org/example/web/HelloControllerTest.java b/tests/test-jex/src/test/java/org/example/web/HelloControllerTest.java index bf332af61..129b7e6e5 100644 --- a/tests/test-jex/src/test/java/org/example/web/HelloControllerTest.java +++ b/tests/test-jex/src/test/java/org/example/web/HelloControllerTest.java @@ -26,6 +26,19 @@ void getHello() { assertEquals("rob", hello.name); } + @Test + void stream() { + final HttpResponse res = client.request() + .path("stream") + .GET() + .asString(); + + assertThat(res.statusCode()).isEqualTo(200); + assertThat(res.headers().firstValue("Content-Type").orElse("Junk")) + .isEqualTo("application/stream+json"); + assertThat(res.body()).isEqualTo("{\"id\":1,\"name\":\"a\"}\n{\"id\":2,\"name\":\"b\"}\n"); + } + @Test void getHelloClient() { final HelloDto hello = client.create(HelloControllerTestAPI.class).getHello().body(); diff --git a/tests/test-nima-htmx/pom.xml b/tests/test-nima-htmx/pom.xml index 939055105..2e19717db 100644 --- a/tests/test-nima-htmx/pom.xml +++ b/tests/test-nima-htmx/pom.xml @@ -88,7 +88,7 @@ io.avaje avaje-jsonb-generator - 3.5 + 3.6-RC2 io.jstach diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index f45190844..87d1c8a7a 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -44,7 +44,7 @@ io.avaje avaje-jsonb - 3.5 + 3.6-RC2 io.helidon.webserver @@ -104,7 +104,7 @@ io.avaje avaje-jsonb-generator - 3.5 + 3.6-RC2 io.avaje diff --git a/tests/test-nima-jsonb/src/main/java/org/example/HelloController.java b/tests/test-nima-jsonb/src/main/java/org/example/HelloController.java index 515ae0852..5820f6def 100644 --- a/tests/test-nima-jsonb/src/main/java/org/example/HelloController.java +++ b/tests/test-nima-jsonb/src/main/java/org/example/HelloController.java @@ -4,6 +4,7 @@ import java.util.List; import java.util.Map; import java.util.Set; +import java.util.stream.Stream; import io.avaje.http.api.Controller; import io.avaje.http.api.Form; @@ -100,6 +101,15 @@ List personList(String sortBy) { return List.of(new Person(42, "fooList"), new Person(43, "barList")); } + @Get("person/{ignored}/stream") + Stream personStream(String ignored) { + return Stream.of( + new Person(42, ignored), + new Person(43, "bar"), + new Person(44, "baz"), + new Person(44, "bax")); + } + // curl -v localhost:8081/person/foo/set @Get("person/{sortBy}/set") Set personSet(String sortBy) { diff --git a/tests/test-nima-jsonb/src/test/java/org/example/HelloControllerTest.java b/tests/test-nima-jsonb/src/test/java/org/example/HelloControllerTest.java new file mode 100644 index 000000000..17db80acb --- /dev/null +++ b/tests/test-nima-jsonb/src/test/java/org/example/HelloControllerTest.java @@ -0,0 +1,56 @@ +package org.example; + +import io.avaje.http.client.HttpClient; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.Test; + +import java.net.http.HttpResponse; +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +public class HelloControllerTest { + + private static TestPair pair = new TestPair(); + private static HttpClient client = pair.client(); + + @AfterAll + static void end() { + pair.stop(); + } + + @Test + void hello() { + HttpResponse res = client.request() + .path("hello") + .GET() + .asString(); + + assertThat(res.statusCode()).isEqualTo(200); + assertThat(res.body()).isEqualTo("Hello world"); + } + + @Test + void personList() { + HttpResponse> res = client.request() + .path("person/name/list") + .GET() + .asList(Person.class); + + assertThat(res.statusCode()).isEqualTo(200); + assertThat(res.body()).hasSize(2); + } + + @Test + void personStream() { + HttpResponse res = client.request() + .path("person/ignoreMe/stream") + .GET() + .asString(); // .asStream(Person.class); + + assertThat(res.statusCode()).isEqualTo(200); + String contentType = res.headers().firstValue("Content-Type").orElse("Junk"); + assertThat(res.body()).isEqualTo("{\"id\":42,\"name\":\"ignoreMe\"}\n{\"id\":43,\"name\":\"bar\"}\n{\"id\":44,\"name\":\"baz\"}\n{\"id\":44,\"name\":\"bax\"}\n"); + assertThat(contentType).isEqualTo("application/stream+json"); + } +} diff --git a/tests/test-sigma/pom.xml b/tests/test-sigma/pom.xml index af09b21d2..d7a51822f 100644 --- a/tests/test-sigma/pom.xml +++ b/tests/test-sigma/pom.xml @@ -48,8 +48,7 @@ swagger-annotations ${swagger.version} - - + io.jstach jstachio @@ -58,13 +57,13 @@ - + io.jstach jstachio-apt 1.3.7 - + io.avaje avaje-inject-generator @@ -82,12 +81,12 @@ io.avaje avaje-jsonb - 3.5 + 3.6-RC2 io.avaje avaje-jsonb-generator - 3.5 + 3.6-RC2 provided From 825d35a4af8ba4c8fff2d753e0d558ef54fe4e81 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 15 Jul 2025 22:35:44 +1200 Subject: [PATCH 1317/1323] Version 3.4-RC3 --- aws-cognito/http-client-authtoken/pom.xml | 2 +- htmx-api/pom.xml | 2 +- htmx-nima-jstache/pom.xml | 2 +- htmx-nima/pom.xml | 4 ++-- http-api-javalin/pom.xml | 2 +- http-api/pom.xml | 2 +- http-client-gson-adapter/pom.xml | 4 ++-- http-client-moshi-adapter/pom.xml | 4 ++-- http-client/pom.xml | 2 +- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 2 +- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-generator-sigma/pom.xml | 2 +- http-inject-plugin/pom.xml | 2 +- pom.xml | 4 ++-- tests/pom.xml | 2 +- tests/test-client-generation/pom.xml | 2 +- tests/test-client/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-htmx/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- tests/test-sigma/pom.xml | 2 +- 27 files changed, 31 insertions(+), 31 deletions(-) diff --git a/aws-cognito/http-client-authtoken/pom.xml b/aws-cognito/http-client-authtoken/pom.xml index a8160b4f1..ef3beafc4 100644 --- a/aws-cognito/http-client-authtoken/pom.xml +++ b/aws-cognito/http-client-authtoken/pom.xml @@ -17,7 +17,7 @@ io.avaje avaje-http-client - 3.4-RC2 + 3.4-RC3 diff --git a/htmx-api/pom.xml b/htmx-api/pom.xml index e4b1c46b0..2e47bd01c 100644 --- a/htmx-api/pom.xml +++ b/htmx-api/pom.xml @@ -6,7 +6,7 @@ io.avaje avaje-http-parent - 3.4-RC2 + 3.4-RC3 avaje-htmx-api diff --git a/htmx-nima-jstache/pom.xml b/htmx-nima-jstache/pom.xml index b6dcba6a5..2e09ecd01 100644 --- a/htmx-nima-jstache/pom.xml +++ b/htmx-nima-jstache/pom.xml @@ -6,7 +6,7 @@ io.avaje avaje-http-parent - 3.4-RC2 + 3.4-RC3 avaje-htmx-nima-jstache diff --git a/htmx-nima/pom.xml b/htmx-nima/pom.xml index 23efa4913..5edea7fcd 100644 --- a/htmx-nima/pom.xml +++ b/htmx-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje avaje-http-parent - 3.4-RC2 + 3.4-RC3 avaje-htmx-nima @@ -22,7 +22,7 @@ io.avaje avaje-htmx-api - 3.4-RC2 + 3.4-RC3 io.helidon.webserver diff --git a/http-api-javalin/pom.xml b/http-api-javalin/pom.xml index badeea79a..0b230cf23 100644 --- a/http-api-javalin/pom.xml +++ b/http-api-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.4-RC2 + 3.4-RC3 .. diff --git a/http-api/pom.xml b/http-api/pom.xml index dbda1ef1c..e616ea2ae 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.4-RC2 + 3.4-RC3 .. diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index 12f7a1165..d3207768e 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.4-RC2 + 3.4-RC3 avaje-http-client-gson @@ -21,7 +21,7 @@ io.avaje avaje-http-client - 3.4-RC2 + 3.4-RC3 provided diff --git a/http-client-moshi-adapter/pom.xml b/http-client-moshi-adapter/pom.xml index 757c97422..d5b75c40d 100644 --- a/http-client-moshi-adapter/pom.xml +++ b/http-client-moshi-adapter/pom.xml @@ -3,7 +3,7 @@ io.avaje avaje-http-parent - 3.4-RC2 + 3.4-RC3 avaje-http-client-moshi avaje-http-client-moshi @@ -20,7 +20,7 @@ io.avaje avaje-http-client - 3.4-RC2 + 3.4-RC3 provided diff --git a/http-client/pom.xml b/http-client/pom.xml index 5d4e75885..a55b437ab 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.4-RC2 + 3.4-RC3 avaje-http-client diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index 582aede2c..346b6639e 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.4-RC2 + 3.4-RC3 avaje-http-client-generator diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index c960ebd64..8077ccc09 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.4-RC2 + 3.4-RC3 avaje-http-generator-core diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index a01c5579f..7a5b92e4e 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 3.4-RC2 + 3.4-RC3 avaje-http-helidon-generator diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index 6443fefce..f1aefb125 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.4-RC2 + 3.4-RC3 avaje-http-javalin-generator diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index 45c9ed050..35aa7b169 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.4-RC2 + 3.4-RC3 avaje-http-jex-generator diff --git a/http-generator-sigma/pom.xml b/http-generator-sigma/pom.xml index 896ee5ced..05142dd67 100644 --- a/http-generator-sigma/pom.xml +++ b/http-generator-sigma/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.4-RC2 + 3.4-RC3 avaje-http-sigma-generator diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index cf35a23a3..7dd70dc02 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.4-RC2 + 3.4-RC3 .. diff --git a/pom.xml b/pom.xml index 34fd9867b..0b7677466 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ io.avaje avaje-http-parent avaje-http-parent - 3.4-RC2 + 3.4-RC3 pom @@ -24,7 +24,7 @@ 2.14.2 3.0-RC10 1.42 - 2025-07-13T21:41:04Z + 2025-07-15T10:34:36Z ${project.build.directory}${file.separator}module-info.shade diff --git a/tests/pom.xml b/tests/pom.xml index fc437c3bc..204ab1c71 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 3.4-RC2 + 3.4-RC3 tests diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index b058fdca1..9c83e2588 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 3.4-RC2 + 3.4-RC3 test-client-generation diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index fa259aaf6..a045058a1 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 3.4-RC2 + 3.4-RC3 test-client diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 7993f1007..43f284a40 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 3.4-RC2 + 3.4-RC3 test-javalin-jsonb diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 64ebd76ed..35410b245 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 3.4-RC2 + 3.4-RC3 test-javalin diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 1a16252ce..7c91365b7 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 3.4-RC2 + 3.4-RC3 test-jex diff --git a/tests/test-nima-htmx/pom.xml b/tests/test-nima-htmx/pom.xml index 2e19717db..ce326781d 100644 --- a/tests/test-nima-htmx/pom.xml +++ b/tests/test-nima-htmx/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 3.4-RC2 + 3.4-RC3 test-nima-htmx diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 87d1c8a7a..3d790abe5 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 3.4-RC2 + 3.4-RC3 test-nima-jsonb diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index 927449611..2e2cf4736 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 3.4-RC2 + 3.4-RC3 test-nima diff --git a/tests/test-sigma/pom.xml b/tests/test-sigma/pom.xml index d7a51822f..3c6b046ea 100644 --- a/tests/test-sigma/pom.xml +++ b/tests/test-sigma/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 3.4-RC2 + 3.4-RC3 test-sigma From 64eeef18fa311a7e13fb85b5e976749e34d4dede Mon Sep 17 00:00:00 2001 From: "robin.bygrave" Date: Wed, 16 Jul 2025 12:16:56 +1200 Subject: [PATCH 1318/1323] [client] Fix HttpClient support for reading empty stream The HttpClient uses the BodyHandlers.ofLines() but was not filtering out empty lines. These empty lines can fail the assigned body handler (e.g. json parsing error). The fix is to filter out empty lines when reading the stream. --- .../io/avaje/http/client/DHttpClientRequest.java | 2 +- .../io/avaje/http/client/HelloControllerTest.java | 12 ++++++++++++ .../org/example/webserver/HelloController$Route.java | 5 +++++ .../java/org/example/webserver/HelloController.java | 7 +++++++ 4 files changed, 25 insertions(+), 1 deletion(-) diff --git a/http-client/src/main/java/io/avaje/http/client/DHttpClientRequest.java b/http-client/src/main/java/io/avaje/http/client/DHttpClientRequest.java index fc740b2d8..398ed19dd 100644 --- a/http-client/src/main/java/io/avaje/http/client/DHttpClientRequest.java +++ b/http-client/src/main/java/io/avaje/http/client/DHttpClientRequest.java @@ -585,7 +585,7 @@ private Stream stream(BodyReader bodyReader) { final HttpResponse> res = handler(HttpResponse.BodyHandlers.ofLines()); this.httpResponse = res; checkResponse(res); - return res.body().map(bodyReader::readBody); + return res.body().filter(line -> !line.isEmpty()).map(bodyReader::readBody); } @Override diff --git a/http-client/src/test/java/io/avaje/http/client/HelloControllerTest.java b/http-client/src/test/java/io/avaje/http/client/HelloControllerTest.java index b6ae766d9..111aceb85 100644 --- a/http-client/src/test/java/io/avaje/http/client/HelloControllerTest.java +++ b/http-client/src/test/java/io/avaje/http/client/HelloControllerTest.java @@ -271,6 +271,18 @@ void get_stream_as() { assertThat(first.name).isEqualTo("one"); } + @Test + void get_stream_as_when_empty() { + final HttpResponse> res = clientContext.request() + .path("hello").path("streamEmpty") + .GET() + .asStream(SimpleData.class); + + assertThat(res.statusCode()).isEqualTo(200); + final List data = res.body().collect(Collectors.toList()); + assertThat(data).isEmpty(); + } + @Test void get_stream_NotFoundException() { clientContext.metrics(true); diff --git a/http-client/src/test/java/org/example/webserver/HelloController$Route.java b/http-client/src/test/java/org/example/webserver/HelloController$Route.java index bca12e34b..caa61d42c 100644 --- a/http-client/src/test/java/org/example/webserver/HelloController$Route.java +++ b/http-client/src/test/java/org/example/webserver/HelloController$Route.java @@ -52,6 +52,11 @@ private void routes(JavalinDefaultRouting cfg) { controller.stream(ctx); }); + cfg.get("/hello/streamEmpty", ctx -> { + ctx.status(200); + controller.streamEmpty(ctx); + }); + cfg.get("/hello/{id}/{date}", ctx -> { ctx.status(200); final int id = asInt(ctx.pathParam("id")); diff --git a/http-client/src/test/java/org/example/webserver/HelloController.java b/http-client/src/test/java/org/example/webserver/HelloController.java index f72598ae2..09f599676 100644 --- a/http-client/src/test/java/org/example/webserver/HelloController.java +++ b/http-client/src/test/java/org/example/webserver/HelloController.java @@ -63,6 +63,13 @@ void stream(Context context) { context.result(content); } + @Get("streamEmpty") + void streamEmpty(Context context) { + // simulate x-json-stream response with empty stream + context.header("content-type", "application/x-json-stream"); + context.result("\n"); + } + /** * Return the Hello DTO. * From 0a2c5b46d9b477175cc4e8dc5c07afef14e7949b Mon Sep 17 00:00:00 2001 From: "robin.bygrave" Date: Wed, 16 Jul 2025 13:22:46 +1200 Subject: [PATCH 1319/1323] Version 3.4-RC4 --- aws-cognito/http-client-authtoken/pom.xml | 2 +- htmx-api/pom.xml | 2 +- htmx-nima-jstache/pom.xml | 2 +- htmx-nima/pom.xml | 4 ++-- http-api-javalin/pom.xml | 2 +- http-api/pom.xml | 2 +- http-client-gson-adapter/pom.xml | 4 ++-- http-client-moshi-adapter/pom.xml | 4 ++-- http-client/pom.xml | 2 +- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 2 +- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-generator-sigma/pom.xml | 2 +- http-inject-plugin/pom.xml | 2 +- pom.xml | 4 ++-- tests/pom.xml | 2 +- tests/test-client-generation/pom.xml | 2 +- tests/test-client/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-htmx/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- tests/test-sigma/pom.xml | 2 +- 27 files changed, 31 insertions(+), 31 deletions(-) diff --git a/aws-cognito/http-client-authtoken/pom.xml b/aws-cognito/http-client-authtoken/pom.xml index ef3beafc4..941e5e8c8 100644 --- a/aws-cognito/http-client-authtoken/pom.xml +++ b/aws-cognito/http-client-authtoken/pom.xml @@ -17,7 +17,7 @@ io.avaje avaje-http-client - 3.4-RC3 + 3.4-RC4 diff --git a/htmx-api/pom.xml b/htmx-api/pom.xml index 2e47bd01c..8b56ea3d1 100644 --- a/htmx-api/pom.xml +++ b/htmx-api/pom.xml @@ -6,7 +6,7 @@ io.avaje avaje-http-parent - 3.4-RC3 + 3.4-RC4 avaje-htmx-api diff --git a/htmx-nima-jstache/pom.xml b/htmx-nima-jstache/pom.xml index 2e09ecd01..edebd22e9 100644 --- a/htmx-nima-jstache/pom.xml +++ b/htmx-nima-jstache/pom.xml @@ -6,7 +6,7 @@ io.avaje avaje-http-parent - 3.4-RC3 + 3.4-RC4 avaje-htmx-nima-jstache diff --git a/htmx-nima/pom.xml b/htmx-nima/pom.xml index 5edea7fcd..85f0b5705 100644 --- a/htmx-nima/pom.xml +++ b/htmx-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje avaje-http-parent - 3.4-RC3 + 3.4-RC4 avaje-htmx-nima @@ -22,7 +22,7 @@ io.avaje avaje-htmx-api - 3.4-RC3 + 3.4-RC4 io.helidon.webserver diff --git a/http-api-javalin/pom.xml b/http-api-javalin/pom.xml index 0b230cf23..f5faaedda 100644 --- a/http-api-javalin/pom.xml +++ b/http-api-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.4-RC3 + 3.4-RC4 .. diff --git a/http-api/pom.xml b/http-api/pom.xml index e616ea2ae..2c87f15db 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.4-RC3 + 3.4-RC4 .. diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index d3207768e..47259219f 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.4-RC3 + 3.4-RC4 avaje-http-client-gson @@ -21,7 +21,7 @@ io.avaje avaje-http-client - 3.4-RC3 + 3.4-RC4 provided diff --git a/http-client-moshi-adapter/pom.xml b/http-client-moshi-adapter/pom.xml index d5b75c40d..1b90528a1 100644 --- a/http-client-moshi-adapter/pom.xml +++ b/http-client-moshi-adapter/pom.xml @@ -3,7 +3,7 @@ io.avaje avaje-http-parent - 3.4-RC3 + 3.4-RC4 avaje-http-client-moshi avaje-http-client-moshi @@ -20,7 +20,7 @@ io.avaje avaje-http-client - 3.4-RC3 + 3.4-RC4 provided diff --git a/http-client/pom.xml b/http-client/pom.xml index a55b437ab..19bd286c7 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.4-RC3 + 3.4-RC4 avaje-http-client diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index 346b6639e..3ad6ce3ec 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.4-RC3 + 3.4-RC4 avaje-http-client-generator diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 8077ccc09..589ccf251 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.4-RC3 + 3.4-RC4 avaje-http-generator-core diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index 7a5b92e4e..1863dd598 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 3.4-RC3 + 3.4-RC4 avaje-http-helidon-generator diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index f1aefb125..22a94cba9 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.4-RC3 + 3.4-RC4 avaje-http-javalin-generator diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index 35aa7b169..3486dd0de 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.4-RC3 + 3.4-RC4 avaje-http-jex-generator diff --git a/http-generator-sigma/pom.xml b/http-generator-sigma/pom.xml index 05142dd67..446f66bd2 100644 --- a/http-generator-sigma/pom.xml +++ b/http-generator-sigma/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.4-RC3 + 3.4-RC4 avaje-http-sigma-generator diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index 7dd70dc02..fe9155605 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.4-RC3 + 3.4-RC4 .. diff --git a/pom.xml b/pom.xml index 0b7677466..432324cc0 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ io.avaje avaje-http-parent avaje-http-parent - 3.4-RC3 + 3.4-RC4 pom @@ -24,7 +24,7 @@ 2.14.2 3.0-RC10 1.42 - 2025-07-15T10:34:36Z + 2025-07-16T01:21:06Z ${project.build.directory}${file.separator}module-info.shade diff --git a/tests/pom.xml b/tests/pom.xml index 204ab1c71..3a27304b3 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 3.4-RC3 + 3.4-RC4 tests diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index 9c83e2588..346614b1b 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 3.4-RC3 + 3.4-RC4 test-client-generation diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index a045058a1..b5dda632c 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 3.4-RC3 + 3.4-RC4 test-client diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 43f284a40..129846d39 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 3.4-RC3 + 3.4-RC4 test-javalin-jsonb diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 35410b245..378cf8d02 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 3.4-RC3 + 3.4-RC4 test-javalin diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 7c91365b7..763ccf594 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 3.4-RC3 + 3.4-RC4 test-jex diff --git a/tests/test-nima-htmx/pom.xml b/tests/test-nima-htmx/pom.xml index ce326781d..6568a635c 100644 --- a/tests/test-nima-htmx/pom.xml +++ b/tests/test-nima-htmx/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 3.4-RC3 + 3.4-RC4 test-nima-htmx diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 3d790abe5..8cc5a46de 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 3.4-RC3 + 3.4-RC4 test-nima-jsonb diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index 2e2cf4736..caade2193 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 3.4-RC3 + 3.4-RC4 test-nima diff --git a/tests/test-sigma/pom.xml b/tests/test-sigma/pom.xml index 3c6b046ea..15ebd22e2 100644 --- a/tests/test-sigma/pom.xml +++ b/tests/test-sigma/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 3.4-RC3 + 3.4-RC4 test-sigma From 635da70cc02da956399eca6f5c3bfc0ff9a33477 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Thu, 17 Jul 2025 19:42:11 -0400 Subject: [PATCH 1320/1323] [client] Support Static URLs (#623) * [client] allow blank baseUrl * Update ApiClient.java * support static http endpoint --- .../avaje/http/client/DHttpClientBuilder.java | 21 ++++++++----------- .../example/dinject/ConfigureWithDITest.java | 2 +- .../generator/client/ClientMethodWriter.java | 13 ++++++++++-- .../generator/client/clients/ApiClient.java | 3 +++ .../io/avaje/http/generator/core/Util.java | 4 ++++ 5 files changed, 28 insertions(+), 15 deletions(-) diff --git a/http-client/src/main/java/io/avaje/http/client/DHttpClientBuilder.java b/http-client/src/main/java/io/avaje/http/client/DHttpClientBuilder.java index eb8e815aa..f7e8a9ced 100644 --- a/http-client/src/main/java/io/avaje/http/client/DHttpClientBuilder.java +++ b/http-client/src/main/java/io/avaje/http/client/DHttpClientBuilder.java @@ -1,11 +1,7 @@ package io.avaje.http.client; -import com.fasterxml.jackson.databind.ObjectMapper; -import io.avaje.inject.BeanScope; -import io.avaje.jsonb.Jsonb; - -import javax.net.ssl.SSLContext; -import javax.net.ssl.SSLParameters; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; import java.net.Authenticator; import java.net.CookieHandler; import java.net.CookieManager; @@ -21,15 +17,18 @@ import java.util.concurrent.Executors; import java.util.function.Function; -import static java.util.Objects.requireNonNull; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLParameters; -import java.lang.invoke.MethodHandles; -import java.lang.invoke.MethodType; +import com.fasterxml.jackson.databind.ObjectMapper; + +import io.avaje.inject.BeanScope; +import io.avaje.jsonb.Jsonb; final class DHttpClientBuilder implements HttpClient.Builder, HttpClient.Builder.State { private java.net.http.HttpClient client; - private String baseUrl; + private String baseUrl = ""; private boolean requestLogging = true; private Duration connectionTimeout = Duration.ofSeconds(20); private Duration requestTimeout = Duration.ofSeconds(20); @@ -168,8 +167,6 @@ private boolean detectTypeExists(String className) { } private DHttpClientContext buildClient() { - requireNonNull(baseUrl, "baseUrl is not specified"); - requireNonNull(requestTimeout, "requestTimeout is not specified"); final var httpClient = client != null ? client : defaultClient(); if (requestLogging) { // register the built-in request/response logging diff --git a/http-client/src/test/java/org/example/dinject/ConfigureWithDITest.java b/http-client/src/test/java/org/example/dinject/ConfigureWithDITest.java index a92d016ea..dc0028ef5 100644 --- a/http-client/src/test/java/org/example/dinject/ConfigureWithDITest.java +++ b/http-client/src/test/java/org/example/dinject/ConfigureWithDITest.java @@ -20,7 +20,7 @@ void configureWith() { HttpClient.Builder builder = HttpClient.builder(); HttpClient.Builder.State state = builder.state(); - assertThat(state.baseUrl()).isNull(); + assertThat(state.baseUrl()).isEmpty(); assertThat(state.bodyAdapter()).isNull(); assertThat(state.client()).isNull(); assertThat(state.requestLogging()).isTrue(); diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java index b1be334ed..d17025183 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java @@ -427,7 +427,7 @@ private void writePaths(Set segments) { } else { // If we have accumulated literals, write them out first if (combinedLiterals.length() > 0) { - writer.append(".path(\"").append(combinedLiterals.toString()).append("\")"); + writeLiteral(combinedLiterals); combinedLiterals.setLength(0); // Clear the buffer } // Write the non-literal segment @@ -441,7 +441,7 @@ private void writePaths(Set segments) { // Write any remaining accumulated literals if (combinedLiterals.length() > 0) { - writer.append(".path(\"").append(combinedLiterals.toString()).append("\")"); + writeLiteral(combinedLiterals); } if (!segments.isEmpty()) { @@ -449,6 +449,15 @@ private void writePaths(Set segments) { } } + private void writeLiteral(StringBuilder combinedLiterals) { + String path = + combinedLiterals.toString().replace("http:/", "http://").replace("https:/", "https://"); + writer + .append(path.startsWith("http:") || path.startsWith("https:") ? ".url(\"" : ".path(\"") + .append(path) + .append("\")"); + } + private boolean isMap(MethodParam param) { return isMap(param.utype().mainType()); } diff --git a/http-generator-client/src/test/java/io/avaje/http/generator/client/clients/ApiClient.java b/http-generator-client/src/test/java/io/avaje/http/generator/client/clients/ApiClient.java index 7c3d57baa..4347de659 100644 --- a/http-generator-client/src/test/java/io/avaje/http/generator/client/clients/ApiClient.java +++ b/http-generator-client/src/test/java/io/avaje/http/generator/client/clients/ApiClient.java @@ -15,4 +15,7 @@ public interface ApiClient { @Get("/consecutive/paths/{accept}/generate") String consecutive(String accept); + + @Get("http://localhost:6969/test") + String staticUrl(); } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/Util.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/Util.java index 8a1569139..3a6a79b63 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/Util.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/Util.java @@ -98,6 +98,10 @@ static String combinePath(String beanPath, String webMethodPath) { if (!webMethodPath.isEmpty() && !webMethodPath.startsWith("/")) { sb.append("/"); } + + if (webMethodPath.startsWith("https:") || webMethodPath.startsWith("http:")) { + return webMethodPath; + } sb.append(trimTrailingSlash(webMethodPath)); } return sb.toString(); From 6416e8a3f6cb4cfb62c91994bc847bc8f0eea2f9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 21 Jul 2025 23:48:03 +0000 Subject: [PATCH 1321/1323] Bump the dependencies group with 10 updates (#624) * Bump the dependencies group with 10 updates Bumps the dependencies group with 10 updates: | Package | From | To | | --- | --- | --- | | [com.fasterxml.jackson.core:jackson-databind](https://github.com/FasterXML/jackson) | `2.19.1` | `2.19.2` | | [io.avaje:avaje-jsonb](https://github.com/avaje/avaje-jsonb) | `3.6-RC2` | `3.6` | | io.avaje:avaje-json-node | `3.6-RC2` | `3.6` | | io.avaje:avaje-jsonb-generator | `3.6-RC2` | `3.6` | | io.helidon.webserver:helidon-webserver | `4.2.3` | `4.2.4` | | io.helidon.webserver:helidon-webserver-security | `4.2.3` | `4.2.4` | | io.helidon.http.media:helidon-http-media-jsonb | `4.2.3` | `4.2.4` | | [org.junit.jupiter:junit-jupiter-api](https://github.com/junit-team/junit-framework) | `5.13.3` | `5.13.4` | | [org.junit.jupiter:junit-jupiter-engine](https://github.com/junit-team/junit-framework) | `5.13.3` | `5.13.4` | | io.avaje:avaje-json-core | `3.6-RC2` | `3.6` | Updates `com.fasterxml.jackson.core:jackson-databind` from 2.19.1 to 2.19.2 - [Commits](https://github.com/FasterXML/jackson/commits) Updates `io.avaje:avaje-jsonb` from 3.6-RC2 to 3.6 - [Release notes](https://github.com/avaje/avaje-jsonb/releases) - [Commits](https://github.com/avaje/avaje-jsonb/commits/3.6) Updates `io.avaje:avaje-json-node` from 3.6-RC2 to 3.6 Updates `io.avaje:avaje-jsonb-generator` from 3.6-RC2 to 3.6 Updates `io.helidon.webserver:helidon-webserver` from 4.2.3 to 4.2.4 Updates `io.helidon.webserver:helidon-webserver-security` from 4.2.3 to 4.2.4 Updates `io.helidon.http.media:helidon-http-media-jsonb` from 4.2.3 to 4.2.4 Updates `io.helidon.webserver:helidon-webserver-security` from 4.2.3 to 4.2.4 Updates `io.helidon.http.media:helidon-http-media-jsonb` from 4.2.3 to 4.2.4 Updates `org.junit.jupiter:junit-jupiter-api` from 5.13.3 to 5.13.4 - [Release notes](https://github.com/junit-team/junit-framework/releases) - [Commits](https://github.com/junit-team/junit-framework/compare/r5.13.3...r5.13.4) Updates `org.junit.jupiter:junit-jupiter-engine` from 5.13.3 to 5.13.4 - [Release notes](https://github.com/junit-team/junit-framework/releases) - [Commits](https://github.com/junit-team/junit-framework/compare/r5.13.3...r5.13.4) Updates `org.junit.jupiter:junit-jupiter-engine` from 5.13.3 to 5.13.4 - [Release notes](https://github.com/junit-team/junit-framework/releases) - [Commits](https://github.com/junit-team/junit-framework/compare/r5.13.3...r5.13.4) Updates `io.avaje:avaje-json-core` from 3.6-RC2 to 3.6 --- updated-dependencies: - dependency-name: com.fasterxml.jackson.core:jackson-databind dependency-version: 2.19.2 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: io.avaje:avaje-jsonb dependency-version: '3.6' dependency-type: direct:production dependency-group: dependencies - dependency-name: io.avaje:avaje-json-node dependency-version: '3.6' dependency-type: direct:production dependency-group: dependencies - dependency-name: io.avaje:avaje-jsonb-generator dependency-version: '3.6' dependency-type: direct:production dependency-group: dependencies - dependency-name: io.helidon.webserver:helidon-webserver dependency-version: 4.2.4 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: io.helidon.webserver:helidon-webserver-security dependency-version: 4.2.4 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: io.helidon.http.media:helidon-http-media-jsonb dependency-version: 4.2.4 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: io.helidon.webserver:helidon-webserver-security dependency-version: 4.2.4 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: io.helidon.http.media:helidon-http-media-jsonb dependency-version: 4.2.4 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: org.junit.jupiter:junit-jupiter-api dependency-version: 5.13.4 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: org.junit.jupiter:junit-jupiter-engine dependency-version: 5.13.4 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: org.junit.jupiter:junit-jupiter-engine dependency-version: 5.13.4 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: io.avaje:avaje-json-core dependency-version: '3.6' dependency-type: direct:production dependency-group: dependencies ... Signed-off-by: dependabot[bot] * Update HelloControllerTest.java * Update HelloControllerTest.java --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Josiah Noel <32279667+SentryMan@users.noreply.github.com> --- aws-cognito/http-client-authtoken/pom.xml | 4 ++-- htmx-nima/pom.xml | 2 +- http-client/pom.xml | 6 +++--- tests/pom.xml | 6 +++--- tests/test-javalin-jsonb/pom.xml | 4 ++-- tests/test-jex/pom.xml | 4 ++-- .../src/test/java/org/example/web/HelloControllerTest.java | 2 +- tests/test-nima-htmx/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 4 ++-- .../src/test/java/org/example/HelloControllerTest.java | 2 +- tests/test-sigma/pom.xml | 4 ++-- 11 files changed, 20 insertions(+), 20 deletions(-) diff --git a/aws-cognito/http-client-authtoken/pom.xml b/aws-cognito/http-client-authtoken/pom.xml index 941e5e8c8..e69bc8e53 100644 --- a/aws-cognito/http-client-authtoken/pom.xml +++ b/aws-cognito/http-client-authtoken/pom.xml @@ -23,14 +23,14 @@ io.avaje avaje-json-core - 3.6-RC2 + 3.6 io.avaje avaje-json-node - 3.6-RC2 + 3.6 test diff --git a/htmx-nima/pom.xml b/htmx-nima/pom.xml index 85f0b5705..4a6a5b1e3 100644 --- a/htmx-nima/pom.xml +++ b/htmx-nima/pom.xml @@ -27,7 +27,7 @@ io.helidon.webserver helidon-webserver - 4.2.3 + 4.2.4 diff --git a/http-client/pom.xml b/http-client/pom.xml index 19bd286c7..69fb7b7e2 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -30,21 +30,21 @@ com.fasterxml.jackson.core jackson-databind - 2.19.1 + 2.19.2 true io.avaje avaje-jsonb - 3.6-RC2 + 3.6 true io.avaje avaje-json-node - 3.6-RC2 + 3.6 test diff --git a/tests/pom.xml b/tests/pom.xml index 3a27304b3..8e0f4de45 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -12,12 +12,12 @@ true - 5.13.3 + 5.13.4 3.27.3 - 2.19.1 + 2.19.2 3.2 11.5 - 4.2.3 + 4.2.4 6.7.0 diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 129846d39..7d45d5e9b 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -74,13 +74,13 @@ io.avaje avaje-jsonb - 3.6-RC2 + 3.6 io.avaje avaje-jsonb-generator - 3.6-RC2 + 3.6 provided diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 763ccf594..d33a7db76 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -74,7 +74,7 @@ io.avaje avaje-jsonb - 3.6-RC2 + 3.6 @@ -140,7 +140,7 @@ io.avaje avaje-jsonb-generator - 3.6-RC2 + 3.6 io.avaje diff --git a/tests/test-jex/src/test/java/org/example/web/HelloControllerTest.java b/tests/test-jex/src/test/java/org/example/web/HelloControllerTest.java index 129b7e6e5..ab52ad3b3 100644 --- a/tests/test-jex/src/test/java/org/example/web/HelloControllerTest.java +++ b/tests/test-jex/src/test/java/org/example/web/HelloControllerTest.java @@ -36,7 +36,7 @@ void stream() { assertThat(res.statusCode()).isEqualTo(200); assertThat(res.headers().firstValue("Content-Type").orElse("Junk")) .isEqualTo("application/stream+json"); - assertThat(res.body()).isEqualTo("{\"id\":1,\"name\":\"a\"}\n{\"id\":2,\"name\":\"b\"}\n"); + assertThat(res.body()).isEqualTo("{\"id\":1,\"name\":\"a\"}\n{\"id\":2,\"name\":\"b\"}\n\n"); } @Test diff --git a/tests/test-nima-htmx/pom.xml b/tests/test-nima-htmx/pom.xml index 6568a635c..3b7e1f69a 100644 --- a/tests/test-nima-htmx/pom.xml +++ b/tests/test-nima-htmx/pom.xml @@ -88,7 +88,7 @@ io.avaje avaje-jsonb-generator - 3.6-RC2 + 3.6 io.jstach diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 8cc5a46de..9571fe6cc 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -44,7 +44,7 @@ io.avaje avaje-jsonb - 3.6-RC2 + 3.6 io.helidon.webserver @@ -104,7 +104,7 @@ io.avaje avaje-jsonb-generator - 3.6-RC2 + 3.6 io.avaje diff --git a/tests/test-nima-jsonb/src/test/java/org/example/HelloControllerTest.java b/tests/test-nima-jsonb/src/test/java/org/example/HelloControllerTest.java index 17db80acb..e13c4b530 100644 --- a/tests/test-nima-jsonb/src/test/java/org/example/HelloControllerTest.java +++ b/tests/test-nima-jsonb/src/test/java/org/example/HelloControllerTest.java @@ -50,7 +50,7 @@ void personStream() { assertThat(res.statusCode()).isEqualTo(200); String contentType = res.headers().firstValue("Content-Type").orElse("Junk"); - assertThat(res.body()).isEqualTo("{\"id\":42,\"name\":\"ignoreMe\"}\n{\"id\":43,\"name\":\"bar\"}\n{\"id\":44,\"name\":\"baz\"}\n{\"id\":44,\"name\":\"bax\"}\n"); + assertThat(res.body()).isEqualTo("{\"id\":42,\"name\":\"ignoreMe\"}\n{\"id\":43,\"name\":\"bar\"}\n{\"id\":44,\"name\":\"baz\"}\n{\"id\":44,\"name\":\"bax\"}\n\n"); assertThat(contentType).isEqualTo("application/stream+json"); } } diff --git a/tests/test-sigma/pom.xml b/tests/test-sigma/pom.xml index 15ebd22e2..43b9de47d 100644 --- a/tests/test-sigma/pom.xml +++ b/tests/test-sigma/pom.xml @@ -81,12 +81,12 @@ io.avaje avaje-jsonb - 3.6-RC2 + 3.6 io.avaje avaje-jsonb-generator - 3.6-RC2 + 3.6 provided From 2bd6d722be50a0ffbcc9e7a0665fa9e8081fcdcd Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Thu, 24 Jul 2025 16:51:09 -0400 Subject: [PATCH 1322/1323] 3.4 --- aws-cognito/http-client-authtoken/pom.xml | 2 +- htmx-api/pom.xml | 2 +- htmx-nima-jstache/pom.xml | 2 +- htmx-nima/pom.xml | 4 ++-- http-api-javalin/pom.xml | 2 +- http-api/pom.xml | 2 +- http-client-gson-adapter/pom.xml | 4 ++-- http-client-moshi-adapter/pom.xml | 4 ++-- http-client/pom.xml | 2 +- http-generator-client/pom.xml | 2 +- http-generator-core/pom.xml | 2 +- http-generator-helidon/pom.xml | 2 +- http-generator-javalin/pom.xml | 2 +- http-generator-jex/pom.xml | 2 +- http-generator-sigma/pom.xml | 2 +- http-inject-plugin/pom.xml | 2 +- pom.xml | 4 ++-- tests/pom.xml | 2 +- tests/test-client-generation/pom.xml | 2 +- tests/test-client/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 2 +- tests/test-jex/pom.xml | 2 +- tests/test-nima-htmx/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 2 +- tests/test-nima/pom.xml | 2 +- tests/test-sigma/pom.xml | 2 +- 27 files changed, 31 insertions(+), 31 deletions(-) diff --git a/aws-cognito/http-client-authtoken/pom.xml b/aws-cognito/http-client-authtoken/pom.xml index e69bc8e53..dae048187 100644 --- a/aws-cognito/http-client-authtoken/pom.xml +++ b/aws-cognito/http-client-authtoken/pom.xml @@ -17,7 +17,7 @@ io.avaje avaje-http-client - 3.4-RC4 + 3.4 diff --git a/htmx-api/pom.xml b/htmx-api/pom.xml index 8b56ea3d1..9fc8cd849 100644 --- a/htmx-api/pom.xml +++ b/htmx-api/pom.xml @@ -6,7 +6,7 @@ io.avaje avaje-http-parent - 3.4-RC4 + 3.4 avaje-htmx-api diff --git a/htmx-nima-jstache/pom.xml b/htmx-nima-jstache/pom.xml index edebd22e9..e4286e2e9 100644 --- a/htmx-nima-jstache/pom.xml +++ b/htmx-nima-jstache/pom.xml @@ -6,7 +6,7 @@ io.avaje avaje-http-parent - 3.4-RC4 + 3.4 avaje-htmx-nima-jstache diff --git a/htmx-nima/pom.xml b/htmx-nima/pom.xml index 4a6a5b1e3..9c15502b7 100644 --- a/htmx-nima/pom.xml +++ b/htmx-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje avaje-http-parent - 3.4-RC4 + 3.4 avaje-htmx-nima @@ -22,7 +22,7 @@ io.avaje avaje-htmx-api - 3.4-RC4 + 3.4 io.helidon.webserver diff --git a/http-api-javalin/pom.xml b/http-api-javalin/pom.xml index f5faaedda..e9c1c4a08 100644 --- a/http-api-javalin/pom.xml +++ b/http-api-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.4-RC4 + 3.4 .. diff --git a/http-api/pom.xml b/http-api/pom.xml index 2c87f15db..1fa0de56b 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.4-RC4 + 3.4 .. diff --git a/http-client-gson-adapter/pom.xml b/http-client-gson-adapter/pom.xml index 47259219f..c96fc1a88 100644 --- a/http-client-gson-adapter/pom.xml +++ b/http-client-gson-adapter/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.4-RC4 + 3.4 avaje-http-client-gson @@ -21,7 +21,7 @@ io.avaje avaje-http-client - 3.4-RC4 + 3.4 provided diff --git a/http-client-moshi-adapter/pom.xml b/http-client-moshi-adapter/pom.xml index 1b90528a1..1a317a2d9 100644 --- a/http-client-moshi-adapter/pom.xml +++ b/http-client-moshi-adapter/pom.xml @@ -3,7 +3,7 @@ io.avaje avaje-http-parent - 3.4-RC4 + 3.4 avaje-http-client-moshi avaje-http-client-moshi @@ -20,7 +20,7 @@ io.avaje avaje-http-client - 3.4-RC4 + 3.4 provided diff --git a/http-client/pom.xml b/http-client/pom.xml index 69fb7b7e2..5cc1d3ea0 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.4-RC4 + 3.4 avaje-http-client diff --git a/http-generator-client/pom.xml b/http-generator-client/pom.xml index 3ad6ce3ec..8b5146d10 100644 --- a/http-generator-client/pom.xml +++ b/http-generator-client/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.4-RC4 + 3.4 avaje-http-client-generator diff --git a/http-generator-core/pom.xml b/http-generator-core/pom.xml index 589ccf251..bd30cf8a7 100644 --- a/http-generator-core/pom.xml +++ b/http-generator-core/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.4-RC4 + 3.4 avaje-http-generator-core diff --git a/http-generator-helidon/pom.xml b/http-generator-helidon/pom.xml index 1863dd598..19cba2368 100644 --- a/http-generator-helidon/pom.xml +++ b/http-generator-helidon/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 3.4-RC4 + 3.4 avaje-http-helidon-generator diff --git a/http-generator-javalin/pom.xml b/http-generator-javalin/pom.xml index 22a94cba9..074f9eb5e 100644 --- a/http-generator-javalin/pom.xml +++ b/http-generator-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.4-RC4 + 3.4 avaje-http-javalin-generator diff --git a/http-generator-jex/pom.xml b/http-generator-jex/pom.xml index 3486dd0de..41308bc94 100644 --- a/http-generator-jex/pom.xml +++ b/http-generator-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.4-RC4 + 3.4 avaje-http-jex-generator diff --git a/http-generator-sigma/pom.xml b/http-generator-sigma/pom.xml index 446f66bd2..053632ae5 100644 --- a/http-generator-sigma/pom.xml +++ b/http-generator-sigma/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.4-RC4 + 3.4 avaje-http-sigma-generator diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index fe9155605..a59e1b154 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-parent - 3.4-RC4 + 3.4 .. diff --git a/pom.xml b/pom.xml index 432324cc0..74832deea 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ io.avaje avaje-http-parent avaje-http-parent - 3.4-RC4 + 3.4 pom @@ -24,7 +24,7 @@ 2.14.2 3.0-RC10 1.42 - 2025-07-16T01:21:06Z + 2025-07-24T20:50:25Z ${project.build.directory}${file.separator}module-info.shade diff --git a/tests/pom.xml b/tests/pom.xml index 8e0f4de45..e0f40ce34 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ avaje-http-parent io.avaje - 3.4-RC4 + 3.4 tests diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index 346614b1b..4f9e5f3a6 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 3.4-RC4 + 3.4 test-client-generation diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index b5dda632c..dbeddb296 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 3.4-RC4 + 3.4 test-client diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 7d45d5e9b..5cad9fff9 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 3.4-RC4 + 3.4 test-javalin-jsonb diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 378cf8d02..0ac0625ae 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 3.4-RC4 + 3.4 test-javalin diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index d33a7db76..640d1f016 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -4,7 +4,7 @@ io.avaje tests - 3.4-RC4 + 3.4 test-jex diff --git a/tests/test-nima-htmx/pom.xml b/tests/test-nima-htmx/pom.xml index 3b7e1f69a..701e47960 100644 --- a/tests/test-nima-htmx/pom.xml +++ b/tests/test-nima-htmx/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 3.4-RC4 + 3.4 test-nima-htmx diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 9571fe6cc..ed103a0ab 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 3.4-RC4 + 3.4 test-nima-jsonb diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index caade2193..34ada5eef 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -6,7 +6,7 @@ io.avaje tests - 3.4-RC4 + 3.4 test-nima diff --git a/tests/test-sigma/pom.xml b/tests/test-sigma/pom.xml index 43b9de47d..f54527255 100644 --- a/tests/test-sigma/pom.xml +++ b/tests/test-sigma/pom.xml @@ -5,7 +5,7 @@ io.avaje tests - 3.4-RC4 + 3.4 test-sigma From a4cea7ef6d44768457c1f6f80be4387faa006ecd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 5 Aug 2025 02:07:36 +0000 Subject: [PATCH 1323/1323] Bump the dependencies group with 9 updates Bumps the dependencies group with 9 updates: | Package | From | To | | --- | --- | --- | | [io.avaje:avaje-inject](https://github.com/avaje/avaje-inject) | `11.5` | `11.6` | | io.avaje:avaje-inject-generator | `11.5` | `11.6` | | io.avaje:avaje-inject-maven-plugin | `11.5` | `11.6` | | [io.avaje:avaje-prisms](https://github.com/avaje/avaje-prisms) | `1.42` | `1.43` | | io.swagger.core.v3:swagger-models | `2.2.34` | `2.2.35` | | io.swagger.core.v3:swagger-annotations | `2.2.34` | `2.2.35` | | [io.avaje:avaje-validator](https://github.com/avaje/avaje-validator) | `2.12` | `2.13` | | io.avaje:avaje-validator-constraints | `2.12` | `2.13` | | io.avaje:avaje-validator-generator | `2.12` | `2.13` | Updates `io.avaje:avaje-inject` from 11.5 to 11.6 - [Release notes](https://github.com/avaje/avaje-inject/releases) - [Commits](https://github.com/avaje/avaje-inject/compare/11.5...11.6) Updates `io.avaje:avaje-inject-generator` from 11.5 to 11.6 Updates `io.avaje:avaje-inject-generator` from 11.5 to 11.6 Updates `io.avaje:avaje-inject-maven-plugin` from 11.5 to 11.6 Updates `io.avaje:avaje-prisms` from 1.42 to 1.43 - [Release notes](https://github.com/avaje/avaje-prisms/releases) - [Commits](https://github.com/avaje/avaje-prisms/compare/1.42...1.43) Updates `io.swagger.core.v3:swagger-models` from 2.2.34 to 2.2.35 Updates `io.swagger.core.v3:swagger-annotations` from 2.2.34 to 2.2.35 Updates `io.swagger.core.v3:swagger-annotations` from 2.2.34 to 2.2.35 Updates `io.avaje:avaje-validator` from 2.12 to 2.13 - [Release notes](https://github.com/avaje/avaje-validator/releases) - [Commits](https://github.com/avaje/avaje-validator/compare/2.12...2.13) Updates `io.avaje:avaje-validator-constraints` from 2.12 to 2.13 Updates `io.avaje:avaje-validator-generator` from 2.12 to 2.13 --- updated-dependencies: - dependency-name: io.avaje:avaje-inject dependency-version: '11.6' dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.avaje:avaje-inject-generator dependency-version: '11.6' dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.avaje:avaje-inject-generator dependency-version: '11.6' dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.avaje:avaje-inject-maven-plugin dependency-version: '11.6' dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.avaje:avaje-prisms dependency-version: '1.43' dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.swagger.core.v3:swagger-models dependency-version: 2.2.35 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: io.swagger.core.v3:swagger-annotations dependency-version: 2.2.35 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: io.swagger.core.v3:swagger-annotations dependency-version: 2.2.35 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: io.avaje:avaje-validator dependency-version: '2.13' dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.avaje:avaje-validator-constraints dependency-version: '2.13' dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.avaje:avaje-validator-generator dependency-version: '2.13' dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies ... Signed-off-by: dependabot[bot] --- htmx-nima-jstache/pom.xml | 2 +- http-client/pom.xml | 6 +++--- http-inject-plugin/pom.xml | 2 +- pom.xml | 4 ++-- tests/pom.xml | 8 ++++---- tests/test-client-generation/pom.xml | 2 +- tests/test-javalin-jsonb/pom.xml | 2 +- tests/test-javalin/pom.xml | 4 ++-- tests/test-jex/pom.xml | 6 +++--- tests/test-nima-htmx/pom.xml | 2 +- tests/test-nima-jsonb/pom.xml | 6 +++--- tests/test-nima/pom.xml | 2 +- tests/test-sigma/pom.xml | 2 +- 13 files changed, 24 insertions(+), 24 deletions(-) diff --git a/htmx-nima-jstache/pom.xml b/htmx-nima-jstache/pom.xml index e4286e2e9..22fa1df97 100644 --- a/htmx-nima-jstache/pom.xml +++ b/htmx-nima-jstache/pom.xml @@ -40,7 +40,7 @@ io.avaje avaje-inject - 11.5 + 11.6 provided true diff --git a/http-client/pom.xml b/http-client/pom.xml index 5cc1d3ea0..8a175b951 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -51,7 +51,7 @@ io.avaje avaje-inject - 11.5 + 11.6 true @@ -121,7 +121,7 @@ io.avaje avaje-inject-generator - 11.5 + 11.6 @@ -160,7 +160,7 @@ io.avaje avaje-inject-maven-plugin - 11.5 + 11.6 diff --git a/http-inject-plugin/pom.xml b/http-inject-plugin/pom.xml index a59e1b154..8ad5b8ce0 100644 --- a/http-inject-plugin/pom.xml +++ b/http-inject-plugin/pom.xml @@ -20,7 +20,7 @@ io.avaje avaje-inject - 11.5 + 11.6 provided true diff --git a/pom.xml b/pom.xml index 74832deea..8e0397d44 100644 --- a/pom.xml +++ b/pom.xml @@ -20,10 +20,10 @@ true - 2.2.34 + 2.2.35 2.14.2 3.0-RC10 - 1.42 + 1.43 2025-07-24T20:50:25Z ${project.build.directory}${file.separator}module-info.shade diff --git a/tests/pom.xml b/tests/pom.xml index e0f40ce34..728f0d3ec 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -16,7 +16,7 @@ 3.27.3 2.19.2 3.2 - 11.5 + 11.6 4.2.4 6.7.0 @@ -48,19 +48,19 @@ io.avaje avaje-validator - 2.12 + 2.13 io.avaje avaje-validator-constraints - 2.12 + 2.13 io.avaje avaje-validator-generator - 2.12 + 2.13 diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index 4f9e5f3a6..53efef4aa 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -141,7 +141,7 @@ io.avaje avaje-inject-maven-plugin - 11.5 + 11.6 process-sources diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index 5cad9fff9..6e14fcd4a 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -13,7 +13,7 @@ true org.example.myapp.Main - 2.2.34 + 2.2.35 1.3.71 diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 0ac0625ae..28496c70e 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -12,7 +12,7 @@ true org.example.myapp.Main - 2.2.34 + 2.2.35 1.3.71 @@ -57,7 +57,7 @@ io.avaje avaje-validator - 2.12 + 2.13 diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 640d1f016..d5d50c2f6 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -12,7 +12,7 @@ 21 true org.example.myapp.Main - 2.2.34 + 2.2.35 @@ -145,7 +145,7 @@ io.avaje avaje-validator-generator - 2.12 + 2.13 io.jstach @@ -187,7 +187,7 @@ io.avaje avaje-inject-maven-plugin - 11.5 + 11.6 process-sources diff --git a/tests/test-nima-htmx/pom.xml b/tests/test-nima-htmx/pom.xml index 701e47960..58be92b9f 100644 --- a/tests/test-nima-htmx/pom.xml +++ b/tests/test-nima-htmx/pom.xml @@ -103,7 +103,7 @@ io.avaje avaje-inject-maven-plugin - 11.5 + 11.6 process-sources diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index ed103a0ab..61a352705 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -13,7 +13,7 @@ 21 - 2.2.34 + 2.2.35 UTF-8 false @@ -109,7 +109,7 @@ io.avaje avaje-validator-generator - 2.12 + 2.13 io.jstach @@ -133,7 +133,7 @@ io.avaje avaje-inject-maven-plugin - 11.5 + 11.6 process-sources diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index 34ada5eef..e59c9ba7b 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -81,7 +81,7 @@ io.avaje avaje-inject-maven-plugin - 11.5 + 11.6 process-sources diff --git a/tests/test-sigma/pom.xml b/tests/test-sigma/pom.xml index f54527255..743ed797a 100644 --- a/tests/test-sigma/pom.xml +++ b/tests/test-sigma/pom.xml @@ -13,7 +13,7 @@ 17 true - 2.2.34 + 2.2.35 1.3.71

    diff --git a/http-client/src/main/java/io/avaje/http/client/JsonbBodyAdapter.java b/http-client/src/main/java/io/avaje/http/client/JsonbBodyAdapter.java index 610c87720..68f1286d9 100644 --- a/http-client/src/main/java/io/avaje/http/client/JsonbBodyAdapter.java +++ b/http-client/src/main/java/io/avaje/http/client/JsonbBodyAdapter.java @@ -55,14 +55,14 @@ public BodyReader beanReader(Class cls) { @SuppressWarnings("unchecked") @Override - public BodyReader beanReader(ParameterizedType cls) { - return (BodyReader) beanReaderCache.computeIfAbsent(cls, aClass -> new JReader<>(jsonb.type(cls))); + public BodyReader beanReader(ParameterizedType type) { + return (BodyReader) beanReaderCache.computeIfAbsent(type, aClass -> new JReader<>(jsonb.type(type))); } @SuppressWarnings("unchecked") @Override - public BodyReader> listReader(ParameterizedType cls) { - return (BodyReader>) listReaderCache.computeIfAbsent(cls, aClass -> new JReader<>(jsonb.type(cls).list())); + public BodyReader> listReader(ParameterizedType type) { + return (BodyReader>) listReaderCache.computeIfAbsent(type, aClass -> new JReader<>(jsonb.type(type).list())); } @SuppressWarnings("unchecked") diff --git a/http-client/src/test/java/io/avaje/http/client/HelloControllerTest.java b/http-client/src/test/java/io/avaje/http/client/HelloControllerTest.java index 9968c7e93..1bf3bbea2 100644 --- a/http-client/src/test/java/io/avaje/http/client/HelloControllerTest.java +++ b/http-client/src/test/java/io/avaje/http/client/HelloControllerTest.java @@ -252,6 +252,24 @@ void get_stream() { assertThat(first.name).isEqualTo("one"); } + @Test + void get_stream_as() { + final HttpResponse> res = clientContext.request() + .path("hello").path("stream") + .GET() + .asStream(SimpleData.class); + + assertThat(res.statusCode()).isEqualTo(200); + + Stream stream = res.body(); + final List data = stream.collect(Collectors.toList()); + + assertThat(data).hasSize(4); + final SimpleData first = data.get(0); + assertThat(first.id).isEqualTo(1); + assertThat(first.name).isEqualTo("one"); + } + @Test void get_stream_NotFoundException() { clientContext.metrics(true); @@ -299,6 +317,35 @@ void async_get_stream() throws ExecutionException, InterruptedException { future.get(); } + @Test + void async_get_asStream() throws ExecutionException, InterruptedException { + final CompletableFuture>> future = clientContext.request() + .path("hello").path("stream") + .GET().async() + .asStream(SimpleData.class); + + future.whenComplete((res, throwable) -> { + assertThat(throwable).isNull(); + assertThat(res.statusCode()).isEqualTo(200); + Stream stream = res.body(); + final List data = stream.collect(Collectors.toList()); + assertThat(data).hasSize(4); + final SimpleData first = data.get(0); + assertThat(first.id).isEqualTo(1); + assertThat(first.name).isEqualTo("one"); + + try (stream) { + // more typically process with forEach ... + stream.forEach(simpleData -> { + System.out.println("process " + simpleData.id + " " + simpleData.name); + }); + } + }); + + // wait ... + future.get(); + } + @Test void callStreamAsync() throws ExecutionException, InterruptedException { @@ -674,12 +721,19 @@ void get_helloMessage_via_url() { @Test void get_hello_returningListOfBeans() { - final List helloDtos = clientContext.request() .path("hello") .GET().list(HelloDto.class); assertThat(helloDtos).hasSize(2); + + final HttpResponse> res = clientContext.request() + .path("hello") + .GET().asList(HelloDto.class); + + assertThat(res.statusCode()).isEqualTo(200); + List body = res.body(); + assertThat(body).hasSize(2); } @Test @@ -702,7 +756,6 @@ void callListAsync() throws ExecutionException, InterruptedException { @Test void async_list() throws ExecutionException, InterruptedException { - AtomicReference> ref = new AtomicReference<>(); final CompletableFuture> future = clientContext.request() @@ -721,6 +774,29 @@ void async_list() throws ExecutionException, InterruptedException { assertThat(helloDtos).isSameAs(ref.get()); } + @Test + void async_list_as() throws ExecutionException, InterruptedException { + AtomicReference>> ref = new AtomicReference<>(); + + final CompletableFuture>> responseFuture = clientContext.request() + .path("hello") + .GET().async() + .asList(HelloDto.class); + + responseFuture.whenComplete((res, throwable) -> { + assertThat(throwable).isNull(); + assertThat(res.statusCode()).isEqualTo(200); + List helloDtos = res.body(); + assertThat(helloDtos).hasSize(2); + ref.set(res); + }); + + final HttpResponse> helloRes = responseFuture.get(); + assertThat(helloRes.statusCode()).isEqualTo(200); + assertThat(helloRes.body()).hasSize(2); + assertThat(helloRes).isSameAs(ref.get()); + } + @Test void get_withPathParamAndQueryParam_returningBean() { @@ -790,6 +866,40 @@ void async_whenComplete_returningBean() throws ExecutionException, InterruptedEx assertThat(dto.otherParam).isEqualTo("other"); } + @Test + void async_whenComplete_returningBeanWithHeaders() throws ExecutionException, InterruptedException { + final AtomicInteger counter = new AtomicInteger(); + final AtomicReference> ref = new AtomicReference<>(); + + final CompletableFuture> future = clientContext.request() + .path("hello/43/2020-03-05").queryParam("otherParam", "other").queryParam("foo", null) + .GET() + .async().as(HelloDto.class); + + future.whenComplete((res, throwable) -> { + counter.incrementAndGet(); + ref.set(res); + + assertThat(throwable).isNull(); + + assertThat(res.statusCode()).isEqualTo(200); + HelloDto dto = res.body(); + assertThat(dto.id).isEqualTo(43L); + assertThat(dto.name).isEqualTo("2020-03-05"); + assertThat(dto.otherParam).isEqualTo("other"); + }); + + // wait ... + final HttpResponse res = future.get(); + assertThat(counter.incrementAndGet()).isEqualTo(2); + assertThat(res.statusCode()).isEqualTo(200); + HelloDto dto = res.body(); + assertThat(dto).isSameAs(ref.get().body()); + assertThat(dto.id).isEqualTo(43L); + assertThat(dto.name).isEqualTo("2020-03-05"); + assertThat(dto.otherParam).isEqualTo("other"); + } + @Test void async_whenComplete_throwingHttpException() { clientContext.metrics(true); @@ -960,6 +1070,23 @@ void postForm_returningBean() { assertThat(bean.name).isEqualTo("Bax"); assertThat(bean.otherParam).isEqualTo("Bax@foo.com"); assertThat(bean.id).isEqualTo(52); + + final HttpResponse res3 = clientContext.request() + .path("hello/saveform3") + .formParam("name", "Bax") + .formParam("email", "Bax@foo.com") + .formParam("url", "http://foo.com") + .formParam("startDate", "2030-12-03") + .POST() + .as(HelloDto.class); + + assertThat(res.statusCode()).isEqualTo(201); + assertThat(res.headers().map()).isNotEmpty(); + + HelloDto body3 = res3.body(); + assertThat(body3.name).isEqualTo("Bax"); + assertThat(body3.otherParam).isEqualTo("Bax@foo.com"); + assertThat(body3.id).isEqualTo(52); } @Test From 710e0a3335e22aca777ac19fd8242c45f7611a8b Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 17 Jan 2023 16:00:05 +1300 Subject: [PATCH 0511/1323] Update tests dependencies --- tests/test-client-generation/pom.xml | 6 +++--- tests/test-client/pom.xml | 2 +- tests/test-helidon/pom.xml | 6 +++--- tests/test-javalin-jsonb/pom.xml | 8 ++++---- tests/test-javalin/pom.xml | 6 +++--- tests/test-jex/pom.xml | 4 ++-- tests/test-nima-jsonb/pom.xml | 6 +++--- tests/test-nima/pom.xml | 4 ++-- 8 files changed, 21 insertions(+), 21 deletions(-) diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index 7b5c7061b..47b41df13 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -16,7 +16,7 @@ true 1.6 - 8.9 + 8.12-RC1 @@ -30,7 +30,7 @@ io.avaje avaje-http-client - 1.20 + 1.23-SNAPSHOT @@ -42,7 +42,7 @@ com.fasterxml.jackson.core jackson-databind - 2.13.4.1 + 2.14.1 diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index 3807597d8..4d43efd22 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -34,7 +34,7 @@ io.avaje avaje-http-api - 1.20 + 1.23-SNAPSHOT diff --git a/tests/test-helidon/pom.xml b/tests/test-helidon/pom.xml index dc8239437..b704152d7 100644 --- a/tests/test-helidon/pom.xml +++ b/tests/test-helidon/pom.xml @@ -42,12 +42,12 @@ io.avaje avaje-inject - 8.3 + 8.12-RC1 io.avaje avaje-inject-generator - 8.3 + 8.12-RC1 provided @@ -116,7 +116,7 @@ io.avaje avaje-http-client - 1.16 + 1.23-SNAPSHOT test diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index b19709a9c..ac6315ee7 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -47,7 +47,7 @@ io.avaje avaje-inject - 8.9 + 8.12-RC1 @@ -73,7 +73,7 @@ io.avaje avaje-inject-generator - 8.9 + 8.12-RC1 provided @@ -87,7 +87,7 @@ io.avaje avaje-jsonb-generator - 1.0-RC3 + 1.1 provided @@ -109,7 +109,7 @@ io.avaje avaje-http-client - 1.16 + 1.23-SNAPSHOT test diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index 50b140123..b5c9b7714 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -52,7 +52,7 @@ io.avaje avaje-inject - 8.3 + 8.12-RC1 @@ -78,7 +78,7 @@ io.avaje avaje-inject-generator - 8.3 + 8.12-RC1 provided @@ -108,7 +108,7 @@ io.avaje avaje-http-client - 1.16 + 1.23-SNAPSHOT test diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index 20f1e5d3b..a880b95b5 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -18,7 +18,7 @@ org.example.myapp.Main 2.2 2.0.8 - 2.13.4.1 + 2.14.1 8.9 1.23-SNAPSHOT @@ -101,7 +101,7 @@ io.avaje avaje-http-client - 1.16 + 1.23-SNAPSHOT test diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 6ffafa610..6a0b26ff3 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -23,7 +23,7 @@ io.avaje avaje-inject - 8.11 + 8.12-RC1 io.avaje @@ -80,12 +80,12 @@ io.avaje avaje-inject-generator - 8.10 + 8.12-RC1 io.avaje avaje-jsonb-generator - 1.1-RC2 + 1.1 diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index c42511d37..9451f3dd6 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -24,7 +24,7 @@ io.avaje avaje-inject - 8.9 + 8.12-RC1 @@ -72,7 +72,7 @@ io.avaje avaje-inject-generator - 8.9 + 8.12-RC1 From f235fa214833b434a0439230118f670c33752a64 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 17 Jan 2023 16:39:02 +1300 Subject: [PATCH 0512/1323] Update tests to use common test parent, tidy test dependencies --- http-client/pom.xml | 4 +-- tests/pom.xml | 13 +++++++- tests/test-client-generation/pom.xml | 24 ++++++--------- .../test/java/org/example/CommonApiTest.java | 3 -- tests/test-client/pom.xml | 9 +++--- tests/test-helidon/pom.xml | 30 ++++++++----------- tests/test-javalin-jsonb/pom.xml | 28 +++++++---------- tests/test-javalin/pom.xml | 26 +++++++--------- tests/test-jex/pom.xml | 23 +++++--------- tests/test-nima-jsonb/pom.xml | 24 ++++++++------- tests/test-nima/pom.xml | 12 ++++---- 11 files changed, 88 insertions(+), 108 deletions(-) diff --git a/http-client/pom.xml b/http-client/pom.xml index 62331e7c1..e21d77dab 100644 --- a/http-client/pom.xml +++ b/http-client/pom.xml @@ -39,14 +39,14 @@ io.avaje avaje-jsonb - 1.1-RC3 + 1.1 true io.avaje avaje-inject - 8.10 + 8.12-RC1 true diff --git a/tests/pom.xml b/tests/pom.xml index 84158fda5..89a3cf415 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -1,14 +1,25 @@ 4.0.0 + + java11-oss + org.avaje + 3.9 + + - io.dinject + io.avaje.http tests-reactor 1 pom true + 5.9.2 + 3.24.1 + 2.14.1 + 2.5 + 8.12-RC1 diff --git a/tests/test-client-generation/pom.xml b/tests/test-client-generation/pom.xml index 47b41df13..e24e2565b 100644 --- a/tests/test-client-generation/pom.xml +++ b/tests/test-client-generation/pom.xml @@ -1,22 +1,16 @@ - + 4.0.0 - java11-oss - org.avaje - 3.9 - + io.avaje.http + tests-reactor + 1 - 4.0.0 - test-client-generation - 1 true - 1.6 - 8.12-RC1 @@ -42,7 +36,7 @@ com.fasterxml.jackson.core jackson-databind - 2.14.1 + ${jackson.version} @@ -65,7 +59,7 @@ io.avaje - avaje-jex + avaje-jex-jetty ${jex.version} @@ -77,21 +71,21 @@ org.junit.jupiter junit-jupiter-api - 5.6.2 + ${junit.version} test org.junit.jupiter junit-jupiter-engine - 5.6.2 + ${junit.version} test org.assertj assertj-core - 3.16.1 + ${assertj.version} test diff --git a/tests/test-client-generation/src/test/java/org/example/CommonApiTest.java b/tests/test-client-generation/src/test/java/org/example/CommonApiTest.java index 268e97732..84fa0a3b8 100644 --- a/tests/test-client-generation/src/test/java/org/example/CommonApiTest.java +++ b/tests/test-client-generation/src/test/java/org/example/CommonApiTest.java @@ -1,10 +1,7 @@ package org.example; -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.ObjectMapper; import io.avaje.http.client.HttpClientContext; import io.avaje.http.client.JacksonBodyAdapter; -import io.avaje.http.client.RequestLogger; import org.example.server.Main; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; diff --git a/tests/test-client/pom.xml b/tests/test-client/pom.xml index 4d43efd22..8db7725d5 100644 --- a/tests/test-client/pom.xml +++ b/tests/test-client/pom.xml @@ -4,10 +4,9 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - java11-oss - org.avaje - 3.9 - + io.avaje.http + tests-reactor + 1 test-client @@ -40,7 +39,7 @@ com.fasterxml.jackson.core jackson-databind - 2.14.1 + ${jackson.version} diff --git a/tests/test-helidon/pom.xml b/tests/test-helidon/pom.xml index b704152d7..b0d9484e8 100644 --- a/tests/test-helidon/pom.xml +++ b/tests/test-helidon/pom.xml @@ -1,18 +1,14 @@ 4.0.0 - - org.example - test-helidon - 1 - - org.avaje - java11-oss - 3.9 - + io.avaje.http + tests-reactor + 1 + test-helidon + true org.example.Main @@ -37,24 +33,24 @@ io.avaje avaje-http-api - ${avaje-http-version} + 1.23-SNAPSHOT io.avaje avaje-inject - 8.12-RC1 + ${avaje-inject.version} io.avaje avaje-inject-generator - 8.12-RC1 + ${avaje-inject.version} provided io.avaje avaje-http-helidon-generator - ${avaje-http-version} + 1.23-SNAPSHOT provided @@ -84,14 +80,14 @@ org.junit.jupiter junit-jupiter-api - 5.8.2 + ${junit.version} test org.junit.jupiter junit-jupiter-engine - 5.8.2 + ${junit.version} test @@ -104,13 +100,13 @@ org.assertj assertj-core - 3.22.0 + ${assertj.version} test io.rest-assured rest-assured - 5.0.1 + 5.3.0 test diff --git a/tests/test-javalin-jsonb/pom.xml b/tests/test-javalin-jsonb/pom.xml index ac6315ee7..cf3c14100 100644 --- a/tests/test-javalin-jsonb/pom.xml +++ b/tests/test-javalin-jsonb/pom.xml @@ -2,26 +2,20 @@ 4.0.0 - - org.example - test-javalin-jsonb - 1 - - org.avaje - java11-oss - 3.9 - + io.avaje.http + tests-reactor + 1 + test-javalin-jsonb + true org.example.myapp.Main - 5.1.1 + 5.2.0 2.0.8 1.3.71 - 2.13.4.1 - 1.23-SNAPSHOT @@ -47,13 +41,13 @@ io.avaje avaje-inject - 8.12-RC1 + ${avaje-inject.version} io.avaje avaje-http-api - ${avaje-http-version} + 1.23-SNAPSHOT @@ -73,14 +67,14 @@ io.avaje avaje-inject-generator - 8.12-RC1 + ${avaje-inject.version} provided io.avaje avaje-http-javalin-generator - ${avaje-http-version} + 1.23-SNAPSHOT provided @@ -102,7 +96,7 @@ io.rest-assured rest-assured - 5.0.1 + 5.3.0 test diff --git a/tests/test-javalin/pom.xml b/tests/test-javalin/pom.xml index b5c9b7714..93037b313 100644 --- a/tests/test-javalin/pom.xml +++ b/tests/test-javalin/pom.xml @@ -1,26 +1,20 @@ 4.0.0 - - org.example - test-javalin - 1 - - org.avaje - java11-oss - 3.9 - + io.avaje.http + tests-reactor + 1 + test-javalin + true org.example.myapp.Main - 5.1.1 + 5.2.0 2.0.8 1.3.71 - 2.13.4.1 - 1.23-SNAPSHOT @@ -52,13 +46,13 @@ io.avaje avaje-inject - 8.12-RC1 + ${avaje-inject.version} io.avaje avaje-http-api - ${avaje-http-version} + 1.23-SNAPSHOT @@ -78,14 +72,14 @@ io.avaje avaje-inject-generator - 8.12-RC1 + ${avaje-inject.version} provided io.avaje avaje-http-javalin-generator - ${avaje-http-version} + 1.23-SNAPSHOT provided diff --git a/tests/test-jex/pom.xml b/tests/test-jex/pom.xml index a880b95b5..11dd65e2a 100644 --- a/tests/test-jex/pom.xml +++ b/tests/test-jex/pom.xml @@ -1,26 +1,19 @@ 4.0.0 - - org.example - test-jex - 1 - - org.avaje - java11-oss - 3.9 - + io.avaje.http + tests-reactor + 1 + test-jex + true org.example.myapp.Main - 2.2 + 2.5 2.0.8 - 2.14.1 - 8.9 - 1.23-SNAPSHOT @@ -58,7 +51,7 @@ io.avaje avaje-http-api - ${avaje-http.version} + 1.23-SNAPSHOT @@ -85,7 +78,7 @@ io.avaje avaje-http-jex-generator - ${avaje-http.version} + 1.23-SNAPSHOT provided diff --git a/tests/test-nima-jsonb/pom.xml b/tests/test-nima-jsonb/pom.xml index 6a0b26ff3..c1138991e 100644 --- a/tests/test-nima-jsonb/pom.xml +++ b/tests/test-nima-jsonb/pom.xml @@ -1,15 +1,13 @@ - 4.0.0 - - avaje-http-parent - io.avaje - 1.23-SNAPSHOT - ../../pom.xml - + 4.0.0 + + io.avaje.http + tests-reactor + 1 + test-nima-jsonb - 1 19 @@ -23,7 +21,7 @@ io.avaje avaje-inject - 8.12-RC1 + ${avaje-inject.version} io.avaje @@ -61,6 +59,12 @@ + + io.avaje + junit + 1.1 + test + @@ -80,7 +84,7 @@ io.avaje avaje-inject-generator - 8.12-RC1 + ${avaje-inject.version} io.avaje diff --git a/tests/test-nima/pom.xml b/tests/test-nima/pom.xml index 9451f3dd6..e22927091 100644 --- a/tests/test-nima/pom.xml +++ b/tests/test-nima/pom.xml @@ -4,14 +4,12 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - avaje-http-parent - io.avaje - 1.23-SNAPSHOT - ../../pom.xml + io.avaje.http + tests-reactor + 1 test-nima - 1 19 @@ -24,7 +22,7 @@ io.avaje avaje-inject - 8.12-RC1 + ${avaje-inject.version} @@ -72,7 +70,7 @@ io.avaje avaje-inject-generator - 8.12-RC1 + ${avaje-inject.version} From 5d4f229618c17cbbd8a1840953c28e8c46b3a8c7 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 17 Jan 2023 16:47:38 +1300 Subject: [PATCH 0513/1323] Update tests in server modules to use HttpClient from deprecated HttpClientContext --- .../test/java/org/example/BaseWebTest.java | 8 ++--- .../java/org/example/FooControllerTest.java | 4 +-- .../org/example/ReqScopedControllerTest.java | 4 +-- .../java/org/example/myapp/BaseWebTest.java | 6 ++-- .../example/myapp/HelloControllerTest.java | 29 +++++++++---------- .../myapp/ReqScopedControllerTest.java | 4 +-- .../java/org/example/myapp/BaseWebTest.java | 6 ++-- .../example/myapp/HelloControllerTest.java | 29 +++++++++---------- .../myapp/ReqScopedControllerTest.java | 4 +-- .../java/org/example/web/BaseWebTest.java | 8 ++--- .../org/example/web/HelloControllerTest.java | 6 ++-- 11 files changed, 51 insertions(+), 57 deletions(-) diff --git a/tests/test-helidon/src/test/java/org/example/BaseWebTest.java b/tests/test-helidon/src/test/java/org/example/BaseWebTest.java index 77a6a899d..02a1c95db 100644 --- a/tests/test-helidon/src/test/java/org/example/BaseWebTest.java +++ b/tests/test-helidon/src/test/java/org/example/BaseWebTest.java @@ -1,9 +1,7 @@ package org.example; -import com.fasterxml.jackson.databind.ObjectMapper; -import io.avaje.http.client.HttpClientContext; +import io.avaje.http.client.HttpClient; import io.avaje.http.client.JacksonBodyAdapter; -import io.avaje.http.client.RequestLogger; import io.helidon.webserver.WebServer; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; @@ -25,8 +23,8 @@ public static void shutdown() { webServer.shutdown(); } - public static HttpClientContext client() { - return HttpClientContext.builder() + public static HttpClient client() { + return HttpClient.builder() .baseUrl(baseUrl) .bodyAdapter(new JacksonBodyAdapter()) .build(); diff --git a/tests/test-helidon/src/test/java/org/example/FooControllerTest.java b/tests/test-helidon/src/test/java/org/example/FooControllerTest.java index e82a61ceb..6c02c8c89 100644 --- a/tests/test-helidon/src/test/java/org/example/FooControllerTest.java +++ b/tests/test-helidon/src/test/java/org/example/FooControllerTest.java @@ -1,7 +1,7 @@ package org.example; -import io.avaje.http.client.HttpClientContext; import io.avaje.http.api.Get; +import io.avaje.http.client.HttpClient; import io.restassured.response.Response; import org.example.api.FooBody; import org.junit.jupiter.api.Test; @@ -16,7 +16,7 @@ class FooControllerTest extends BaseWebTest { - private final HttpClientContext client = client(); + private final HttpClient client = client(); @Test void hello() { diff --git a/tests/test-helidon/src/test/java/org/example/ReqScopedControllerTest.java b/tests/test-helidon/src/test/java/org/example/ReqScopedControllerTest.java index 798942ce9..ab492d773 100644 --- a/tests/test-helidon/src/test/java/org/example/ReqScopedControllerTest.java +++ b/tests/test-helidon/src/test/java/org/example/ReqScopedControllerTest.java @@ -1,6 +1,6 @@ package org.example; -import io.avaje.http.client.HttpClientContext; +import io.avaje.http.client.HttpClient; import org.junit.jupiter.api.Test; import java.net.http.HttpResponse; @@ -9,7 +9,7 @@ class ReqScopedControllerTest extends BaseWebTest { - private final HttpClientContext client = client(); + private final HttpClient client = client(); @Test void testGet() { diff --git a/tests/test-javalin-jsonb/src/test/java/org/example/myapp/BaseWebTest.java b/tests/test-javalin-jsonb/src/test/java/org/example/myapp/BaseWebTest.java index 872f82e48..1063ede98 100644 --- a/tests/test-javalin-jsonb/src/test/java/org/example/myapp/BaseWebTest.java +++ b/tests/test-javalin-jsonb/src/test/java/org/example/myapp/BaseWebTest.java @@ -1,6 +1,6 @@ package org.example.myapp; -import io.avaje.http.client.HttpClientContext; +import io.avaje.http.client.HttpClient; import io.avaje.http.client.JacksonBodyAdapter; import io.javalin.Javalin; import org.junit.jupiter.api.AfterAll; @@ -23,8 +23,8 @@ public static void shutdown() { webServer.stop(); } - public static HttpClientContext client() { - return HttpClientContext.builder() + public static HttpClient client() { + return HttpClient.builder() .baseUrl(baseUrl) .bodyAdapter(new JacksonBodyAdapter()) .build(); diff --git a/tests/test-javalin-jsonb/src/test/java/org/example/myapp/HelloControllerTest.java b/tests/test-javalin-jsonb/src/test/java/org/example/myapp/HelloControllerTest.java index c007a848e..fdd151b9a 100644 --- a/tests/test-javalin-jsonb/src/test/java/org/example/myapp/HelloControllerTest.java +++ b/tests/test-javalin-jsonb/src/test/java/org/example/myapp/HelloControllerTest.java @@ -7,7 +7,6 @@ import org.example.myapp.web.HelloDto; import org.junit.jupiter.api.Test; -import java.net.http.HttpClient; import java.net.http.HttpResponse; import java.util.List; import java.util.Map; @@ -21,10 +20,10 @@ class HelloControllerTest extends BaseWebTest { - final HttpClientContext clientContext; + final HttpClient client; HelloControllerTest() { - this.clientContext = HttpClientContext.builder() + this.client = HttpClient.builder() .baseUrl(baseUrl) .bodyAdapter(new JacksonBodyAdapter()) .build(); @@ -36,7 +35,7 @@ void hello() { assertThat(response.body().asString()).contains("hello world"); assertThat(response.statusCode()).isEqualTo(200); - final HttpResponse hres = clientContext.request().path("hello").path("message") + final HttpResponse hres = client.request().path("hello").path("message") .GET().asString(); assertThat(hres.body()).contains("hello world"); @@ -56,7 +55,7 @@ void hello2() { assertThat(beans).hasSize(2); - final List helloDtos = clientContext.request() + final List helloDtos = client.request() .path("hello") .GET().list(HelloDto.class); @@ -77,7 +76,7 @@ void getWithPathParamAndQueryParam() { assertThat(bean.name).isEqualTo("2020-03-05"); assertThat(bean.otherParam).isEqualTo("other"); - final HelloDto dto = clientContext.request() + final HelloDto dto = client.request() .path("hello/43/2020-03-05").queryParam("otherParam", "other").queryParam("foo", null) .GET().bean(HelloDto.class); @@ -96,10 +95,10 @@ void postIt() { .body("name", equalTo("posted")) .body("otherParam", equalTo("other")); - final BodyWriter from = clientContext.converters().beanWriter(HelloDto.class); - final BodyReader toDto = clientContext.converters().beanReader(HelloDto.class); + final BodyWriter from = client.bodyAdapter().beanWriter(HelloDto.class); + final BodyReader toDto = client.bodyAdapter().beanReader(HelloDto.class); - final HelloDto bean = clientContext.request() + final HelloDto bean = client.request() .path("hello") .body(from.write(dto)) .POST() @@ -149,7 +148,7 @@ void postForm2_controllerUsingParams() { @Test void postForm3_controllerFormBean_responseJsonDto() { - final HelloDto bean = clientContext.request() + final HelloDto bean = client.request() .path("hello/saveform3") .formParam("name", "Bax") .formParam("email", "Bax@foo.com") @@ -195,7 +194,7 @@ void postForm_validation_expect_badRequest() { assertThat(errors.get("name")).isEqualTo("must not be null"); try { - clientContext.request() + client.request() .path("hello/saveform") .formParam("email", "user@foo.com") .formParam("url", "notAValidUrl") @@ -220,7 +219,7 @@ void postForm_validation_expect_badRequest() { @Test void get_validate_bean_expect422() { - final HttpResponse hres = clientContext.request() + final HttpResponse hres = client.request() .path("hello/withValidBean") .queryParam("email", "user@foo.com") .GET() @@ -231,7 +230,7 @@ void get_validate_bean_expect422() { @Test void get_validate_bean_expect200() { - final HttpResponse hres = clientContext.request() + final HttpResponse hres = client.request() .path("hello/withValidBean") .queryParam("name", "hello") .queryParam("email", "user@foo.com") @@ -281,7 +280,7 @@ void getWithMatrixParam() { .body(equalTo("yr:2011 au:null co:null other:foo3 extra:null")); - final HttpResponse httpRes = clientContext.request() + final HttpResponse httpRes = client.request() .path("hello/withMatrix/2011") .matrixParam("author", "rob") .matrixParam("country", "nz") @@ -297,7 +296,7 @@ void getWithMatrixParam() { @Test void get_slashAcceptingPath_expect200() { - final HttpResponse hres = clientContext.request() + final HttpResponse hres = client.request() .path("hello/slash/one/a/b/other/x/y/z") .GET() .asString(); diff --git a/tests/test-javalin-jsonb/src/test/java/org/example/myapp/ReqScopedControllerTest.java b/tests/test-javalin-jsonb/src/test/java/org/example/myapp/ReqScopedControllerTest.java index af5f0d420..ceef16adf 100644 --- a/tests/test-javalin-jsonb/src/test/java/org/example/myapp/ReqScopedControllerTest.java +++ b/tests/test-javalin-jsonb/src/test/java/org/example/myapp/ReqScopedControllerTest.java @@ -1,6 +1,6 @@ package org.example.myapp; -import io.avaje.http.client.HttpClientContext; +import io.avaje.http.client.HttpClient; import org.junit.jupiter.api.Test; import java.net.http.HttpResponse; @@ -9,7 +9,7 @@ class ReqScopedControllerTest extends BaseWebTest { - private final HttpClientContext client = client(); + private final HttpClient client = client(); @Test void testGet() { diff --git a/tests/test-javalin/src/test/java/org/example/myapp/BaseWebTest.java b/tests/test-javalin/src/test/java/org/example/myapp/BaseWebTest.java index 872f82e48..1063ede98 100644 --- a/tests/test-javalin/src/test/java/org/example/myapp/BaseWebTest.java +++ b/tests/test-javalin/src/test/java/org/example/myapp/BaseWebTest.java @@ -1,6 +1,6 @@ package org.example.myapp; -import io.avaje.http.client.HttpClientContext; +import io.avaje.http.client.HttpClient; import io.avaje.http.client.JacksonBodyAdapter; import io.javalin.Javalin; import org.junit.jupiter.api.AfterAll; @@ -23,8 +23,8 @@ public static void shutdown() { webServer.stop(); } - public static HttpClientContext client() { - return HttpClientContext.builder() + public static HttpClient client() { + return HttpClient.builder() .baseUrl(baseUrl) .bodyAdapter(new JacksonBodyAdapter()) .build(); diff --git a/tests/test-javalin/src/test/java/org/example/myapp/HelloControllerTest.java b/tests/test-javalin/src/test/java/org/example/myapp/HelloControllerTest.java index c007a848e..fdd151b9a 100644 --- a/tests/test-javalin/src/test/java/org/example/myapp/HelloControllerTest.java +++ b/tests/test-javalin/src/test/java/org/example/myapp/HelloControllerTest.java @@ -7,7 +7,6 @@ import org.example.myapp.web.HelloDto; import org.junit.jupiter.api.Test; -import java.net.http.HttpClient; import java.net.http.HttpResponse; import java.util.List; import java.util.Map; @@ -21,10 +20,10 @@ class HelloControllerTest extends BaseWebTest { - final HttpClientContext clientContext; + final HttpClient client; HelloControllerTest() { - this.clientContext = HttpClientContext.builder() + this.client = HttpClient.builder() .baseUrl(baseUrl) .bodyAdapter(new JacksonBodyAdapter()) .build(); @@ -36,7 +35,7 @@ void hello() { assertThat(response.body().asString()).contains("hello world"); assertThat(response.statusCode()).isEqualTo(200); - final HttpResponse hres = clientContext.request().path("hello").path("message") + final HttpResponse hres = client.request().path("hello").path("message") .GET().asString(); assertThat(hres.body()).contains("hello world"); @@ -56,7 +55,7 @@ void hello2() { assertThat(beans).hasSize(2); - final List helloDtos = clientContext.request() + final List helloDtos = client.request() .path("hello") .GET().list(HelloDto.class); @@ -77,7 +76,7 @@ void getWithPathParamAndQueryParam() { assertThat(bean.name).isEqualTo("2020-03-05"); assertThat(bean.otherParam).isEqualTo("other"); - final HelloDto dto = clientContext.request() + final HelloDto dto = client.request() .path("hello/43/2020-03-05").queryParam("otherParam", "other").queryParam("foo", null) .GET().bean(HelloDto.class); @@ -96,10 +95,10 @@ void postIt() { .body("name", equalTo("posted")) .body("otherParam", equalTo("other")); - final BodyWriter from = clientContext.converters().beanWriter(HelloDto.class); - final BodyReader toDto = clientContext.converters().beanReader(HelloDto.class); + final BodyWriter from = client.bodyAdapter().beanWriter(HelloDto.class); + final BodyReader toDto = client.bodyAdapter().beanReader(HelloDto.class); - final HelloDto bean = clientContext.request() + final HelloDto bean = client.request() .path("hello") .body(from.write(dto)) .POST() @@ -149,7 +148,7 @@ void postForm2_controllerUsingParams() { @Test void postForm3_controllerFormBean_responseJsonDto() { - final HelloDto bean = clientContext.request() + final HelloDto bean = client.request() .path("hello/saveform3") .formParam("name", "Bax") .formParam("email", "Bax@foo.com") @@ -195,7 +194,7 @@ void postForm_validation_expect_badRequest() { assertThat(errors.get("name")).isEqualTo("must not be null"); try { - clientContext.request() + client.request() .path("hello/saveform") .formParam("email", "user@foo.com") .formParam("url", "notAValidUrl") @@ -220,7 +219,7 @@ void postForm_validation_expect_badRequest() { @Test void get_validate_bean_expect422() { - final HttpResponse hres = clientContext.request() + final HttpResponse hres = client.request() .path("hello/withValidBean") .queryParam("email", "user@foo.com") .GET() @@ -231,7 +230,7 @@ void get_validate_bean_expect422() { @Test void get_validate_bean_expect200() { - final HttpResponse hres = clientContext.request() + final HttpResponse hres = client.request() .path("hello/withValidBean") .queryParam("name", "hello") .queryParam("email", "user@foo.com") @@ -281,7 +280,7 @@ void getWithMatrixParam() { .body(equalTo("yr:2011 au:null co:null other:foo3 extra:null")); - final HttpResponse httpRes = clientContext.request() + final HttpResponse httpRes = client.request() .path("hello/withMatrix/2011") .matrixParam("author", "rob") .matrixParam("country", "nz") @@ -297,7 +296,7 @@ void getWithMatrixParam() { @Test void get_slashAcceptingPath_expect200() { - final HttpResponse hres = clientContext.request() + final HttpResponse hres = client.request() .path("hello/slash/one/a/b/other/x/y/z") .GET() .asString(); diff --git a/tests/test-javalin/src/test/java/org/example/myapp/ReqScopedControllerTest.java b/tests/test-javalin/src/test/java/org/example/myapp/ReqScopedControllerTest.java index af5f0d420..ceef16adf 100644 --- a/tests/test-javalin/src/test/java/org/example/myapp/ReqScopedControllerTest.java +++ b/tests/test-javalin/src/test/java/org/example/myapp/ReqScopedControllerTest.java @@ -1,6 +1,6 @@ package org.example.myapp; -import io.avaje.http.client.HttpClientContext; +import io.avaje.http.client.HttpClient; import org.junit.jupiter.api.Test; import java.net.http.HttpResponse; @@ -9,7 +9,7 @@ class ReqScopedControllerTest extends BaseWebTest { - private final HttpClientContext client = client(); + private final HttpClient client = client(); @Test void testGet() { diff --git a/tests/test-jex/src/test/java/org/example/web/BaseWebTest.java b/tests/test-jex/src/test/java/org/example/web/BaseWebTest.java index e21361576..10afb6c56 100644 --- a/tests/test-jex/src/test/java/org/example/web/BaseWebTest.java +++ b/tests/test-jex/src/test/java/org/example/web/BaseWebTest.java @@ -1,9 +1,7 @@ package org.example.web; -import com.fasterxml.jackson.databind.ObjectMapper; -import io.avaje.http.client.HttpClientContext; +import io.avaje.http.client.HttpClient; import io.avaje.http.client.JacksonBodyAdapter; -import io.avaje.http.client.RequestLogger; import io.avaje.jex.Jex; import org.example.Main; import org.junit.jupiter.api.AfterAll; @@ -28,8 +26,8 @@ public static void shutdown() { webServer.shutdown(); } - public static HttpClientContext client() { - return HttpClientContext.builder() + public static HttpClient client() { + return HttpClient.builder() .baseUrl(baseUrl) .requestTimeout(Duration.ofMinutes(2)) .bodyAdapter(new JacksonBodyAdapter()) diff --git a/tests/test-jex/src/test/java/org/example/web/HelloControllerTest.java b/tests/test-jex/src/test/java/org/example/web/HelloControllerTest.java index a97d71751..9bba2f034 100644 --- a/tests/test-jex/src/test/java/org/example/web/HelloControllerTest.java +++ b/tests/test-jex/src/test/java/org/example/web/HelloControllerTest.java @@ -1,6 +1,6 @@ package org.example.web; -import io.avaje.http.client.HttpClientContext; +import io.avaje.http.client.HttpClient; import io.avaje.http.client.HttpException; import org.junit.jupiter.api.Test; @@ -12,7 +12,7 @@ class HelloControllerTest extends BaseWebTest { - final static HttpClientContext client = client(); + final static HttpClient client = client(); @Test void getHello() { @@ -27,7 +27,7 @@ void getPlain() { final HttpResponse res = client.request().path("plain").GET().asString(); assertEquals("something", res.body()); - assertThat(res.headers().firstValue("content-type").get()).startsWith("text/plain;"); + assertThat(res.headers().firstValue("content-type").orElseThrow()).startsWith("text/plain;"); } @Test From c7465f604358c140fab9bf974f3b10b1c14d3e12 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 17 Jan 2023 17:03:15 +1300 Subject: [PATCH 0514/1323] [http-client] Update the client generation to use HttpClient This also changes the HttpApiProvider interface to use HttpClient so this generated code really wants the same version of the HttpClient which I think is reasonable. --- .../java/io/avaje/http/client/HttpApiProvider.java | 2 +- .../test/java/org/example/github/SimpleProvider.java | 4 ++-- .../example/github/httpclient/Simple$HttpClient.java | 12 +++++------- .../http/generator/client/ClientMethodWriter.java | 2 +- .../io/avaje/http/generator/client/ClientWriter.java | 12 ++++++------ .../src/test/java/org/example/SimpleTest.java | 4 ++-- .../main/java/example/github/SimpleHttpClient.java | 10 ++++------ 7 files changed, 21 insertions(+), 25 deletions(-) diff --git a/http-client/src/main/java/io/avaje/http/client/HttpApiProvider.java b/http-client/src/main/java/io/avaje/http/client/HttpApiProvider.java index 00829724c..9936f1749 100644 --- a/http-client/src/main/java/io/avaje/http/client/HttpApiProvider.java +++ b/http-client/src/main/java/io/avaje/http/client/HttpApiProvider.java @@ -15,6 +15,6 @@ public interface HttpApiProvider { /** * Return the provided implementation of the API. */ - T provide(HttpClientContext client); + T provide(HttpClient client); } diff --git a/http-client/src/test/java/org/example/github/SimpleProvider.java b/http-client/src/test/java/org/example/github/SimpleProvider.java index 58bd5a339..aa5897e8f 100644 --- a/http-client/src/test/java/org/example/github/SimpleProvider.java +++ b/http-client/src/test/java/org/example/github/SimpleProvider.java @@ -1,7 +1,7 @@ package org.example.github; import io.avaje.http.client.HttpApiProvider; -import io.avaje.http.client.HttpClientContext; +import io.avaje.http.client.HttpClient; import org.example.github.httpclient.Simple$HttpClient; public class SimpleProvider implements HttpApiProvider { @@ -12,7 +12,7 @@ public Class type() { } @Override - public Simple provide(HttpClientContext client) { + public Simple provide(HttpClient client) { return new Simple$HttpClient(client); } } diff --git a/http-client/src/test/java/org/example/github/httpclient/Simple$HttpClient.java b/http-client/src/test/java/org/example/github/httpclient/Simple$HttpClient.java index 73a16d0d1..ed6b73487 100644 --- a/http-client/src/test/java/org/example/github/httpclient/Simple$HttpClient.java +++ b/http-client/src/test/java/org/example/github/httpclient/Simple$HttpClient.java @@ -13,16 +13,14 @@ public class Simple$HttpClient implements Simple { - private final HttpClientContext context; + private final HttpClient context; private final BodyReader readRepo; private final BodyWriter writeRepo; -// private final BodyConverter, String> toListOfRepo; - public Simple$HttpClient(HttpClientContext context) { + public Simple$HttpClient(HttpClient context) { this.context = context; - this.readRepo = context.converters().beanReader(Repo.class); - this.writeRepo = context.converters().beanWriter(Repo.class); -// this.toListOfRepo = context.converters().toListOf(Repo.class); + this.readRepo = context.bodyAdapter().beanReader(Repo.class); + this.writeRepo = context.bodyAdapter().beanWriter(Repo.class); } @Get("users/{user}/repos") @@ -75,7 +73,7 @@ public Class type() { } @Override - public Simple provide(HttpClientContext client) { + public Simple provide(HttpClient client) { return new Simple$HttpClient(client); } } diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java index e2d65a4a8..8d559d115 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientMethodWriter.java @@ -76,7 +76,7 @@ void write() { if (!method.isVoid()) { writer.append("return "); } - writer.append("clientContext.request()").eol(); + writer.append("client.request()").eol(); PathSegments pathSegments = method.pathSegments(); Set segments = pathSegments.segments(); diff --git a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientWriter.java b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientWriter.java index 6f465bd73..967831b0b 100644 --- a/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientWriter.java +++ b/http-generator-client/src/main/java/io/avaje/http/generator/client/ClientWriter.java @@ -14,7 +14,7 @@ */ class ClientWriter extends BaseControllerWriter { - private static final String HTTP_CLIENT_CONTEXT = "io.avaje.http.client.HttpClientContext"; + private static final String HTTP_CLIENT = "io.avaje.http.client.HttpClient"; private static final String HTTP_API_PROVIDER = "io.avaje.http.client.HttpApiProvider"; private static final String AT_GENERATED = "@Generated(\"avaje-http-client-generator\")"; @@ -25,7 +25,7 @@ class ClientWriter extends BaseControllerWriter { ClientWriter(ControllerReader reader, ProcessingContext ctx, boolean useJsonB) throws IOException { super(reader, ctx, SUFFIX); - reader.addImportType(HTTP_CLIENT_CONTEXT); + reader.addImportType(HTTP_CLIENT); reader.addImportType(HTTP_API_PROVIDER); this.useJsonb = useJsonB; readMethods(); @@ -65,7 +65,7 @@ private void writeProvider() { writer.append(" return %s.class;", shortName).eol(); writer.append(" }").eol(); writer.append(" @Override").eol(); - writer.append(" public %s provide(HttpClientContext client) {", shortName).eol(); + writer.append(" public %s provide(HttpClient client) {", shortName).eol(); writer.append(" return new %s%s(client);", shortName, SUFFIX).eol(); writer.append(" }").eol(); writer.append(" }").eol(); @@ -81,10 +81,10 @@ private void writeClassStart() { writer.append(AT_GENERATED).eol(); writer.append("public class %s%s implements %s {", shortName, SUFFIX, shortName).eol().eol(); - writer.append(" private final HttpClientContext clientContext;").eol().eol(); + writer.append(" private final HttpClient client;").eol().eol(); - writer.append(" public %s%s(HttpClientContext ctx) {", shortName, SUFFIX).eol(); - writer.append(" this.clientContext = ctx;").eol(); + writer.append(" public %s%s(HttpClient client) {", shortName, SUFFIX).eol(); + writer.append(" this.client = client;").eol(); writer.append(" }").eol().eol(); } diff --git a/tests/test-client-generation/src/test/java/org/example/SimpleTest.java b/tests/test-client-generation/src/test/java/org/example/SimpleTest.java index 30e27b016..9a659722a 100644 --- a/tests/test-client-generation/src/test/java/org/example/SimpleTest.java +++ b/tests/test-client-generation/src/test/java/org/example/SimpleTest.java @@ -3,9 +3,9 @@ import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import io.avaje.http.client.HttpApiProvider; +import io.avaje.http.client.HttpClient; import io.avaje.http.client.HttpClientContext; import io.avaje.http.client.JacksonBodyAdapter; - import org.example.httpclient.GitHubUsersHttpClient; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; @@ -45,7 +45,7 @@ public Class type() { } @Override - public GitHubUsers provide(HttpClientContext client) { + public GitHubUsers provide(HttpClient client) { return new GitHubUsersHttpClient(client); } } diff --git a/tests/test-client/src/main/java/example/github/SimpleHttpClient.java b/tests/test-client/src/main/java/example/github/SimpleHttpClient.java index 4eb3210b1..882685577 100644 --- a/tests/test-client/src/main/java/example/github/SimpleHttpClient.java +++ b/tests/test-client/src/main/java/example/github/SimpleHttpClient.java @@ -1,9 +1,7 @@ package example.github; -//import io.avaje.http.api.Get; - import io.avaje.http.client.HttpApiProvider; -import io.avaje.http.client.HttpClientContext; +import io.avaje.http.client.HttpClient; import io.avaje.http.client.HttpException; import java.util.List; @@ -19,15 +17,15 @@ public Class type() { } @Override - public Simple provide(HttpClientContext client) { + public Simple provide(HttpClient client) { return new SimpleClient(client); } private static class SimpleClient implements Simple { - private final HttpClientContext context; + private final HttpClient context; - SimpleClient(HttpClientContext context) { + SimpleClient(HttpClient context) { this.context = context; } From df083a90119b2ad140bc28c57c82904ccf361afc Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 17 Jan 2023 17:23:04 +1300 Subject: [PATCH 0515/1323] #133 - [http-client] Disable more client tests that hit github api --- .../src/main/java/io/avaje/http/client/DHttpApi.java | 6 +++--- .../test/java/io/avaje/http/client/DHttpApiTest.java | 10 +++++----- .../src/test/java/org/example/GitHubServiceTest.java | 5 +---- .../src/test/java/org/example/SimpleTest.java | 10 ++++------ .../src/test/java/example/github/GithubTest.java | 11 +++++++---- 5 files changed, 20 insertions(+), 22 deletions(-) diff --git a/http-client/src/main/java/io/avaje/http/client/DHttpApi.java b/http-client/src/main/java/io/avaje/http/client/DHttpApi.java index 643f48432..10ef79676 100644 --- a/http-client/src/main/java/io/avaje/http/client/DHttpApi.java +++ b/http-client/src/main/java/io/avaje/http/client/DHttpApi.java @@ -31,7 +31,7 @@ void init() { log.log(DEBUG, "providers for {0}", providerMap.keySet()); } - void addProvider(HttpApiProvider apiProvider) { + void addProvider(HttpApiProvider apiProvider) { providerMap.put(apiProvider.type(), apiProvider); } @@ -41,7 +41,7 @@ private HttpApiProvider lookup(Class type) { } @SuppressWarnings("unchecked") - T provideFor(Class type, HttpClientContext clientContext) { + T provideFor(Class type, HttpClient clientContext) { final HttpApiProvider apiProvider = lookup(type); if (apiProvider == null) { throw new IllegalArgumentException("No registered HttpApiProvider for type: " + type); @@ -52,7 +52,7 @@ T provideFor(Class type, HttpClientContext clientContext) { /** * Return the client implementation via service loading. */ - static T provide(Class type, HttpClientContext clientContext) { + static T provide(Class type, HttpClient clientContext) { return INSTANCE.provideFor(type, clientContext); } diff --git a/http-client/src/test/java/io/avaje/http/client/DHttpApiTest.java b/http-client/src/test/java/io/avaje/http/client/DHttpApiTest.java index fb597fb81..763fb5b86 100644 --- a/http-client/src/test/java/io/avaje/http/client/DHttpApiTest.java +++ b/http-client/src/test/java/io/avaje/http/client/DHttpApiTest.java @@ -12,7 +12,7 @@ import static org.assertj.core.api.Assertions.assertThat; -public class DHttpApiTest { +class DHttpApiTest { @Disabled @Test @@ -31,22 +31,22 @@ void test_github_listRepos() { assertThat(repos).isNotEmpty(); } + @Disabled @Test void jsonb_github_listRepos() { - Jsonb jsonb = Jsonb.newBuilder() + Jsonb jsonb = Jsonb.builder() .add(Repo.class, RepoJsonAdapter::new) - //.adapter(new JacksonAdapter()) .build(); - final HttpClientContext clientContext = HttpClientContext.builder() + final HttpClient client = HttpClient.builder() .baseUrl("https://api.github.com") .bodyAdapter(new JsonbBodyAdapter(jsonb)) .build(); DHttpApi httpApi = new DHttpApi(); httpApi.addProvider(new Simple$HttpClient.Provider()); - final Simple simple = httpApi.provideFor(Simple.class, clientContext); + final Simple simple = httpApi.provideFor(Simple.class, client); final List repos = simple.listRepos("rbygrave", "junk"); assertThat(repos).isNotEmpty(); diff --git a/tests/test-client-generation/src/test/java/org/example/GitHubServiceTest.java b/tests/test-client-generation/src/test/java/org/example/GitHubServiceTest.java index c20b06e1e..4915acb72 100644 --- a/tests/test-client-generation/src/test/java/org/example/GitHubServiceTest.java +++ b/tests/test-client-generation/src/test/java/org/example/GitHubServiceTest.java @@ -12,7 +12,7 @@ import java.io.IOException; import java.util.List; -public class GitHubServiceTest { +class GitHubServiceTest { @Disabled @Test @@ -37,9 +37,6 @@ public void onFailure(Call> call, Throwable throwable) { System.out.println("onFailure: " + throwable); } }); -// final Response> res = call.execute(); -// final List body = res.body(); -// System.out.println("done count: "+body.size()); final Call call2 = service.list2("octocat"); final Response res2 = call2.execute(); diff --git a/tests/test-client-generation/src/test/java/org/example/SimpleTest.java b/tests/test-client-generation/src/test/java/org/example/SimpleTest.java index 9a659722a..d3593983c 100644 --- a/tests/test-client-generation/src/test/java/org/example/SimpleTest.java +++ b/tests/test-client-generation/src/test/java/org/example/SimpleTest.java @@ -4,7 +4,6 @@ import com.fasterxml.jackson.databind.ObjectMapper; import io.avaje.http.client.HttpApiProvider; import io.avaje.http.client.HttpClient; -import io.avaje.http.client.HttpClientContext; import io.avaje.http.client.JacksonBodyAdapter; import org.example.httpclient.GitHubUsersHttpClient; import org.junit.jupiter.api.Disabled; @@ -14,22 +13,21 @@ import static org.assertj.core.api.Assertions.assertThat; -public class SimpleTest { +class SimpleTest { @Disabled @Test void listRepos() { - final ObjectMapper objectMapper = new ObjectMapper() .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - final HttpClientContext clientContext = - HttpClientContext.builder() + final HttpClient client = + HttpClient.builder() .baseUrl("https://api.github.com") .bodyAdapter(new JacksonBodyAdapter(objectMapper)) .build(); - GitHubUsers simple = clientContext.create(GitHubUsers.class); + GitHubUsers simple = client.create(GitHubUsers.class); final List repos = simple.listRepos("rbygrave"); System.out.println("got repos - " + repos.size()); diff --git a/tests/test-client/src/test/java/example/github/GithubTest.java b/tests/test-client/src/test/java/example/github/GithubTest.java index 9d6c76f58..5bfdfa284 100644 --- a/tests/test-client/src/test/java/example/github/GithubTest.java +++ b/tests/test-client/src/test/java/example/github/GithubTest.java @@ -2,36 +2,39 @@ import com.google.gson.Gson; import io.avaje.http.client.BodyAdapter; -import io.avaje.http.client.HttpClientContext; +import io.avaje.http.client.HttpClient; import io.avaje.http.client.JacksonBodyAdapter; import io.avaje.http.client.gson.GsonBodyAdapter; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import java.util.List; import static org.assertj.core.api.Assertions.assertThat; -public class GithubTest { +class GithubTest { + @Disabled @Test void test_with_jackson() { assertListRepos(jacksonBodyAdapter()); } + @Disabled @Test void test_with_gson() { assertListRepos(gsonBodyAdapter()); } private void assertListRepos(BodyAdapter bodyAdapter) { - final HttpClientContext clientContext = HttpClientContext.builder() + final HttpClient client = HttpClient.builder() .baseUrl("https://api.github.com") .bodyAdapter(bodyAdapter) // .requestLogging(false) // .requestListener(new RequestLogger()) .build(); - final Simple simple = clientContext.create(Simple.class); + final Simple simple = client.create(Simple.class); final List repos = simple.listRepos("rbygrave", "junk"); assertThat(repos).isNotEmpty(); From 6292783ae04b6c8cf75fd7c4995f2d677ebbe397 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 17 Jan 2023 17:31:27 +1300 Subject: [PATCH 0516/1323] Update github workflow for EA and try triggering build wf on push only --- .github/workflows/build.yml | 2 +- .github/workflows/jdk-ea.yml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 5d02d8dc4..eb6d9e426 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,6 +1,6 @@ name: Build -on: [push, pull_request, workflow_dispatch] +on: [push, workflow_dispatch] jobs: build: runs-on: ${{ matrix.os }} diff --git a/.github/workflows/jdk-ea.yml b/.github/workflows/jdk-ea.yml index 9b8ba702e..9d02b3776 100644 --- a/.github/workflows/jdk-ea.yml +++ b/.github/workflows/jdk-ea.yml @@ -1,10 +1,10 @@ -name: avaje-inject EA +name: avaje-http EA on: workflow_dispatch: schedule: - - cron: '39 1 * * 1,3,5' + - cron: '39 1 * * 2,5' jobs: build: From bc83bb5714b4dcca1830836840c9fb1b521b0632 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Tue, 17 Jan 2023 00:36:06 -0500 Subject: [PATCH 0517/1323] make it inherit --- .../http/generator/core/MethodReader.java | 103 +++++++++++++----- .../generator/core/ProcessingContext.java | 24 ++++ .../generator/core/SuperMethodFinder.java | 26 +++++ .../http/generator/core/javadoc/Javadoc.java | 8 ++ .../myapp/web/test/HealthController.java | 29 +++++ .../myapp/web/test/HealthControllerImpl.java | 13 +++ .../src/main/resources/public/openapi.json | 35 ++++++ .../http/generator/JavalinProcessorTest.java | 38 ++++++- .../resources/expectedInheritedOpenApi.json | 62 +++++++++++ .../expectedOpenApi.json | 0 10 files changed, 309 insertions(+), 29 deletions(-) create mode 100644 http-generator-core/src/main/java/io/avaje/http/generator/core/SuperMethodFinder.java create mode 100644 tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/HealthController.java create mode 100644 tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/HealthControllerImpl.java create mode 100644 tests/test-javalin-jsonb/src/test/resources/expectedInheritedOpenApi.json rename tests/test-javalin-jsonb/src/test/{java/io/avaje/http/generator => resources}/expectedOpenApi.json (100%) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java index 44201fd61..9a813f952 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java @@ -5,6 +5,7 @@ import java.util.Arrays; import java.util.List; import java.util.Optional; +import java.util.function.Predicate; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -60,6 +61,7 @@ public class MethodReader { private final PathSegments pathSegments; private final boolean hasValid; + private final List superMethods; MethodReader(ControllerReader bean, ExecutableElement element, ExecutableType actualExecutable, ProcessingContext ctx) { this.ctx = ctx; @@ -69,18 +71,46 @@ public class MethodReader { this.actualParams = (actualExecutable == null) ? null : actualExecutable.getParameterTypes(); this.isVoid = element.getReturnType().getKind() == TypeKind.VOID; this.methodRoles = Util.findRoles(element); - this.javadoc = Javadoc.parse(ctx.docComment(element)); this.produces = produces(bean); - this.apiResponses = getApiResponses(); initWebMethodViaAnnotation(); + + this.superMethods = + ctx.getSuperMethods(element.getEnclosingElement(), element.toString().replace("()", "")); + + this.apiResponses = getApiResponses(); + this.javadoc = + Optional.of(Javadoc.parse(ctx.docComment(element))) + .filter(Predicate.not(Javadoc::isEmpty)) + .orElseGet( + () -> + superMethods.stream() + .map(e -> Javadoc.parse(ctx.docComment(e))) + .filter(Predicate.not(Javadoc::isEmpty)) + .findFirst() + .orElse(Javadoc.parse(""))); + if (isWebMethod()) { - Annotation jakartaValidAnnotation = null; + + Class jakartaValidAnnotation; try { - jakartaValidAnnotation = findAnnotation(jakartaValidAnnotation()); + jakartaValidAnnotation = jakartaValidAnnotation(); } catch (final ClassNotFoundException e) { - // ignore + jakartaValidAnnotation = null; } - this.hasValid = findAnnotation(Valid.class) != null || jakartaValidAnnotation != null; + + final var jakartaAnnotation = jakartaValidAnnotation; + + this.hasValid = + findAnnotation(Valid.class) != null + || (jakartaValidAnnotation != null && findAnnotation(jakartaValidAnnotation) != null) + || superMethods.stream() + .map( + e -> + findAnnotation(Valid.class, e) != null + || (jakartaAnnotation != null + && findAnnotation(jakartaAnnotation, e) != null)) + .anyMatch(b -> b); + this.pathSegments = PathSegments.parse(Util.combinePath(bean.path(), webMethodPath)); } else { this.hasValid = false; @@ -99,31 +129,31 @@ public String toString() { } private void initWebMethodViaAnnotation() { - Form form = findAnnotation(Form.class); + final var form = findAnnotation(Form.class); if (form != null) { this.formMarker = true; } - Get get = findAnnotation(Get.class); + final var get = findAnnotation(Get.class); if (get != null) { initSetWebMethod(WebMethod.GET, get.value()); return; } - Put put = findAnnotation(Put.class); + final var put = findAnnotation(Put.class); if (put != null) { initSetWebMethod(WebMethod.PUT, put.value()); return; } - Post post = findAnnotation(Post.class); + final var post = findAnnotation(Post.class); if (post != null) { initSetWebMethod(WebMethod.POST, post.value()); return; } - Patch patch = findAnnotation(Patch.class); + final var patch = findAnnotation(Patch.class); if (patch != null) { initSetWebMethod(WebMethod.PATCH, patch.value()); return; } - Delete delete = findAnnotation(Delete.class); + final var delete = findAnnotation(Delete.class); if (delete != null) { initSetWebMethod(WebMethod.DELETE, delete.value()); } @@ -149,19 +179,34 @@ private List getApiResponses() { .map(OpenAPIResponses::value) .flatMap(Arrays::stream); - return Stream.concat(container, Arrays.stream(element.getAnnotationsByType(OpenAPIResponse.class))) - .collect(Collectors.toList()); + final var methodResponses = + Stream.concat( + container, Arrays.stream(element.getAnnotationsByType(OpenAPIResponse.class))); + final var superMethodResponses = + superMethods.stream() + .flatMap( + m -> Stream.concat( + Optional.ofNullable(findAnnotation(OpenAPIResponses.class,m)).stream() + .map(OpenAPIResponses::value) + .flatMap(Arrays::stream), + Arrays.stream(m.getAnnotationsByType(OpenAPIResponse.class)))); + return Stream.concat(methodResponses, superMethodResponses).collect(Collectors.toList()); } public A findAnnotation(Class type) { - A annotation = element.getAnnotation(type); + + return findAnnotation(type, element); + } + + public A findAnnotation(Class type, ExecutableElement elem) { + final var annotation = elem.getAnnotation(type); if (annotation != null) { return annotation; } - return bean.findMethodAnnotation(type, element); + return bean.findMethodAnnotation(type, elem); } private List addTagsToList(Element element, List list) { @@ -172,15 +217,17 @@ private List addTagsToList(Element element, List list) { list.add(element.getAnnotation(Tag.class).name()); } if (element.getAnnotation(Tags.class) != null) { - for (Tag tag : element.getAnnotation(Tags.class).value()) + for (final Tag tag : element.getAnnotation(Tags.class).value()) list.add(tag.name()); } return list; } public List tags() { - List tags = new ArrayList<>(); - tags = addTagsToList(element, tags); + final List tags = new ArrayList<>(); + addTagsToList(element, tags); + superMethods.forEach(e -> addTagsToList(e, tags)); + return addTagsToList(element.getEnclosingElement(), tags); } @@ -191,20 +238,20 @@ void read() { // non-path parameters default to form or query parameters based on the // existence of @Form annotation on the method - ParamType defaultParamType = (formMarker) ? ParamType.FORMPARAM : ParamType.QUERYPARAM; + final var defaultParamType = (formMarker) ? ParamType.FORMPARAM : ParamType.QUERYPARAM; final List parameters = element.getParameters(); - for (int i = 0; i < parameters.size(); i++) { - VariableElement p = parameters.get(i); + for (var i = 0; i < parameters.size(); i++) { + final VariableElement p = parameters.get(i); TypeMirror typeMirror; if (actualParams != null) { typeMirror = actualParams.get(i); } else { typeMirror = p.asType(); } - String rawType = Util.typeDef(typeMirror); - UType type = Util.parse(typeMirror.toString()); - MethodParam param = new MethodParam(p, type, rawType, ctx, defaultParamType, formMarker); + final var rawType = Util.typeDef(typeMirror); + final var type = Util.parse(typeMirror.toString()); + final var param = new MethodParam(p, type, rawType, ctx, defaultParamType, formMarker); params.add(param); param.addImports(bean); } @@ -286,7 +333,7 @@ public String simpleName() { } public boolean isFormBody() { - for (MethodParam param : params) { + for (final MethodParam param : params) { if (param.isForm()) { return true; } @@ -295,7 +342,7 @@ public boolean isFormBody() { } public String bodyType() { - for (MethodParam param : params) { + for (final MethodParam param : params) { if (param.isBody()) { return param.shortType(); } @@ -304,7 +351,7 @@ public String bodyType() { } public String bodyName() { - for (MethodParam param : params) { + for (final MethodParam param : params) { if (param.isBody()) { return param.name(); } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java index fcb51fc09..d75e89b2c 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java @@ -1,14 +1,19 @@ package io.avaje.http.generator.core; import java.io.IOException; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; import javax.annotation.processing.Filer; import javax.annotation.processing.Messager; import javax.annotation.processing.ProcessingEnvironment; import javax.lang.model.element.Element; +import javax.lang.model.element.ExecutableElement; import javax.lang.model.element.TypeElement; import javax.lang.model.type.DeclaredType; import javax.lang.model.type.TypeMirror; +import javax.lang.model.util.ElementFilter; import javax.lang.model.util.Elements; import javax.lang.model.util.Types; import javax.tools.Diagnostic; @@ -115,6 +120,25 @@ public TypeMirror asMemberOf(DeclaredType declaredType, Element element) { return types.asMemberOf(declaredType, element); } + public List getSuperMethods(Element element, String methodName) { + + return types.directSupertypes(element.asType()).stream() + .filter(t -> !t.toString().contains("java.lang.Object")) + .map( + superType -> { + final var superClass = (TypeElement) types.asElement(superType); + for (final ExecutableElement method : + ElementFilter.methodsIn(elements.getAllMembers(superClass))) { + if (method.getSimpleName().contentEquals(methodName)) { + return method; + } + } + return null; + }) + .filter(Objects::nonNull) + .collect(Collectors.toList()); + } + public PlatformAdapter platform() { return readAdapter; } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/SuperMethodFinder.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/SuperMethodFinder.java new file mode 100644 index 000000000..46f5a1c09 --- /dev/null +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/SuperMethodFinder.java @@ -0,0 +1,26 @@ +package io.avaje.http.generator.core; + +import javax.lang.model.element.Element; +import javax.lang.model.element.ExecutableElement; +import javax.lang.model.element.TypeElement; +import javax.lang.model.type.TypeMirror; +import javax.lang.model.util.ElementFilter; +import javax.lang.model.util.Elements; +import javax.lang.model.util.Types; + +public class SuperMethodFinder { + private SuperMethodFinder() {} + + public static ExecutableElement getSuperMethod( + Element element, String methodName, Types types, Elements elements) { + final TypeMirror superType = types.directSupertypes(element.asType()).get(0); + final var superClass = (TypeElement) types.asElement(superType); + for (final ExecutableElement method : + ElementFilter.methodsIn(elements.getAllMembers(superClass))) { + if (method.getSimpleName().contentEquals(methodName)) { + return method; + } + } + return null; + } +} diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/javadoc/Javadoc.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/javadoc/Javadoc.java index 95f2f3d87..3545416fb 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/javadoc/Javadoc.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/javadoc/Javadoc.java @@ -63,4 +63,12 @@ public String getReturnDescription() { public boolean isDeprecated() { return deprecated; } + + public boolean isEmpty() { + return summary.isBlank() + && description.isBlank() + && params.isEmpty() + && returnDescription.isEmpty() + && !deprecated; + } } diff --git a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/HealthController.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/HealthController.java new file mode 100644 index 000000000..3a62033bd --- /dev/null +++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/HealthController.java @@ -0,0 +1,29 @@ +package org.example.myapp.web.test; + +import io.avaje.http.api.Get; +import io.avaje.http.api.MediaType; +import io.avaje.http.api.OpenAPIResponse; +import io.avaje.http.api.Path; +import io.avaje.http.api.Produces; +import io.swagger.v3.oas.annotations.OpenAPIDefinition; +import io.swagger.v3.oas.annotations.info.Info; +import io.swagger.v3.oas.annotations.tags.Tag; + +@Path("javalin") +@OpenAPIDefinition( + info = + @Info( + title = "Example service showing off the Path extension method of controller", + description = "")) +public interface HealthController { + /** + * Standard Get + * + * @return a health check + */ + @Get("/health") + @Produces(MediaType.TEXT_PLAIN) + @Tag(name = "tag1", description = "it's somethin") + @OpenAPIResponse(responseCode = "500", type = ErrorResponse.class) + String health(); +} diff --git a/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/HealthControllerImpl.java b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/HealthControllerImpl.java new file mode 100644 index 000000000..e89195d97 --- /dev/null +++ b/tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/test/HealthControllerImpl.java @@ -0,0 +1,13 @@ +package org.example.myapp.web.test; + +import io.avaje.http.api.Controller; + +@Controller +public class HealthControllerImpl implements HealthController { + + @Override + public String health() { + + return "this feels like a picnic *chew*"; + } +} diff --git a/tests/test-javalin-jsonb/src/main/resources/public/openapi.json b/tests/test-javalin-jsonb/src/main/resources/public/openapi.json index 65e54b00f..5ececf2d2 100644 --- a/tests/test-javalin-jsonb/src/main/resources/public/openapi.json +++ b/tests/test-javalin-jsonb/src/main/resources/public/openapi.json @@ -6,6 +6,10 @@ "version" : "" }, "tags" : [ + { + "name" : "tag1", + "description" : "it's somethin" + }, { "name" : "tag1", "description" : "this is added to openapi tags" @@ -764,6 +768,37 @@ "deprecated" : true } }, + "/javalin/health" : { + "get" : { + "tags" : [ + "tag1" + ], + "summary" : "Standard Get", + "description" : "", + "responses" : { + "500" : { + "description" : "a health check", + "content" : { + "text/plain" : { + "schema" : { + "$ref" : "#/components/schemas/ErrorResponse" + } + } + } + }, + "200" : { + "description" : "a health check", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + }, "/openapi/get" : { "get" : { "tags" : [ diff --git a/tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/JavalinProcessorTest.java b/tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/JavalinProcessorTest.java index 555cdc7b7..c58970cdb 100644 --- a/tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/JavalinProcessorTest.java +++ b/tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/JavalinProcessorTest.java @@ -8,6 +8,7 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; @@ -155,12 +156,47 @@ public void testOpenAPIGeneration() throws Exception { final var mapper = new ObjectMapper(); final var expectedOpenApiJson = - mapper.readTree(new File("src/test/java/io/avaje/http/generator/expectedOpenApi.json")); + mapper.readTree(new File("src/test/resources/expectedOpenApi.json")); final var generatedOpenApi = mapper.readTree(new File("openapi.json")); assert expectedOpenApiJson.equals(generatedOpenApi); } + @Test + public void testInheritableOpenAPIGeneration() throws Exception { + final var source = Paths.get("src").toAbsolutePath().toString(); + // OpenAPIController + final var files = getSourceFiles(source); + + final List openAPIController = new ArrayList<>(2); + for (final var file : files) { + if (file.isNameCompatible("HealthController", Kind.SOURCE) + || file.isNameCompatible("HealthControllerImpl", Kind.SOURCE)) + openAPIController.add(file); + } + final var compiler = ToolProvider.getSystemJavaCompiler(); + + final var task = + compiler.getTask( + new PrintWriter(System.out), + null, + null, + List.of("--release=11"), + null, + openAPIController); + task.setProcessors(List.of(new JavalinProcessor(false), new Processor())); + + assertThat(task.call()).isTrue(); + + final var mapper = new ObjectMapper(); + final var expectedOpenApiJson = + mapper.readTree(new File("src/test/resources/expectedInheritedOpenApi.json")); + final var generatedOpenApi = mapper.readTree(new File("openapi.json")); + + assert expectedOpenApiJson.equals(generatedOpenApi); + } + + private Iterable getSourceFiles(String source) throws Exception { final var compiler = ToolProvider.getSystemJavaCompiler(); final var files = compiler.getStandardFileManager(null, null, null); diff --git a/tests/test-javalin-jsonb/src/test/resources/expectedInheritedOpenApi.json b/tests/test-javalin-jsonb/src/test/resources/expectedInheritedOpenApi.json new file mode 100644 index 000000000..f7e5bde03 --- /dev/null +++ b/tests/test-javalin-jsonb/src/test/resources/expectedInheritedOpenApi.json @@ -0,0 +1,62 @@ +{ + "openapi" : "3.0.1", + "info" : { + "title" : "Example service", + "description" : "Example Javalin controllers with Java and Maven", + "version" : "" + }, + "tags" : [ + { + "name" : "tag1", + "description" : "it's somethin" + } + ], + "paths" : { + "/javalin/health" : { + "get" : { + "tags" : [ + "tag1" + ], + "summary" : "Standard Get", + "description" : "", + "responses" : { + "400" : { + "description" : "a health check", + "content" : { + "text/plain" : { + "schema" : { + "$ref" : "#/components/schemas/ErrorResponse" + } + } + } + }, + "200" : { + "description" : "a health check", + "content" : { + "text/plain" : { + "schema" : { + "type" : "string" + } + } + } + } + } + } + } + }, + "components" : { + "schemas" : { + "ErrorResponse" : { + "type" : "object", + "properties" : { + "id" : { + "type" : "string" + }, + "text" : { + "type" : "string" + } + } + } + } + } +} diff --git a/tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/expectedOpenApi.json b/tests/test-javalin-jsonb/src/test/resources/expectedOpenApi.json similarity index 100% rename from tests/test-javalin-jsonb/src/test/java/io/avaje/http/generator/expectedOpenApi.json rename to tests/test-javalin-jsonb/src/test/resources/expectedOpenApi.json From cea0910543fbe46ed5af1784599f3805e3a1ce22 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Tue, 17 Jan 2023 00:45:25 -0500 Subject: [PATCH 0518/1323] Update expectedInheritedOpenApi.json --- .../src/test/resources/expectedInheritedOpenApi.json | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tests/test-javalin-jsonb/src/test/resources/expectedInheritedOpenApi.json b/tests/test-javalin-jsonb/src/test/resources/expectedInheritedOpenApi.json index f7e5bde03..d79d0822f 100644 --- a/tests/test-javalin-jsonb/src/test/resources/expectedInheritedOpenApi.json +++ b/tests/test-javalin-jsonb/src/test/resources/expectedInheritedOpenApi.json @@ -1,8 +1,7 @@ { "openapi" : "3.0.1", "info" : { - "title" : "Example service", - "description" : "Example Javalin controllers with Java and Maven", + "title" : "Example service showing off the Path extension method of controller", "version" : "" }, "tags" : [ @@ -20,7 +19,7 @@ "summary" : "Standard Get", "description" : "", "responses" : { - "400" : { + "500" : { "description" : "a health check", "content" : { "text/plain" : { From 1f912ed53b38a32d7346ef51d64686656a4ab6c9 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Tue, 17 Jan 2023 00:48:57 -0500 Subject: [PATCH 0519/1323] remove formatting --- .../http/generator/core/MethodReader.java | 32 +++++++++---------- .../generator/core/SuperMethodFinder.java | 26 --------------- 2 files changed, 16 insertions(+), 42 deletions(-) delete mode 100644 http-generator-core/src/main/java/io/avaje/http/generator/core/SuperMethodFinder.java diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java index 9a813f952..2b2d8cb16 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java @@ -129,31 +129,31 @@ public String toString() { } private void initWebMethodViaAnnotation() { - final var form = findAnnotation(Form.class); + Form form = findAnnotation(Form.class); if (form != null) { this.formMarker = true; } - final var get = findAnnotation(Get.class); + Get get = findAnnotation(Get.class); if (get != null) { initSetWebMethod(WebMethod.GET, get.value()); return; } - final var put = findAnnotation(Put.class); + Put put = findAnnotation(Put.class); if (put != null) { initSetWebMethod(WebMethod.PUT, put.value()); return; } - final var post = findAnnotation(Post.class); + Post post = findAnnotation(Post.class); if (post != null) { initSetWebMethod(WebMethod.POST, post.value()); return; } - final var patch = findAnnotation(Patch.class); + Patch patch = findAnnotation(Patch.class); if (patch != null) { initSetWebMethod(WebMethod.PATCH, patch.value()); return; } - final var delete = findAnnotation(Delete.class); + Delete delete = findAnnotation(Delete.class); if (delete != null) { initSetWebMethod(WebMethod.DELETE, delete.value()); } @@ -217,7 +217,7 @@ private List addTagsToList(Element element, List list) { list.add(element.getAnnotation(Tag.class).name()); } if (element.getAnnotation(Tags.class) != null) { - for (final Tag tag : element.getAnnotation(Tags.class).value()) + for (Tag tag : element.getAnnotation(Tags.class).value()) list.add(tag.name()); } return list; @@ -238,20 +238,20 @@ void read() { // non-path parameters default to form or query parameters based on the // existence of @Form annotation on the method - final var defaultParamType = (formMarker) ? ParamType.FORMPARAM : ParamType.QUERYPARAM; + ParamType defaultParamType = (formMarker) ? ParamType.FORMPARAM : ParamType.QUERYPARAM; final List parameters = element.getParameters(); - for (var i = 0; i < parameters.size(); i++) { - final VariableElement p = parameters.get(i); + for (int i = 0; i < parameters.size(); i++) { + VariableElement p = parameters.get(i); TypeMirror typeMirror; if (actualParams != null) { typeMirror = actualParams.get(i); } else { typeMirror = p.asType(); } - final var rawType = Util.typeDef(typeMirror); - final var type = Util.parse(typeMirror.toString()); - final var param = new MethodParam(p, type, rawType, ctx, defaultParamType, formMarker); + String rawType = Util.typeDef(typeMirror); + UType type = Util.parse(typeMirror.toString()); + MethodParam param = new MethodParam(p, type, rawType, ctx, defaultParamType, formMarker); params.add(param); param.addImports(bean); } @@ -333,7 +333,7 @@ public String simpleName() { } public boolean isFormBody() { - for (final MethodParam param : params) { + for (MethodParam param : params) { if (param.isForm()) { return true; } @@ -342,7 +342,7 @@ public boolean isFormBody() { } public String bodyType() { - for (final MethodParam param : params) { + for (MethodParam param : params) { if (param.isBody()) { return param.shortType(); } @@ -351,7 +351,7 @@ public String bodyType() { } public String bodyName() { - for (final MethodParam param : params) { + for (MethodParam param : params) { if (param.isBody()) { return param.name(); } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/SuperMethodFinder.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/SuperMethodFinder.java deleted file mode 100644 index 46f5a1c09..000000000 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/SuperMethodFinder.java +++ /dev/null @@ -1,26 +0,0 @@ -package io.avaje.http.generator.core; - -import javax.lang.model.element.Element; -import javax.lang.model.element.ExecutableElement; -import javax.lang.model.element.TypeElement; -import javax.lang.model.type.TypeMirror; -import javax.lang.model.util.ElementFilter; -import javax.lang.model.util.Elements; -import javax.lang.model.util.Types; - -public class SuperMethodFinder { - private SuperMethodFinder() {} - - public static ExecutableElement getSuperMethod( - Element element, String methodName, Types types, Elements elements) { - final TypeMirror superType = types.directSupertypes(element.asType()).get(0); - final var superClass = (TypeElement) types.asElement(superType); - for (final ExecutableElement method : - ElementFilter.methodsIn(elements.getAllMembers(superClass))) { - if (method.getSimpleName().contentEquals(methodName)) { - return method; - } - } - return null; - } -} From 3f818e7925c1507189b84bc725f0595e9f2a7cbb Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Tue, 17 Jan 2023 00:54:22 -0500 Subject: [PATCH 0520/1323] Update Javadoc.java --- .../main/java/io/avaje/http/generator/core/javadoc/Javadoc.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/javadoc/Javadoc.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/javadoc/Javadoc.java index 3545416fb..3e161108b 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/javadoc/Javadoc.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/javadoc/Javadoc.java @@ -68,7 +68,7 @@ public boolean isEmpty() { return summary.isBlank() && description.isBlank() && params.isEmpty() - && returnDescription.isEmpty() + && returnDescription.isBlank() && !deprecated; } } From a540a99fae72ca8ba08b1d45fd430ccb86e688d0 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Tue, 17 Jan 2023 00:59:17 -0500 Subject: [PATCH 0521/1323] Update MethodReader.java --- .../main/java/io/avaje/http/generator/core/MethodReader.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java index 2b2d8cb16..f17d87ed4 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java @@ -224,8 +224,7 @@ private List addTagsToList(Element element, List list) { } public List tags() { - final List tags = new ArrayList<>(); - addTagsToList(element, tags); + final var tags = addTagsToList(element, new ArrayList<>()); superMethods.forEach(e -> addTagsToList(e, tags)); return addTagsToList(element.getEnclosingElement(), tags); From df6cb511a0a9b161559aa06a067e9ebbebe84667 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Tue, 17 Jan 2023 01:10:07 -0500 Subject: [PATCH 0522/1323] Update MethodReader.java --- .../main/java/io/avaje/http/generator/core/MethodReader.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java index f17d87ed4..aec51d6a2 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java @@ -75,7 +75,7 @@ public class MethodReader { initWebMethodViaAnnotation(); this.superMethods = - ctx.getSuperMethods(element.getEnclosingElement(), element.toString().replace("()", "")); + ctx.getSuperMethods(element.getEnclosingElement(), element.getSimpleName().toString()); this.apiResponses = getApiResponses(); this.javadoc = From 37487536c9c85bd80565aba8ebdbaf27ac082d34 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Tue, 17 Jan 2023 01:12:31 -0500 Subject: [PATCH 0523/1323] format --- .../io/avaje/http/generator/core/MethodReader.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java index aec51d6a2..873c3df0d 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java @@ -186,11 +186,12 @@ private List getApiResponses() { final var superMethodResponses = superMethods.stream() .flatMap( - m -> Stream.concat( - Optional.ofNullable(findAnnotation(OpenAPIResponses.class,m)).stream() - .map(OpenAPIResponses::value) - .flatMap(Arrays::stream), - Arrays.stream(m.getAnnotationsByType(OpenAPIResponse.class)))); + m -> + Stream.concat( + Optional.ofNullable(findAnnotation(OpenAPIResponses.class, m)).stream() + .map(OpenAPIResponses::value) + .flatMap(Arrays::stream), + Arrays.stream(m.getAnnotationsByType(OpenAPIResponse.class)))); return Stream.concat(methodResponses, superMethodResponses).collect(Collectors.toList()); } From df6d0c81c7f61d35602ed4289b3f7059d7d1f438 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Tue, 17 Jan 2023 01:18:15 -0500 Subject: [PATCH 0524/1323] Update MethodReader.java --- .../main/java/io/avaje/http/generator/core/MethodReader.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java index 873c3df0d..e6b07955e 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java @@ -77,6 +77,8 @@ public class MethodReader { this.superMethods = ctx.getSuperMethods(element.getEnclosingElement(), element.getSimpleName().toString()); + superMethods.stream().forEach(m -> methodRoles.addAll(Util.findRoles(m))); + this.apiResponses = getApiResponses(); this.javadoc = Optional.of(Javadoc.parse(ctx.docComment(element))) From 9f5805d96fd35876abdce2cb1e9fc4fbec0b09e7 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 17 Jan 2023 19:45:07 +1300 Subject: [PATCH 0525/1323] Update github workflow for EA and try triggering build wf on pull request only --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index eb6d9e426..92cd6b1b7 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,6 +1,6 @@ name: Build -on: [push, workflow_dispatch] +on: [pull_request, workflow_dispatch] jobs: build: runs-on: ${{ matrix.os }} From 72fe111f3fac0dc358519e8b927e1116b840c2e5 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 17 Jan 2023 20:19:49 +1300 Subject: [PATCH 0526/1323] #135 Refactor extracting methods for MethodReader --- .../http/generator/core/MethodReader.java | 153 ++++++++---------- .../generator/core/ProcessingContext.java | 41 +++-- .../src/main/resources/public/openapi.json | 6 +- 3 files changed, 88 insertions(+), 112 deletions(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java index e6b07955e..c49348237 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/MethodReader.java @@ -1,13 +1,10 @@ package io.avaje.http.generator.core; -import java.lang.annotation.Annotation; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Optional; -import java.util.function.Predicate; -import java.util.stream.Collectors; -import java.util.stream.Stream; +import io.avaje.http.api.*; +import io.avaje.http.generator.core.javadoc.Javadoc; +import io.avaje.http.generator.core.openapi.MethodDocBuilder; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.tags.Tags; import javax.lang.model.element.Element; import javax.lang.model.element.ExecutableElement; @@ -16,53 +13,39 @@ import javax.lang.model.type.TypeKind; import javax.lang.model.type.TypeMirror; import javax.validation.Valid; - -import io.avaje.http.api.Delete; -import io.avaje.http.api.Form; -import io.avaje.http.api.Get; -import io.avaje.http.api.OpenAPIResponse; -import io.avaje.http.api.OpenAPIResponses; -import io.avaje.http.api.Patch; -import io.avaje.http.api.Post; -import io.avaje.http.api.Produces; -import io.avaje.http.api.Put; -import io.avaje.http.generator.core.javadoc.Javadoc; -import io.avaje.http.generator.core.openapi.MethodDocBuilder; -import io.swagger.v3.oas.annotations.tags.Tag; -import io.swagger.v3.oas.annotations.tags.Tags; +import java.lang.annotation.Annotation; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Optional; +import java.util.function.Predicate; +import java.util.stream.Collectors; +import java.util.stream.Stream; public class MethodReader { private final ProcessingContext ctx; private final ControllerReader bean; private final ExecutableElement element; - private final boolean isVoid; private final List params = new ArrayList<>(); - private final Javadoc javadoc; - - private WebMethod webMethod; - private String webMethodPath; - - private boolean formMarker; - /** * Holds enum Roles that are required for the method. */ private final List methodRoles; - private final String produces; - private final List apiResponses; - private final ExecutableType actualExecutable; private final List actualParams; - private final PathSegments pathSegments; private final boolean hasValid; private final List superMethods; + private WebMethod webMethod; + private String webMethodPath; + private boolean formMarker; + MethodReader(ControllerReader bean, ExecutableElement element, ExecutableType actualExecutable, ProcessingContext ctx) { this.ctx = ctx; this.bean = bean; @@ -74,45 +57,20 @@ public class MethodReader { this.produces = produces(bean); initWebMethodViaAnnotation(); - this.superMethods = - ctx.getSuperMethods(element.getEnclosingElement(), element.getSimpleName().toString()); - - superMethods.stream().forEach(m -> methodRoles.addAll(Util.findRoles(m))); - - this.apiResponses = getApiResponses(); - this.javadoc = - Optional.of(Javadoc.parse(ctx.docComment(element))) - .filter(Predicate.not(Javadoc::isEmpty)) - .orElseGet( - () -> - superMethods.stream() - .map(e -> Javadoc.parse(ctx.docComment(e))) - .filter(Predicate.not(Javadoc::isEmpty)) - .findFirst() - .orElse(Javadoc.parse(""))); + this.superMethods = ctx.superMethods(element.getEnclosingElement(), element.getSimpleName().toString()); + superMethods.forEach(m -> methodRoles.addAll(Util.findRoles(m))); - if (isWebMethod()) { + this.apiResponses = buildApiResponses(); + this.javadoc = buildJavadoc(element, ctx); - Class jakartaValidAnnotation; + if (isWebMethod()) { + Class jakartaValidAnnotation; try { jakartaValidAnnotation = jakartaValidAnnotation(); } catch (final ClassNotFoundException e) { jakartaValidAnnotation = null; } - - final var jakartaAnnotation = jakartaValidAnnotation; - - this.hasValid = - findAnnotation(Valid.class) != null - || (jakartaValidAnnotation != null && findAnnotation(jakartaValidAnnotation) != null) - || superMethods.stream() - .map( - e -> - findAnnotation(Valid.class, e) != null - || (jakartaAnnotation != null - && findAnnotation(jakartaAnnotation, e) != null)) - .anyMatch(b -> b); - + this.hasValid = hasValid(jakartaValidAnnotation); this.pathSegments = PathSegments.parse(Util.combinePath(bean.path(), webMethodPath)); } else { this.hasValid = false; @@ -120,6 +78,29 @@ && findAnnotation(jakartaAnnotation, e) != null)) } } + private Javadoc buildJavadoc(ExecutableElement element, ProcessingContext ctx) { + return Optional.of(Javadoc.parse(ctx.docComment(element))) + .filter(Predicate.not(Javadoc::isEmpty)) + .orElseGet(() -> superMethods.stream() + .map(e -> Javadoc.parse(ctx.docComment(e))) + .filter(Predicate.not(Javadoc::isEmpty)) + .findFirst() + .orElse(Javadoc.parse(""))); + } + + private boolean hasValid(Class jakartaValidAnnotation) { + return findAnnotation(Valid.class) != null + || (jakartaValidAnnotation != null && findAnnotation(jakartaValidAnnotation) != null) + || superMethodHasValid(jakartaValidAnnotation); + } + + private boolean superMethodHasValid(Class jakartaAnnotation) { + return superMethods.stream() + .anyMatch(e -> + findAnnotation(Valid.class, e) != null + || (jakartaAnnotation != null && findAnnotation(jakartaAnnotation, e) != null)); + } + @SuppressWarnings("unchecked") private static Class jakartaValidAnnotation() throws ClassNotFoundException { return (Class) Class.forName(Valid.class.getCanonicalName().replace("javax", "jakarta")); @@ -175,31 +156,30 @@ private String produces(ControllerReader bean) { return (produces != null) ? produces.value() : bean.produces(); } - private List getApiResponses() { + private List buildApiResponses() { final var container = - Optional.ofNullable(findAnnotation(OpenAPIResponses.class)).stream() - .map(OpenAPIResponses::value) - .flatMap(Arrays::stream); + Optional.ofNullable(findAnnotation(OpenAPIResponses.class)).stream() + .map(OpenAPIResponses::value) + .flatMap(Arrays::stream); final var methodResponses = - Stream.concat( - container, Arrays.stream(element.getAnnotationsByType(OpenAPIResponse.class))); + Stream.concat( + container, Arrays.stream(element.getAnnotationsByType(OpenAPIResponse.class))); final var superMethodResponses = - superMethods.stream() - .flatMap( - m -> - Stream.concat( - Optional.ofNullable(findAnnotation(OpenAPIResponses.class, m)).stream() - .map(OpenAPIResponses::value) - .flatMap(Arrays::stream), - Arrays.stream(m.getAnnotationsByType(OpenAPIResponse.class)))); + superMethods.stream() + .flatMap( + method -> + Stream.concat( + Optional.ofNullable(findAnnotation(OpenAPIResponses.class, method)).stream() + .map(OpenAPIResponses::value) + .flatMap(Arrays::stream), + Arrays.stream(method.getAnnotationsByType(OpenAPIResponse.class)))); return Stream.concat(methodResponses, superMethodResponses).collect(Collectors.toList()); } public A findAnnotation(Class type) { - return findAnnotation(type, element); } @@ -208,28 +188,27 @@ public A findAnnotation(Class type, ExecutableElement if (annotation != null) { return annotation; } - return bean.findMethodAnnotation(type, elem); } private List addTagsToList(Element element, List list) { - if (element == null) + if (element == null) { return list; - + } if (element.getAnnotation(Tag.class) != null) { list.add(element.getAnnotation(Tag.class).name()); } if (element.getAnnotation(Tags.class) != null) { - for (Tag tag : element.getAnnotation(Tags.class).value()) + for (Tag tag : element.getAnnotation(Tags.class).value()) { list.add(tag.name()); + } } return list; } public List tags() { final var tags = addTagsToList(element, new ArrayList<>()); - superMethods.forEach(e -> addTagsToList(e, tags)); - + superMethods.forEach(method -> addTagsToList(method, tags)); return addTagsToList(element.getEnclosingElement(), tags); } diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java index d75e89b2c..83e2df4ee 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java @@ -1,9 +1,6 @@ package io.avaje.http.generator.core; -import java.io.IOException; -import java.util.List; -import java.util.Objects; -import java.util.stream.Collectors; +import io.avaje.http.generator.core.openapi.DocContext; import javax.annotation.processing.Filer; import javax.annotation.processing.Messager; @@ -20,8 +17,10 @@ import javax.tools.FileObject; import javax.tools.JavaFileObject; import javax.tools.StandardLocation; - -import io.avaje.http.generator.core.openapi.DocContext; +import java.io.IOException; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; public class ProcessingContext { @@ -120,23 +119,21 @@ public TypeMirror asMemberOf(DeclaredType declaredType, Element element) { return types.asMemberOf(declaredType, element); } - public List getSuperMethods(Element element, String methodName) { - + public List superMethods(Element element, String methodName) { return types.directSupertypes(element.asType()).stream() - .filter(t -> !t.toString().contains("java.lang.Object")) - .map( - superType -> { - final var superClass = (TypeElement) types.asElement(superType); - for (final ExecutableElement method : - ElementFilter.methodsIn(elements.getAllMembers(superClass))) { - if (method.getSimpleName().contentEquals(methodName)) { - return method; - } - } - return null; - }) - .filter(Objects::nonNull) - .collect(Collectors.toList()); + .filter(type -> !type.toString().contains("java.lang.Object")) + .map( + superType -> { + final var superClass = (TypeElement) types.asElement(superType); + for (final ExecutableElement method : ElementFilter.methodsIn(elements.getAllMembers(superClass))) { + if (method.getSimpleName().contentEquals(methodName)) { + return method; + } + } + return null; + }) + .filter(Objects::nonNull) + .collect(Collectors.toList()); } public PlatformAdapter platform() { diff --git a/tests/test-javalin-jsonb/src/main/resources/public/openapi.json b/tests/test-javalin-jsonb/src/main/resources/public/openapi.json index 5ececf2d2..8d00293ff 100644 --- a/tests/test-javalin-jsonb/src/main/resources/public/openapi.json +++ b/tests/test-javalin-jsonb/src/main/resources/public/openapi.json @@ -1,18 +1,18 @@ { "openapi" : "3.0.1", "info" : { - "title" : "Example service", + "title" : "Example service showing off the Path extension method of controller", "description" : "Example Javalin controllers with Java and Maven", "version" : "" }, "tags" : [ { "name" : "tag1", - "description" : "it's somethin" + "description" : "this is added to openapi tags" }, { "name" : "tag1", - "description" : "this is added to openapi tags" + "description" : "it's somethin" } ], "paths" : { From c0d0684d5834262e23cfee2c8d4ba1982e4f7056 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 17 Jan 2023 20:29:54 +1300 Subject: [PATCH 0527/1323] Simplify useJavax determination in ProcessingContext IntelliJ warned that for `javax && !jakarta` the !jakarta part was always true. That leads to this simplification. --- .../java/io/avaje/http/generator/core/ProcessingContext.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java index 83e2df4ee..f26b1e13d 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java @@ -58,10 +58,8 @@ public ProcessingContext(ProcessingEnvironment env, PlatformAdapter readAdapter) final var override = env.getOptions().get("useJavax"); if (override != null || (javax && jakarta)) { this.useJavax = Boolean.parseBoolean(override); - } else if (javax && !jakarta) { - useJavax = javax; } else { - useJavax = false; + this.useJavax = javax; } } From 3efb620018b693d2da046b2aeba0543f41ae381c Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Tue, 17 Jan 2023 19:23:01 -0500 Subject: [PATCH 0528/1323] jakarta --- http-hibernate-validator/pom.xml | 20 +++++++++---------- .../hibernate/validator/BeanValidator.java | 16 +++++++-------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/http-hibernate-validator/pom.xml b/http-hibernate-validator/pom.xml index 0ad273c35..951e24b60 100644 --- a/http-hibernate-validator/pom.xml +++ b/http-hibernate-validator/pom.xml @@ -4,7 +4,7 @@ io.avaje avaje-http-hibernate-validator - 2.8 + 3.0 org.avaje @@ -23,26 +23,26 @@ org.hibernate.validator hibernate-validator - 6.2.3.Final + 8.0.0.Final - - org.glassfish - javax.el - 3.0.1-b12 - + + org.glassfish.expressly + expressly + 5.0.0 + io.avaje avaje-http-api - 1.12 + 1.22 provided io.avaje avaje-inject - 8.3 + 8.11 provided @@ -51,7 +51,7 @@ io.avaje avaje-inject-generator - 8.3 + 8.11 provided diff --git a/http-hibernate-validator/src/main/java/io/avaje/http/hibernate/validator/BeanValidator.java b/http-hibernate-validator/src/main/java/io/avaje/http/hibernate/validator/BeanValidator.java index a4aa549c5..bc5231640 100644 --- a/http-hibernate-validator/src/main/java/io/avaje/http/hibernate/validator/BeanValidator.java +++ b/http-hibernate-validator/src/main/java/io/avaje/http/hibernate/validator/BeanValidator.java @@ -1,18 +1,18 @@ package io.avaje.http.hibernate.validator; -import io.avaje.http.api.ValidationException; -import io.avaje.http.api.Validator; -import io.avaje.inject.Component; - -import javax.validation.ConstraintViolation; -import javax.validation.Path; -import javax.validation.Validation; -import javax.validation.ValidatorFactory; import java.util.LinkedHashMap; import java.util.Map; import java.util.Set; +import io.avaje.http.api.ValidationException; +import io.avaje.http.api.Validator; +import io.avaje.inject.Component; +import jakarta.validation.ConstraintViolation; +import jakarta.validation.Path; +import jakarta.validation.Validation; +import jakarta.validation.ValidatorFactory; + @Component public class BeanValidator implements Validator { From 162be6e74ebeafa6a666456eef7c48acdbe53a3a Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Tue, 17 Jan 2023 20:27:21 -0500 Subject: [PATCH 0529/1323] Delete README.md --- http-api/README.md | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 http-api/README.md diff --git a/http-api/README.md b/http-api/README.md deleted file mode 100644 index bda6b0703..000000000 --- a/http-api/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# dinject-controller - -Controller annotations for use with Javalin. - -See https://dinject.io/docs/javalin/ From 3fd124bed9d076868cb9245624233d32a6d2422d Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Wed, 18 Jan 2023 00:44:09 -0500 Subject: [PATCH 0530/1323] fix annotations on openapi schema --- .../src/main/java/io/avaje/http/generator/core/Util.java | 2 +- .../avaje/http/generator/core/openapi/SchemaDocBuilder.java | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/Util.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/Util.java index 29544e52b..2f7e2d9e6 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/Util.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/Util.java @@ -38,7 +38,7 @@ public static String typeDef(TypeMirror typeMirror) { } } - static String trimAnnotations(String type) { + public static String trimAnnotations(String type) { int pos = type.indexOf("@"); if (pos == -1) { return type; diff --git a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/SchemaDocBuilder.java b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/SchemaDocBuilder.java index 22b1b1403..5d3f2061f 100644 --- a/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/SchemaDocBuilder.java +++ b/http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/SchemaDocBuilder.java @@ -1,5 +1,6 @@ package io.avaje.http.generator.core.openapi; +import io.avaje.http.generator.core.Util; import io.swagger.v3.oas.annotations.Hidden; import io.swagger.v3.oas.models.Operation; import io.swagger.v3.oas.models.media.ArraySchema; @@ -203,8 +204,9 @@ private Schema buildMapSchema(TypeMirror type) { } private String getObjectSchemaName(TypeMirror type) { - String canonicalName = type.toString(); - int pos = canonicalName.lastIndexOf('.'); + + var canonicalName = Util.trimAnnotations(type.toString()); + final var pos = canonicalName.lastIndexOf('.'); if (pos > -1) { canonicalName = canonicalName.substring(pos + 1); } From c00ecbf7f8af79a87d46ccbc973341fda366c579 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Wed, 18 Jan 2023 00:52:38 -0500 Subject: [PATCH 0531/1323] Update pom.xml --- http-hibernate-validator/pom.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/http-hibernate-validator/pom.xml b/http-hibernate-validator/pom.xml index 951e24b60..f5ac927f3 100644 --- a/http-hibernate-validator/pom.xml +++ b/http-hibernate-validator/pom.xml @@ -26,11 +26,11 @@ 8.0.0.Final - - org.glassfish.expressly - expressly - 5.0.0 - + + org.glassfish.expressly + expressly + 5.0.0 + io.avaje From b9b1eaf73aa5780214694db1374cebb453305971 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Wed, 18 Jan 2023 19:58:07 +1300 Subject: [PATCH 0532/1323] Update parent pom to java11-oss for http-hibernate-validator 3.0 --- http-hibernate-validator/pom.xml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/http-hibernate-validator/pom.xml b/http-hibernate-validator/pom.xml index f5ac927f3..462fd4cc7 100644 --- a/http-hibernate-validator/pom.xml +++ b/http-hibernate-validator/pom.xml @@ -8,7 +8,7 @@ org.avaje - java8-oss + java11-oss 3.9 @@ -26,11 +26,11 @@ 8.0.0.Final - - org.glassfish.expressly - expressly - 5.0.0 - + + org.glassfish.expressly + expressly + 5.0.0 + io.avaje From 13bf6386645c33b433031f8d7dd0b4876774eebc Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Wed, 18 Jan 2023 20:20:20 +1300 Subject: [PATCH 0533/1323] Update the openapi-maven-plugin, parent pom, repackage - repackage into io.avaje.http - update the parent pom to java11-oss --- openapi-maven-plugin/pom.xml | 24 +++++++++---------- .../http}/maven/openapi/OpenApiMojo.java | 2 +- 2 files changed, 12 insertions(+), 14 deletions(-) rename openapi-maven-plugin/src/main/java/io/{dinject => avaje/http}/maven/openapi/OpenApiMojo.java (98%) diff --git a/openapi-maven-plugin/pom.xml b/openapi-maven-plugin/pom.xml index a02fbadb9..6a084bedb 100644 --- a/openapi-maven-plugin/pom.xml +++ b/openapi-maven-plugin/pom.xml @@ -1,22 +1,20 @@ 4.0.0 + + org.avaje + java11-oss + 3.9 + - io.dinject openapi-maven-plugin 1.4-SNAPSHOT maven-plugin openapi-maven-plugin - https://dinject.io/ - - - org.avaje - java8-oss - 2.1 - + https://avaje.io/http - scm:git:git@github.com:dinject/openapi-maven-plugin.git + scm:git:git@github.com:avaje/avaje-http.git HEAD @@ -25,26 +23,26 @@ org.apache.maven maven-plugin-api - 3.6.1 + 3.8.5 org.apache.maven maven-core - 3.5.3 + 3.8.5 org.apache.maven.plugin-tools maven-plugin-annotations - 3.6.0 + 3.6.4 provided junit junit - 4.13.1 + 4.13.2 test diff --git a/openapi-maven-plugin/src/main/java/io/dinject/maven/openapi/OpenApiMojo.java b/openapi-maven-plugin/src/main/java/io/avaje/http/maven/openapi/OpenApiMojo.java similarity index 98% rename from openapi-maven-plugin/src/main/java/io/dinject/maven/openapi/OpenApiMojo.java rename to openapi-maven-plugin/src/main/java/io/avaje/http/maven/openapi/OpenApiMojo.java index 6205e71e0..e8a0a5ab7 100644 --- a/openapi-maven-plugin/src/main/java/io/dinject/maven/openapi/OpenApiMojo.java +++ b/openapi-maven-plugin/src/main/java/io/avaje/http/maven/openapi/OpenApiMojo.java @@ -1,4 +1,4 @@ -package io.dinject.maven.openapi; +package io.avaje.http.maven.openapi; import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugins.annotations.LifecyclePhase; From 84f67057967edd0816655317c9db130cec0c5d94 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Wed, 18 Jan 2023 20:27:00 +1300 Subject: [PATCH 0534/1323] Update the openapi-maven-plugin, put version back to 1.0 Putting version back to 1.0 with the groupId change. I think that is ok. --- openapi-maven-plugin/README.md | 19 +++++++++++++++++++ openapi-maven-plugin/pom.xml | 2 +- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/openapi-maven-plugin/README.md b/openapi-maven-plugin/README.md index 5632986f8..f30a3688f 100644 --- a/openapi-maven-plugin/README.md +++ b/openapi-maven-plugin/README.md @@ -1,2 +1,21 @@ # openapi-maven-plugin Maven plugin for OpenAPI generation (swagger) + +```xml + + + io.avaje + openapi-maven-plugin + 1.0 + + + main + process-classes + + openapi + + + + + +``` diff --git a/openapi-maven-plugin/pom.xml b/openapi-maven-plugin/pom.xml index 6a084bedb..23e8bccae 100644 --- a/openapi-maven-plugin/pom.xml +++ b/openapi-maven-plugin/pom.xml @@ -8,7 +8,7 @@ openapi-maven-plugin - 1.4-SNAPSHOT + 1.0 maven-plugin openapi-maven-plugin https://avaje.io/http From a170be20d0a1c3f39ae8d7c47c710ffc111437ab Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Wed, 18 Jan 2023 21:24:44 +1300 Subject: [PATCH 0535/1323] [http-client] Add code generation for the as() methods returning HttpResponse, HttpResponse>, HttpResponse> --- .../java/io/avaje/http/client/DHttpCall.java | 123 ++++++++++++++++++ .../avaje/http/client/HttpCallResponse.java | 52 +++++++- .../generator/client/ClientMethodWriter.java | 23 ++-- .../io/avaje/http/generator/core/UType.java | 1 + .../java/org/example/WithAsResponseApi.java | 35 +++++ 5 files changed, 222 insertions(+), 12 deletions(-) create mode 100644 tests/test-client-generation/src/main/java/org/example/WithAsResponseApi.java diff --git a/http-client/src/main/java/io/avaje/http/client/DHttpCall.java b/http-client/src/main/java/io/avaje/http/client/DHttpCall.java index 31c94e97e..7882c0664 100644 --- a/http-client/src/main/java/io/avaje/http/client/DHttpCall.java +++ b/http-client/src/main/java/io/avaje/http/client/DHttpCall.java @@ -55,6 +55,36 @@ public HttpCall bean(Class type) { return new CallBean<>(type); } + @Override + public HttpCall> as(Class type) { + return new CallAs<>(type); + } + + @Override + public HttpCall> as(ParameterizedType type) { + return new CallAs<>(type); + } + + @Override + public HttpCall>> asList(Class type) { + return new CallAsList<>(type); + } + + @Override + public HttpCall>> asList(ParameterizedType type) { + return new CallAsList<>(type); + } + + @Override + public HttpCall>> asStream(Class type) { + return new CallAsStream<>(type); + } + + @Override + public HttpCall>> asStream(ParameterizedType type) { + return new CallAsStream<>(type); + } + @Override public HttpCall> list(Class type) { return new CallList<>(type); @@ -85,6 +115,7 @@ private class CallVoid implements HttpCall> { public HttpResponse execute() { return request.asVoid(); } + @Override public CompletableFuture> async() { return request.async().asVoid(); @@ -96,6 +127,7 @@ private class CallDiscarding implements HttpCall> { public HttpResponse execute() { return request.asDiscarding(); } + @Override public CompletableFuture> async() { return request.async().asDiscarding(); @@ -107,6 +139,7 @@ private class CallString implements HttpCall> { public HttpResponse execute() { return request.asString(); } + @Override public CompletableFuture> async() { return request.async().asString(); @@ -118,6 +151,7 @@ private class CallBytes implements HttpCall> { public HttpResponse execute() { return request.asByteArray(); } + @Override public CompletableFuture> async() { return request.async().asByteArray(); @@ -129,6 +163,7 @@ private class CallLines implements HttpCall>> { public HttpResponse> execute() { return request.asLines(); } + @Override public CompletableFuture>> async() { return request.async().asLines(); @@ -140,12 +175,97 @@ private class CallInputStream implements HttpCall> { public HttpResponse execute() { return request.asInputStream(); } + @Override public CompletableFuture> async() { return request.async().asInputStream(); } } + private class CallAs implements HttpCall> { + private final Class type; + private final ParameterizedType genericType; + private final boolean isGeneric; + + CallAs(Class type) { + this.isGeneric = false; + this.type = type; + this.genericType = null; + } + + CallAs(ParameterizedType type) { + this.isGeneric = true; + this.type = null; + this.genericType = type; + } + + @Override + public HttpResponse execute() { + return isGeneric ? request.as(genericType) : request.as(type); + } + + @Override + public CompletableFuture> async() { + return isGeneric ? request.async().as(genericType) : request.async().as(type); + } + } + + private class CallAsList implements HttpCall>> { + private final Class type; + private final ParameterizedType genericType; + private final boolean isGeneric; + + CallAsList(Class type) { + this.isGeneric = false; + this.type = type; + this.genericType = null; + } + + CallAsList(ParameterizedType type) { + this.isGeneric = true; + this.type = null; + this.genericType = type; + } + + @Override + public HttpResponse> execute() { + return isGeneric ? request.asList(genericType) : request.asList(type); + } + + @Override + public CompletableFuture>> async() { + return isGeneric ? request.async().asList(genericType) : request.async().asList(type); + } + } + + private class CallAsStream implements HttpCall>> { + private final Class type; + private final ParameterizedType genericType; + private final boolean isGeneric; + + CallAsStream(Class type) { + this.isGeneric = false; + this.type = type; + this.genericType = null; + } + + CallAsStream(ParameterizedType type) { + this.isGeneric = true; + this.type = null; + this.genericType = type; + } + + @Override + public HttpResponse> execute() { + return isGeneric ? request.asStream(genericType) : request.asStream(type); + } + + @Override + public CompletableFuture>> async() { + return isGeneric ? request.async().asStream(genericType) : request.async().asStream(type); + } + } + private class CallBean implements HttpCall { private final Class type; private final ParameterizedType genericType; @@ -232,13 +352,16 @@ public CompletableFuture> async() { private class CallHandler implements HttpCall> { private final HttpResponse.BodyHandler handler; + CallHandler(HttpResponse.BodyHandler handler) { this.handler = handler; } + @Override public HttpResponse execute() { return request.handler(handler); } + @Override public CompletableFuture> async() { return request.async().handler(handler); diff --git a/http-client/src/main/java/io/avaje/http/client/HttpCallResponse.java b/http-client/src/main/java/io/avaje/http/client/HttpCallResponse.java index 96cccbe52..e7bf1126d 100644 --- a/http-client/src/main/java/io/avaje/http/client/HttpCallResponse.java +++ b/http-client/src/main/java/io/avaje/http/client/HttpCallResponse.java @@ -126,6 +126,52 @@ default HttpCall> withHandler(HttpResponse.BodyHandler bo return handler(bodyHandler); } + /** + * A bean response to execute async or sync. + *